From 101b2ad7538bc1a5417b54cf5713d403f9a2eefa Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering@fb.com>
Date: Thu, 15 Sep 2016 16:26:34 -0700
Subject: [PATCH] folly/.../ExceptionTracerLib.cpp: provide less DOF fodder
 (avoid heap use-after-free)

Summary:
Before this change, an application would fail consistently with a shutdown-time heap use-after-free (i.e., destructor-order-fiasco when one of the following symbols was used after its static-destruction-triggered free):

  DECLARE_CALLBACK(CxaThrow);
  DECLARE_CALLBACK(CxaBeginCatch);
  DECLARE_CALLBACK(CxaRethrow);
  DECLARE_CALLBACK(CxaEndCatch);
  DECLARE_CALLBACK(RethrowException);

Each of those would define a classic meyers singleton.
Since each destructor is trivial, we can fix this by making each a pseudo-leaky (indestructible) meyers singleton instead. Since each static value is never destroyed,
it can never cause a DOF error again.

Differential Revision: D3870740

fbshipit-source-id: 625f5d5268768ca0e4125bed72bc66c53618be29
---
 .../exception_tracer/ExceptionTracerLib.cpp       | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/folly/experimental/exception_tracer/ExceptionTracerLib.cpp b/folly/experimental/exception_tracer/ExceptionTracerLib.cpp
index 2d2c0133..2ba97b78 100644
--- a/folly/experimental/exception_tracer/ExceptionTracerLib.cpp
+++ b/folly/experimental/exception_tracer/ExceptionTracerLib.cpp
@@ -20,6 +20,7 @@
 
 #include <vector>
 
+#include <folly/Indestructible.h>
 #include <folly/Portability.h>
 #include <folly/SharedMutex.h>
 #include <folly/Synchronized.h>
@@ -69,13 +70,13 @@ class CallbackHolder {
 namespace folly {
 namespace exception_tracer {
 
-#define DECLARE_CALLBACK(NAME)                         \
-  CallbackHolder<NAME##Type>& get##NAME##Callbacks() { \
-    static CallbackHolder<NAME##Type> Callbacks;       \
-    return Callbacks;                                  \
-  }                                                    \
-  void register##NAME##Callback(NAME##Type callback) { \
-    get##NAME##Callbacks().registerCallback(callback); \
+#define DECLARE_CALLBACK(NAME)                                   \
+  CallbackHolder<NAME##Type>& get##NAME##Callbacks() {           \
+    static Indestructible<CallbackHolder<NAME##Type>> Callbacks; \
+    return *Callbacks;                                           \
+  }                                                              \
+  void register##NAME##Callback(NAME##Type callback) {           \
+    get##NAME##Callbacks().registerCallback(callback);           \
   }
 
 DECLARE_CALLBACK(CxaThrow);
-- 
2.34.1