diff --git a/mailnews/base/src/nsMsgQuickSearchDBView.cpp b/mailnews/base/src/nsMsgQuickSearchDBView.cpp
--- a/mailnews/base/src/nsMsgQuickSearchDBView.cpp
+++ b/mailnews/base/src/nsMsgQuickSearchDBView.cpp
@@ -637,30 +637,46 @@ nsMsgQuickSearchDBView::ListIdsInThreadO
                                              nsMsgKey parentKey, PRInt32 level,
                                              nsMsgKey keyToSkip,
                                              nsMsgViewIndex *viewIndex,
                                              PRUint32 *pNumListed)
 {
   nsCOMPtr <nsISimpleEnumerator> msgEnumerator;
   nsresult rv = threadHdr->EnumerateMessages(parentKey, getter_AddRefs(msgEnumerator));
   NS_ENSURE_SUCCESS(rv, rv);
+  
+  // We use the numChildren as a sanity check on the thread structure.
+  // If we discover depths of more than numChildren, it means we have
+  // some sort of circular thread relationship and we bail out of the
+  // while loop before overflowing the stack with recursive calls.
+  PRUint32 numChildren;
+  (void) threadHdr->GetNumChildren(&numChildren);
   PRBool hasMore;
   nsCOMPtr <nsISupports> supports;
   nsCOMPtr <nsIMsgDBHdr> msgHdr;
-  while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv = msgEnumerator->HasMoreElements(&hasMore)) && hasMore)
+  while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv = msgEnumerator->HasMoreElements(&hasMore)) &&
+         hasMore)
   {
     rv = msgEnumerator->GetNext(getter_AddRefs(supports));
     if (NS_SUCCEEDED(rv) && supports)
     {
       msgHdr = do_QueryInterface(supports);
       nsMsgKey msgKey;
       msgHdr->GetMessageKey(&msgKey);
       if (msgKey == keyToSkip)
         continue;
 
+      // Technically, this is an error, but forcing a database rebuild
+      // is too destructive so we just return.
+      if (*pNumListed > numChildren)
+      {
+        NS_ERROR("loop in message threading while listing children");
+        return NS_OK;
+      }
+
       PRInt32 childLevel = level;
       if (m_origKeys.BinaryIndexOf(msgKey) != -1)
       {
         PRUint32 msgFlags;
         msgHdr->GetFlags(&msgFlags);
         InsertMsgHdrAt(*viewIndex, msgHdr, msgKey, msgFlags & ~MSG_VIEW_FLAGS, level);
         (*pNumListed)++;
         (*viewIndex)++;
