CrashRecoveryTest.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/Support/Compiler.h"
  9. #include "llvm/Support/CrashRecoveryContext.h"
  10. #include "gtest/gtest.h"
  11. #ifdef _WIN32
  12. #define WIN32_LEAN_AND_MEAN
  13. #define NOGDI
  14. #include <windows.h>
  15. #endif
  16. using namespace llvm;
  17. using namespace llvm::sys;
  18. static int GlobalInt = 0;
  19. static void nullDeref() { *(volatile int *)0x10 = 0; }
  20. static void incrementGlobal() { ++GlobalInt; }
  21. static void llvmTrap() { LLVM_BUILTIN_TRAP; }
  22. TEST(CrashRecoveryTest, Basic) {
  23. llvm::CrashRecoveryContext::Enable();
  24. GlobalInt = 0;
  25. EXPECT_TRUE(CrashRecoveryContext().RunSafely(incrementGlobal));
  26. EXPECT_EQ(1, GlobalInt);
  27. EXPECT_FALSE(CrashRecoveryContext().RunSafely(nullDeref));
  28. EXPECT_FALSE(CrashRecoveryContext().RunSafely(llvmTrap));
  29. }
  30. struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {
  31. IncrementGlobalCleanup(CrashRecoveryContext *CRC)
  32. : CrashRecoveryContextCleanup(CRC) {}
  33. virtual void recoverResources() { ++GlobalInt; }
  34. };
  35. static void noop() {}
  36. TEST(CrashRecoveryTest, Cleanup) {
  37. llvm::CrashRecoveryContext::Enable();
  38. GlobalInt = 0;
  39. {
  40. CrashRecoveryContext CRC;
  41. CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
  42. EXPECT_TRUE(CRC.RunSafely(noop));
  43. } // run cleanups
  44. EXPECT_EQ(1, GlobalInt);
  45. GlobalInt = 0;
  46. {
  47. CrashRecoveryContext CRC;
  48. CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
  49. EXPECT_FALSE(CRC.RunSafely(nullDeref));
  50. } // run cleanups
  51. EXPECT_EQ(1, GlobalInt);
  52. }
  53. #ifdef _WIN32
  54. static void raiseIt() {
  55. RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);
  56. }
  57. TEST(CrashRecoveryTest, RaiseException) {
  58. llvm::CrashRecoveryContext::Enable();
  59. EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));
  60. }
  61. static void outputString() {
  62. OutputDebugStringA("output for debugger\n");
  63. }
  64. TEST(CrashRecoveryTest, CallOutputDebugString) {
  65. llvm::CrashRecoveryContext::Enable();
  66. EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));
  67. }
  68. #endif