summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Support/CrashRecoveryTest.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-05-17 18:16:17 +0000
committerReid Kleckner <rnk@google.com>2017-05-17 18:16:17 +0000
commit710c1cebb4b916ed20dc05d30d71650ff62e1071 (patch)
treeb0104745cb7dee0f9ca49d265082e42c4425d4cd /llvm/unittests/Support/CrashRecoveryTest.cpp
parentc8556788a0894ae62f109b08322909c82c12ef0b (diff)
downloadbcm5719-llvm-710c1cebb4b916ed20dc05d30d71650ff62e1071.tar.gz
bcm5719-llvm-710c1cebb4b916ed20dc05d30d71650ff62e1071.zip
Re-land r303274: "[CrashRecovery] Use SEH __try instead of VEH when available"
We have to check gCrashRecoveryEnabled before using __try. In other words, SEH works too well and we ended up recovering from crashes in implicit module builds that we weren't supposed to. Only libclang is supposed to enable CrashRecoveryContext to allow implicit module builds to crash. llvm-svn: 303279
Diffstat (limited to 'llvm/unittests/Support/CrashRecoveryTest.cpp')
-rw-r--r--llvm/unittests/Support/CrashRecoveryTest.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/llvm/unittests/Support/CrashRecoveryTest.cpp b/llvm/unittests/Support/CrashRecoveryTest.cpp
new file mode 100644
index 00000000000..dbb0db57679
--- /dev/null
+++ b/llvm/unittests/Support/CrashRecoveryTest.cpp
@@ -0,0 +1,83 @@
+//===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/Compiler.h"
+#include "gtest/gtest.h"
+
+#ifdef LLVM_ON_WIN32
+#define WIN32_LEAN_AND_MEAN
+#define NOGDI
+#include <windows.h>
+#endif
+
+using namespace llvm;
+using namespace llvm::sys;
+
+static int GlobalInt = 0;
+static void nullDeref() { *(volatile int *)nullptr = 0; }
+static void incrementGlobal() { ++GlobalInt; }
+static void llvmTrap() { LLVM_BUILTIN_TRAP; }
+
+TEST(CrashRecoveryTest, Basic) {
+ llvm::CrashRecoveryContext::Enable();
+ GlobalInt = 0;
+ EXPECT_TRUE(CrashRecoveryContext().RunSafely(incrementGlobal));
+ EXPECT_EQ(1, GlobalInt);
+ EXPECT_FALSE(CrashRecoveryContext().RunSafely(nullDeref));
+ EXPECT_FALSE(CrashRecoveryContext().RunSafely(llvmTrap));
+}
+
+struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {
+ IncrementGlobalCleanup(CrashRecoveryContext *CRC)
+ : CrashRecoveryContextCleanup(CRC) {}
+ virtual void recoverResources() { ++GlobalInt; }
+};
+
+static void noop() {}
+
+TEST(CrashRecoveryTest, Cleanup) {
+ llvm::CrashRecoveryContext::Enable();
+ GlobalInt = 0;
+ {
+ CrashRecoveryContext CRC;
+ CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
+ EXPECT_TRUE(CRC.RunSafely(noop));
+ } // run cleanups
+ EXPECT_EQ(1, GlobalInt);
+
+ GlobalInt = 0;
+ {
+ CrashRecoveryContext CRC;
+ CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
+ EXPECT_FALSE(CRC.RunSafely(nullDeref));
+ } // run cleanups
+ EXPECT_EQ(1, GlobalInt);
+}
+
+#ifdef LLVM_ON_WIN32
+static void raiseIt() {
+ RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);
+}
+
+TEST(CrashRecoveryTest, RaiseException) {
+ llvm::CrashRecoveryContext::Enable();
+ EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));
+}
+
+static void outputString() {
+ OutputDebugStringA("output for debugger\n");
+}
+
+TEST(CrashRecoveryTest, CallOutputDebugString) {
+ llvm::CrashRecoveryContext::Enable();
+ EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));
+}
+
+#endif
OpenPOWER on IntegriCloud