Bug 626994. Add debugging for infinite recursion in spline flattening. r=ehsan,a=b
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Tue, 01 Feb 2011 17:49:29 -0500
changeset 61767 3fd821a55f6d9cd9e9a8d03497aab09c5fc9e8bc
parent 61766 c698ef73edae81063d1f30875689007eb10c2ff4
child 61768 835b313007b49d24a8243dbddf070e65c9e59c01
push idunknown
push userunknown
push dateunknown
reviewersehsan, b
bugs626994
milestone2.0b11pre
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 626994. Add debugging for infinite recursion in spline flattening. r=ehsan,a=b Hopefully this gives us some idea about what's going wrong.
gfx/cairo/cairo/src/cairo-spline.c
widget/src/xpwidgets/GfxInfoBase.cpp
--- a/gfx/cairo/cairo/src/cairo-spline.c
+++ b/gfx/cairo/cairo/src/cairo-spline.c
@@ -178,40 +178,63 @@ static double
     berr = bdx * bdx + bdy * bdy;
     cerr = cdx * cdx + cdy * cdy;
     if (berr > cerr)
 	return berr;
     else
 	return cerr;
 }
 
+void StoreSpline(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy);
+void CrashSpline();
+
 static cairo_status_t
 _cairo_spline_decompose_into (cairo_spline_knots_t *s1, double tolerance_squared, cairo_spline_t *result)
 {
+    static int depth;
     cairo_spline_knots_t s2;
     cairo_status_t status;
 
+    depth++;
+#ifdef MOZ_ENABLE_LIBXUL
+    if (depth == 200) {
+        CrashSpline();
+    }
+#endif
+
     if (_cairo_spline_error_squared (s1) < tolerance_squared)
 	return _cairo_spline_add_point (result, &s1->a);
 
     _de_casteljau (s1, &s2);
 
     status = _cairo_spline_decompose_into (s1, tolerance_squared, result);
     if (unlikely (status))
 	return status;
 
-    return _cairo_spline_decompose_into (&s2, tolerance_squared, result);
+    status = _cairo_spline_decompose_into (&s2, tolerance_squared, result);
+    depth--;
+    return status;
 }
 
 cairo_status_t
 _cairo_spline_decompose (cairo_spline_t *spline, double tolerance)
 {
     cairo_spline_knots_t s1;
     cairo_status_t status;
 
+#ifdef MOZ_ENABLE_LIBXUL
+    StoreSpline(spline->knots.a.x,
+                spline->knots.a.y,
+                spline->knots.b.x,
+                spline->knots.b.y,
+                spline->knots.c.x,
+                spline->knots.c.y,
+                spline->knots.d.x,
+                spline->knots.d.y);
+#endif
     s1 = spline->knots;
     spline->last_point = s1.a;
     status = _cairo_spline_decompose_into (&s1, tolerance * tolerance, spline);
     if (unlikely (status))
 	return status;
 
     return _cairo_spline_add_point (spline, &spline->knots.d);
 }
--- a/widget/src/xpwidgets/GfxInfoBase.cpp
+++ b/widget/src/xpwidgets/GfxInfoBase.cpp
@@ -52,16 +52,79 @@
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOM3Node.h"
 #include "nsIDOMNodeList.h"
 #include "nsTArray.h"
 
+#if defined(MOZ_CRASHREPORTER) && defined(MOZ_ENABLE_LIBXUL)
+#include "nsExceptionHandler.h"
+#endif
+
+extern "C" {
+  void StoreSpline(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy);
+  void CrashSpline();
+}
+
+static double crash_ax;
+static double crash_ay;
+static double crash_bx;
+static double crash_by;
+static double crash_cx;
+static double crash_cy;
+static double crash_dx;
+static double crash_dy;
+
+void
+StoreSpline(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy) {
+    crash_ax = ax;
+    crash_ay = ay;
+    crash_bx = bx;
+    crash_by = by;
+    crash_cx = cx;
+    crash_cy = cy;
+    crash_dx = dx;
+    crash_dy = dy;
+}
+
+void
+CrashSpline() {
+#if defined(MOZ_CRASHREPORTER) && defined(MOZ_ENABLE_LIBXUL)
+  static bool annotated;
+
+  if (!annotated) {
+    nsCAutoString note;
+
+    note.AppendPrintf("curve ");
+    note.AppendPrintf("%llx ", crash_ax);
+    note.AppendPrintf("%llx, ", crash_ay);
+    note.AppendPrintf("%llx ", crash_bx);
+    note.AppendPrintf("%llx, ", crash_by);
+    note.AppendPrintf("%llx ", crash_cx);
+    note.AppendPrintf("%llx, ", crash_cy);
+    note.AppendPrintf("%llx ", crash_dx);
+    note.AppendPrintf("%llx\n", crash_dy);
+    note.AppendPrintf("crv-f: %f ", crash_ax);
+    note.AppendPrintf("%f, ", crash_ay);
+    note.AppendPrintf("%f ", crash_bx);
+    note.AppendPrintf("%f, ", crash_by);
+    note.AppendPrintf("%f ", crash_cx);
+    note.AppendPrintf("%f, ", crash_cy);
+    note.AppendPrintf("%f ", crash_dx);
+    note.AppendPrintf("%f\n", crash_dy);
+
+    CrashReporter::AppendAppNotesToCrashReport(note);
+    annotated = true;
+  }
+#endif
+}
+
+
 using namespace mozilla::widget;
 
 NS_IMPL_ISUPPORTS3(GfxInfoBase, nsIGfxInfo, nsIObserver, nsISupportsWeakReference)
 
 #define BLACKLIST_PREF_BRANCH "gfx.blacklist."
 #define SUGGESTED_VERSION_PREF BLACKLIST_PREF_BRANCH "suggested-driver-version"
 #define BLACKLIST_ENTRY_TAG_NAME "gfxBlacklistEntry"