Bug 1268246 - Add a simple Poison class lifetime checker. r=froydnj
authorBenoit Girard <b56girard@gmail.com>
Fri, 29 Apr 2016 13:54:54 -0400
changeset 334534 506eacf36f935c80636b68363f69e7e87d1ee52a
parent 334533 6ff2e12738caf72a99ed0156b1da87cb1948570b
child 334535 a17e8323ae15f62945bc64d62719f393a7bc1a74
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1268246
milestone49.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 1268246 - Add a simple Poison class lifetime checker. r=froydnj MozReview-Commit-ID: HpUjIaLPV7u
mfbt/Poison.h
--- a/mfbt/Poison.h
+++ b/mfbt/Poison.h
@@ -54,9 +54,55 @@ inline void mozWritePoison(void* aPtr, s
 extern MFBT_API void mozPoisonValueInit();
 
 /* Values annotated by CrashReporter */
 extern MFBT_DATA uintptr_t gMozillaPoisonBase;
 extern MFBT_DATA uintptr_t gMozillaPoisonSize;
 
 MOZ_END_EXTERN_C
 
+#if defined(__cplusplus)
+
+namespace mozilla {
+
+/**
+ * This class is designed to cause crashes when various kinds of memory
+ * corruption are observed. For instance, let's say we have a class C where we
+ * suspect out-of-bounds writes to some members.  We can insert a member of type
+ * Poison near the members we suspect are being corrupted by out-of-bounds
+ * writes.  Or perhaps we have a class K we suspect is subject to use-after-free
+ * violations, in which case it doesn't particularly matter where in the class
+ * we add the member of type Poison.
+ *
+ * In either case, we then insert calls to Check() throughout the code.  Doing
+ * so enables us to narrow down the location where the corruption is occurring.
+ * A pleasant side-effect of these additional Check() calls is that crash
+ * signatures may become more regular, as crashes will ideally occur
+ * consolidated at the point of a Check(), rather than scattered about at
+ * various uses of the corrupted memory.
+ */
+class CorruptionCanary {
+public:
+  CorruptionCanary() {
+    mValue = kCanarySet;
+  }
+
+  ~CorruptionCanary() {
+    Check();
+    mValue = mozPoisonValue();
+  }
+
+  void Check() const {
+    if (mValue != kCanarySet) {
+      MOZ_CRASH("Canary check failed, check lifetime");
+    }
+  }
+
+private:
+  static const uintptr_t kCanarySet = 0x0f0b0f0b;
+  uintptr_t mValue;
+};
+
+} // mozilla
+
+#endif
+
 #endif /* mozilla_Poison_h */