• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/Support/Compiler.h"
11 #include "llvm/Support/CrashRecoveryContext.h"
12 #include "gtest/gtest.h"
13 
14 #ifdef _WIN32
15 #define WIN32_LEAN_AND_MEAN
16 #define NOGDI
17 #include <windows.h>
18 #endif
19 
20 using namespace llvm;
21 using namespace llvm::sys;
22 
23 static int GlobalInt = 0;
nullDeref()24 static void nullDeref() { *(volatile int *)0x10 = 0; }
incrementGlobal()25 static void incrementGlobal() { ++GlobalInt; }
llvmTrap()26 static void llvmTrap() { LLVM_BUILTIN_TRAP; }
27 
TEST(CrashRecoveryTest,Basic)28 TEST(CrashRecoveryTest, Basic) {
29   llvm::CrashRecoveryContext::Enable();
30   GlobalInt = 0;
31   EXPECT_TRUE(CrashRecoveryContext().RunSafely(incrementGlobal));
32   EXPECT_EQ(1, GlobalInt);
33   EXPECT_FALSE(CrashRecoveryContext().RunSafely(nullDeref));
34   EXPECT_FALSE(CrashRecoveryContext().RunSafely(llvmTrap));
35 }
36 
37 struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {
IncrementGlobalCleanupIncrementGlobalCleanup38   IncrementGlobalCleanup(CrashRecoveryContext *CRC)
39       : CrashRecoveryContextCleanup(CRC) {}
recoverResourcesIncrementGlobalCleanup40   virtual void recoverResources() { ++GlobalInt; }
41 };
42 
noop()43 static void noop() {}
44 
TEST(CrashRecoveryTest,Cleanup)45 TEST(CrashRecoveryTest, Cleanup) {
46   llvm::CrashRecoveryContext::Enable();
47   GlobalInt = 0;
48   {
49     CrashRecoveryContext CRC;
50     CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
51     EXPECT_TRUE(CRC.RunSafely(noop));
52   } // run cleanups
53   EXPECT_EQ(1, GlobalInt);
54 
55   GlobalInt = 0;
56   {
57     CrashRecoveryContext CRC;
58     CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
59     EXPECT_FALSE(CRC.RunSafely(nullDeref));
60   } // run cleanups
61   EXPECT_EQ(1, GlobalInt);
62 }
63 
64 #ifdef _WIN32
raiseIt()65 static void raiseIt() {
66   RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);
67 }
68 
TEST(CrashRecoveryTest,RaiseException)69 TEST(CrashRecoveryTest, RaiseException) {
70   llvm::CrashRecoveryContext::Enable();
71   EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));
72 }
73 
outputString()74 static void outputString() {
75   OutputDebugStringA("output for debugger\n");
76 }
77 
TEST(CrashRecoveryTest,CallOutputDebugString)78 TEST(CrashRecoveryTest, CallOutputDebugString) {
79   llvm::CrashRecoveryContext::Enable();
80   EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));
81 }
82 
83 #endif
84