blob: e9ffd1f8871f8a6c9ef287268409545e42b432cb [file] [log] [blame]
Reid Kleckner710c1ce2017-05-17 18:16:17 +00001//===- 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/CrashRecoveryContext.h"
11#include "llvm/Support/Compiler.h"
12#include "gtest/gtest.h"
13
14#ifdef LLVM_ON_WIN32
15#define WIN32_LEAN_AND_MEAN
16#define NOGDI
17#include <windows.h>
18#endif
19
20using namespace llvm;
21using namespace llvm::sys;
22
23static int GlobalInt = 0;
Vitaly Buka1887dd82017-05-24 18:11:57 +000024static void nullDeref() { *(volatile int *)0x10 = 0; }
Reid Kleckner710c1ce2017-05-17 18:16:17 +000025static void incrementGlobal() { ++GlobalInt; }
26static void llvmTrap() { LLVM_BUILTIN_TRAP; }
27
28TEST(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
37struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {
38 IncrementGlobalCleanup(CrashRecoveryContext *CRC)
39 : CrashRecoveryContextCleanup(CRC) {}
40 virtual void recoverResources() { ++GlobalInt; }
41};
42
43static void noop() {}
44
45TEST(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 LLVM_ON_WIN32
65static void raiseIt() {
66 RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);
67}
68
69TEST(CrashRecoveryTest, RaiseException) {
70 llvm::CrashRecoveryContext::Enable();
71 EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));
72}
73
74static void outputString() {
75 OutputDebugStringA("output for debugger\n");
76}
77
78TEST(CrashRecoveryTest, CallOutputDebugString) {
79 llvm::CrashRecoveryContext::Enable();
80 EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));
81}
82
83#endif