Bug 818626 - Record in crash reports whether nsPrintObject trees are sane. r=roc
authorCameron McCormack <cam@mcc.id.au>
Mon, 31 Dec 2012 10:17:40 +1100
changeset 126352 28f9ce570aa1a362225315809ea7637de8a9ea05
parent 126351 e7eb5d6958184d514cae08e4e3443999ee39c7b0
child 126353 bac88e28327870fe13b3db5c15439664f47402ca
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs818626
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 818626 - Record in crash reports whether nsPrintObject trees are sane. r=roc
layout/printing/nsPrintData.cpp
--- a/layout/printing/nsPrintData.cpp
+++ b/layout/printing/nsPrintData.cpp
@@ -7,16 +7,20 @@
 
 #include "nsIStringBundle.h"
 #include "nsIServiceManager.h"
 #include "nsPrintObject.h"
 #include "nsPrintPreviewListener.h"
 #include "nsIWebProgressListener.h"
 #include "mozilla/Services.h"
 
+#ifdef MOZ_CRASHREPORTER
+#include "nsExceptionHandler.h"
+#endif
+
 //-----------------------------------------------------
 // PR LOGGING
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif
 
 #include "prlog.h"
 
@@ -61,16 +65,72 @@ nsPrintData::nsPrintData(ePrintDataType 
   }
 
   if (!mBrandName) {
     mBrandName = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document"));
   }
 
 }
 
+#ifdef MOZ_CRASHREPORTER
+#define ASSERT_AND_NOTE(message) \
+  { NS_ASSERTION(false, message); \
+    CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING(message "\n")); }
+#else
+#define ASSERT_AND_NOTE(message) \
+  NS_ASSERTION(false, message);
+#endif
+
+static void
+AssertPresShellsAndContextsSane(nsPrintObject* aPO,
+                                nsTArray<nsIPresShell*>& aPresShells,
+                                nsTArray<nsPresContext*>& aPresContexts)
+{
+  if (aPO->mPresShell) {
+    if (aPresShells.Contains(aPO->mPresShell)) {
+      ASSERT_AND_NOTE("duplicate pres shells in print object tree");
+    } else {
+      aPresShells.AppendElement(aPO->mPresShell);
+    }
+  }
+  if (aPO->mPresContext) {
+    if (aPresContexts.Contains(aPO->mPresContext)) {
+      ASSERT_AND_NOTE("duplicate pres contexts in print object tree");
+    } else {
+      aPresContexts.AppendElement(aPO->mPresContext);
+    }
+  }
+  if (aPO->mPresShell && !aPO->mPresContext) {
+    ASSERT_AND_NOTE("print object has pres shell but no pres context");
+  }
+  if (!aPO->mPresShell && aPO->mPresContext) {
+    ASSERT_AND_NOTE("print object has pres context but no pres shell");
+  }
+  if (aPO->mPresContext && aPO->mPresContext->GetPresShell() != aPO->mPresShell) {
+    ASSERT_AND_NOTE("print object has mismatching pres shell and pres context");
+  }
+  if (aPO->mPresContext && !aPO->mPresContext->GetPresShell()) {
+    ASSERT_AND_NOTE("mPresShell->GetPresShell() is null");
+  }
+
+  for (uint32_t i = 0; i < aPO->mKids.Length(); i++) {
+    AssertPresShellsAndContextsSane(aPO->mKids[i], aPresShells, aPresContexts);
+  }
+}
+
+#undef ASSERT_AND_NOTE
+
+static void
+AssertPresShellsAndContextsSane(nsPrintObject* aPO)
+{
+  nsTArray<nsIPresShell*> presShells;
+  nsTArray<nsPresContext*> presContexts;
+  AssertPresShellsAndContextsSane(aPO, presShells, presContexts);
+}
+
 nsPrintData::~nsPrintData()
 {
   MOZ_COUNT_DTOR(nsPrintData);
   // remove the event listeners
   if (mPPEventListeners) {
     mPPEventListeners->RemoveListeners();
     NS_RELEASE(mPPEventListeners);
   }
@@ -94,16 +154,17 @@ nsPrintData::~nsPrintData()
         rv = mPrintDC->AbortDocument();  
       }
       if (NS_FAILED(rv)) {
         // XXX nsPrintData::ShowPrintErrorDialog(rv);
       }
     }
   }
 
+  AssertPresShellsAndContextsSane(mPrintObject);
   delete mPrintObject;
 
   if (mBrandName) {
     NS_Free(mBrandName);
   }
 }
 
 void nsPrintData::OnStartPrinting()