LLVM assertion failures should funnel into WTF's crash handling
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 3 Nov 2013 01:33:13 +0000 (01:33 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 3 Nov 2013 01:33:13 +0000 (01:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=123682

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.

Inside llvmForJSC, we override assertion-related functions and funnel them
into g_llvmTrapCallback(). We also now register a fatal error handler inside
the library and funnel that into g_llvmTrapCallback, and have
initializeAndGetJSCLLVMAPI() take such a callback as an argument.

Inside JSC, we no longer call LLVMInstallFatalErrorHandler() but instead we
pass WTFLogAlwaysAndCrash() as the trap callback for llvmForJSC.

* llvm/InitializeLLVM.cpp:
(JSC::initializeLLVM):
* llvm/InitializeLLVMPOSIX.cpp:
(JSC::initializeLLVMPOSIX):
* llvm/library/LLVMExports.cpp:
(llvmCrash):
(initializeAndGetJSCLLVMAPI):
* llvm/library/LLVMOverrides.cpp:
(raise):
(__assert_rtn):
(abort):
* llvm/library/LLVMTrapCallback.h: Added.

Source/WTF:

Reviewed by Geoffrey Garen.

Give JSC some new toys to play with for crash handling.

* wtf/Assertions.cpp:
* wtf/Assertions.h:

Tools:

Reviewed by Geoffrey Garen.

Need to disable LLVM's crash overrides so that we can do our own crash overrides.

* Scripts/configure-llvm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@158509 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/llvm/InitializeLLVM.cpp
Source/JavaScriptCore/llvm/InitializeLLVMPOSIX.cpp
Source/JavaScriptCore/llvm/library/LLVMExports.cpp
Source/JavaScriptCore/llvm/library/LLVMOverrides.cpp
Source/JavaScriptCore/llvm/library/LLVMTrapCallback.h [new file with mode: 0644]
Source/WTF/ChangeLog
Source/WTF/wtf/Assertions.cpp
Source/WTF/wtf/Assertions.h
Tools/ChangeLog
Tools/Scripts/configure-llvm

index 1d2983b..6ec3ce8 100644 (file)
@@ -1,5 +1,33 @@
 2013-11-02  Filip Pizlo  <fpizlo@apple.com>
 
+        LLVM assertion failures should funnel into WTF's crash handling
+        https://bugs.webkit.org/show_bug.cgi?id=123682
+
+        Reviewed by Geoffrey Garen.
+        
+        Inside llvmForJSC, we override assertion-related functions and funnel them
+        into g_llvmTrapCallback(). We also now register a fatal error handler inside
+        the library and funnel that into g_llvmTrapCallback, and have
+        initializeAndGetJSCLLVMAPI() take such a callback as an argument.
+        
+        Inside JSC, we no longer call LLVMInstallFatalErrorHandler() but instead we
+        pass WTFLogAlwaysAndCrash() as the trap callback for llvmForJSC.
+
+        * llvm/InitializeLLVM.cpp:
+        (JSC::initializeLLVM):
+        * llvm/InitializeLLVMPOSIX.cpp:
+        (JSC::initializeLLVMPOSIX):
+        * llvm/library/LLVMExports.cpp:
+        (llvmCrash):
+        (initializeAndGetJSCLLVMAPI):
+        * llvm/library/LLVMOverrides.cpp:
+        (raise):
+        (__assert_rtn):
+        (abort):
+        * llvm/library/LLVMTrapCallback.h: Added.
+
+2013-11-02  Filip Pizlo  <fpizlo@apple.com>
+
         CodeBlock::jettison() shouldn't call baselineVersion()
         https://bugs.webkit.org/show_bug.cgi?id=123675
 
index cbfadb8..2d43310 100644 (file)
@@ -35,22 +35,9 @@ namespace JSC {
 
 static pthread_once_t initializeLLVMOnceKey = PTHREAD_ONCE_INIT;
 
-static NO_RETURN_DUE_TO_CRASH void llvmCrash(const char* reason)
-{
-    WTFLogAlways("LLVM failure: %s", reason);
-    CRASH();
-}
-
-static void initializeLLVMOnce()
-{
-    initializeLLVMImpl();
-    
-    llvm->InstallFatalErrorHandler(llvmCrash);
-}
-
 void initializeLLVM()
 {
-    pthread_once(&initializeLLVMOnceKey, initializeLLVMOnce);
+    pthread_once(&initializeLLVMOnceKey, initializeLLVMImpl);
 }
 
 } // namespace JSC
index 2740922..156879d 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace JSC {
 
-typedef LLVMAPI* (*InitializerFunction)();
+typedef LLVMAPI* (*InitializerFunction)(void (*)(const char*, ...));
 
 void initializeLLVMPOSIX(const char* libraryName)
 {
@@ -44,7 +44,7 @@ void initializeLLVMPOSIX(const char* libraryName)
         dlsym(library, "initializeAndGetJSCLLVMAPI"));
     ASSERT_WITH_MESSAGE(initializer, "%s", dlerror());
     
-    llvm = initializer();
+    llvm = initializer(WTFLogAlwaysAndCrash);
 }
 
 } // namespace JSC
index 2f5f9ae..6e74b50 100644 (file)
 #if HAVE(LLVM)
 
 #include "LLVMAPI.h"
+#include "LLVMTrapCallback.h"
 
-extern "C" WTF_EXPORT_PRIVATE JSC::LLVMAPI* initializeAndGetJSCLLVMAPI();
+extern "C" WTF_EXPORT_PRIVATE JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*)(const char*, ...));
 
-extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI()
+static void llvmCrash(const char* reason)
 {
+    g_llvmTrapCallback("LLVM fatal error: %s", reason);
+}
+
+extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*callback)(const char*, ...))
+{
+    g_llvmTrapCallback = callback;
+    
+    LLVMInstallFatalErrorHandler(llvmCrash);
     LLVMLinkInMCJIT();
     LLVMInitializeNativeTarget();
     LLVMInitializeX86AsmPrinter();
index 463a49e..ced4066 100644 (file)
 
 #include "config_llvm.h"
 
+#include "LLVMTrapCallback.h"
+
 #if HAVE(LLVM)
 
 extern "C" int __cxa_atexit();
 extern "C" int __cxa_atexit() { return 0; }
 
+void (*g_llvmTrapCallback)(const char* message, ...);
+
+// If LLVM tries to raise signals, abort, or fail an assertion, then let
+// WebKit handle it instead of trapping.
+extern "C" int raise(int signal);
+extern "C" void __assert_rtn(const char* function, const char* filename, int lineNumber, const char* expression);
+extern "C" void abort(void);
+
+extern "C" int raise(int signal)
+{
+    g_llvmTrapCallback("raise(%d) called.", signal);
+    return 0;
+}
+extern "C" void __assert_rtn(const char* function, const char* filename, int lineNumber, const char* expression)
+{
+    if (function)
+        g_llvmTrapCallback("Assertion failed: (%s), function %s, file %s, line %d.", expression, function, filename, lineNumber);
+    g_llvmTrapCallback("Assertion failed: (%s), file %s, line %d.", expression, filename, lineNumber);
+}
+extern "C" void abort(void)
+{
+    g_llvmTrapCallback("abort() called.");
+}
+
 #endif // HAVE(LLVM)
diff --git a/Source/JavaScriptCore/llvm/library/LLVMTrapCallback.h b/Source/JavaScriptCore/llvm/library/LLVMTrapCallback.h
new file mode 100644 (file)
index 0000000..92620b0
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef LLVMTrapCallback_h
+#define LLVMTrapCallback_h
+
+extern void (*g_llvmTrapCallback)(const char* message, ...);
+
+#endif // LLVMTrapCallback_h
+
index e817885..e5a0119 100644 (file)
@@ -1,3 +1,15 @@
+2013-11-02  Filip Pizlo  <fpizlo@apple.com>
+
+        LLVM assertion failures should funnel into WTF's crash handling
+        https://bugs.webkit.org/show_bug.cgi?id=123682
+
+        Reviewed by Geoffrey Garen.
+        
+        Give JSC some new toys to play with for crash handling.
+
+        * wtf/Assertions.cpp:
+        * wtf/Assertions.h:
+
 2013-11-02  Patrick Gansterer  <paroga@webkit.org>
 
         Fix UnicodeWchar after r157330.
index aa902c6..3928468 100644 (file)
@@ -41,7 +41,6 @@
 #include <wtf/text/WTFString.h>
 
 #include <stdio.h>
-#include <stdarg.h>
 #include <string.h>
 
 #if HAVE(SIGNAL_H)
@@ -428,12 +427,26 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
     printCallSite(file, line, function);
 }
 
+void WTFLogAlwaysV(const char* format, va_list args)
+{
+    vprintf_stderr_with_trailing_newline(format, args);
+}
+
 void WTFLogAlways(const char* format, ...)
 {
     va_list args;
     va_start(args, format);
-    vprintf_stderr_with_trailing_newline(format, args);
+    WTFLogAlwaysV(format, args);
+    va_end(args);
+}
+
+void WTFLogAlwaysAndCrash(const char* format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    WTFLogAlwaysV(format, args);
     va_end(args);
+    WTFCrash();
 }
 
 WTFLogChannel* WTFLogChannelByName(WTFLogChannel* channels[], size_t count, const char* name)
index be7570a..2504b24 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <wtf/Platform.h>
 
+#include <stdarg.h>
 #include <stddef.h>
 
 #if !COMPILER(MSVC)
 extern "C" {
 #endif
 
+/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
+
+   Use CRASH() in response to known, unrecoverable errors like out-of-memory.
+   Macro is enabled in both debug and release mode.
+   To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
+
+   Signals are ignored by the crash reporter on OS X so we must do better.
+*/
+#if COMPILER(CLANG)
+#define NO_RETURN_DUE_TO_CRASH NO_RETURN
+#else
+#define NO_RETURN_DUE_TO_CRASH
+#endif
+
 typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
 
 typedef struct {
@@ -121,7 +136,9 @@ WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const ch
 WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
 WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
 WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
+WTF_EXPORT_PRIVATE void WTFLogAlwaysV(const char* format, va_list);
 WTF_EXPORT_PRIVATE void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
+WTF_EXPORT_PRIVATE void WTFLogAlwaysAndCrash(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2) NO_RETURN_DUE_TO_CRASH;
 WTF_EXPORT_PRIVATE WTFLogChannel* WTFLogChannelByName(WTFLogChannel*[], size_t count, const char*);
 WTF_EXPORT_PRIVATE void WTFInitializeLogChannelStatesFromString(WTFLogChannel*[], size_t count, const char*);
 
@@ -139,20 +156,6 @@ WTF_EXPORT_PRIVATE void WTFInvokeCrashHook();
 }
 #endif
 
-/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
-
-   Use CRASH() in response to known, unrecoverable errors like out-of-memory.
-   Macro is enabled in both debug and release mode.
-   To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
-
-   Signals are ignored by the crash reporter on OS X so we must do better.
-*/
-#if COMPILER(CLANG)
-#define NO_RETURN_DUE_TO_CRASH NO_RETURN
-#else
-#define NO_RETURN_DUE_TO_CRASH
-#endif
-
 #ifndef CRASH
 #define CRASH() WTFCrash()
 #endif
index 9440587..17bff86 100644 (file)
@@ -1,3 +1,14 @@
+2013-11-02  Filip Pizlo  <fpizlo@apple.com>
+
+        LLVM assertion failures should funnel into WTF's crash handling
+        https://bugs.webkit.org/show_bug.cgi?id=123682
+
+        Reviewed by Geoffrey Garen.
+        
+        Need to disable LLVM's crash overrides so that we can do our own crash overrides.
+
+        * Scripts/configure-llvm:
+
 2013-11-01  Andy Estes  <aestes@apple.com>
 
         Teach check-for-webkit-framework-include-consistency to ignore stale iOS Private headers that might exist in build directories due to r158443
index c72d89c..1b6eee5 100755 (executable)
@@ -37,5 +37,5 @@ fi
 # only want to build a backend for our current target) and to add more flags to remove
 # dependencies and features.
 
-./configure --enable-optimized=yes --enable-backtraces=no --enable-targets=x86_64 --enable-libcpp=yes --enable-zlib=no --enable-terminfo=no
+./configure --enable-optimized=yes --enable-backtraces=no --enable-targets=x86_64 --enable-libcpp=yes --enable-zlib=no --enable-terminfo=no --enable-crash-overrides=no