ReportError.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. enum ErrorReason
  7. {
  8. JavascriptDispatch_OUTOFMEMORY = 1,
  9. Fatal_Internal_Error = 2,
  10. Fatal_Debug_Heap_OUTOFMEMORY = 3,
  11. Fatal_Amd64StackWalkerOutOfContexts = 4,
  12. // Unused = 5,
  13. Fatal_Binary_Inconsistency = 6,
  14. WriteBarrier_OUTOFMEMORY = 7,
  15. CustomHeap_MEMORYCORRUPTION = 8,
  16. LargeHeapBlock_Metadata_Corrupt = 9,
  17. Fatal_Version_Inconsistency = 10,
  18. MarkStack_OUTOFMEMORY = 11,
  19. EnterScript_FromDOM_NoScriptScope = 12,
  20. Fatal_FailedToBox_OUTOFMEMORY = 13
  21. };
  22. extern "C" void ReportFatalException(
  23. __in ULONG_PTR context,
  24. __in HRESULT exceptionCode,
  25. __in ErrorReason reasonCode,
  26. __in ULONG scenario);
  27. // We can have other error handle code path with
  28. // unique call stack so we can collect data in Dr. Watson.
  29. void JavascriptDispatch_OOM_fatal_error(
  30. __in ULONG_PTR context);
  31. void CustomHeap_BadPageState_fatal_error(
  32. __in ULONG_PTR context);
  33. void Amd64StackWalkerOutOfContexts_fatal_error(
  34. __in ULONG_PTR context);
  35. void FailedToBox_OOM_fatal_error(
  36. __in ULONG_PTR context);
  37. #if defined(RECYCLER_WRITE_BARRIER) && defined(_M_X64_OR_ARM64)
  38. void X64WriteBarrier_OOM_fatal_error();
  39. #endif
  40. void DebugHeap_OOM_fatal_error();
  41. void MarkStack_OOM_fatal_error();
  42. void Binary_Inconsistency_fatal_error();
  43. void Version_Inconsistency_fatal_error();
  44. #ifdef LARGEHEAPBLOCK_ENCODING
  45. void LargeHeapBlock_Metadata_Corrupted(
  46. __in ULONG_PTR context, __in unsigned char calculatedCheckSum);
  47. #endif
  48. void FromDOM_NoScriptScope_fatal_error();
  49. #ifndef DISABLE_SEH
  50. // RtlReportException is available on Vista and up, but we cannot use it for OOB release.
  51. // Use UnhandleExceptionFilter to let the default handler handles it.
  52. __inline LONG FatalExceptionFilter(
  53. __in LPEXCEPTION_POINTERS lpep)
  54. {
  55. LONG rc = UnhandledExceptionFilter(lpep);
  56. // re == EXCEPTION_EXECUTE_HANDLER means there is no debugger attached, let's terminate
  57. // the process. Otherwise give control to the debugger.
  58. // Note: in case when postmortem debugger is registered but no actual debugger attached,
  59. // rc will be 0 (and EXCEPTION_EXECUTE_HANDLER is 1), so it acts as if there is debugger attached.
  60. if (rc == EXCEPTION_EXECUTE_HANDLER)
  61. {
  62. TerminateProcess(GetCurrentProcess(), (UINT)DBG_TERMINATE_PROCESS);
  63. }
  64. else
  65. {
  66. // However, if debugger was not attached for some reason, terminate the process.
  67. if (!IsDebuggerPresent())
  68. {
  69. TerminateProcess(GetCurrentProcess(), (UINT)DBG_TERMINATE_PROCESS);
  70. }
  71. DebugBreak();
  72. }
  73. return EXCEPTION_CONTINUE_SEARCH;
  74. }
  75. #endif // DISABLE_SEH
  76. template<class Fn>
  77. static STDMETHODIMP DebugApiWrapper(Fn fn)
  78. {
  79. // If an assertion or AV is hit, it triggers a SEH exception. SEH exceptions escaped here will be eaten by PDM. To prevent assertions
  80. // from getting unnoticed, we install a SEH exception filter and crash the process.
  81. #if ENABLE_DEBUG_API_WRAPPER
  82. __try
  83. {
  84. #endif
  85. return fn();
  86. #if ENABLE_DEBUG_API_WRAPPER
  87. }
  88. __except(FatalExceptionFilter(GetExceptionInformation()))
  89. {
  90. }
  91. return E_FAIL;
  92. #endif
  93. }