ReportError.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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. Fatal_Recycler_MemoryCorruption = 14,
  22. Fatal_Debugger_AttachDetach_Failure = 15,
  23. Fatal_EntryExitRecordCorruption = 16,
  24. Fatal_UnexpectedExceptionHandling = 17,
  25. Fatal_RpcFailure = 18,
  26. Fatal_JsReentrancy_Error = 19,
  27. Fatal_TTDAbort = 20,
  28. Fatal_Failed_API_Result = 21,
  29. Fatal_OutOfMemory = 22,
  30. // Unused = 23,
  31. Fatal_JsBuiltIn_Error = 24,
  32. Fatal_XDataRegistration = 25,
  33. };
  34. extern "C" void ReportFatalException(
  35. __in ULONG_PTR context,
  36. __in HRESULT exceptionCode,
  37. __in ErrorReason reasonCode,
  38. __in ULONG_PTR scenario);
  39. // We can have other error handle code path with
  40. // unique call stack so we can collect data in Dr. Watson.
  41. void JavascriptDispatch_OOM_fatal_error(
  42. __in ULONG_PTR context);
  43. void CustomHeap_BadPageState_unrecoverable_error(
  44. __in ULONG_PTR context);
  45. void Amd64StackWalkerOutOfContexts_unrecoverable_error(
  46. __in ULONG_PTR context);
  47. void FailedToBox_OOM_unrecoverable_error(
  48. __in ULONG_PTR context);
  49. #if defined(RECYCLER_WRITE_BARRIER) && defined(TARGET_64)
  50. void X64WriteBarrier_OOM_unrecoverable_error();
  51. #endif
  52. void DebugHeap_OOM_fatal_error();
  53. void MarkStack_OOM_unrecoverable_error();
  54. void Binary_Inconsistency_fatal_error();
  55. void Version_Inconsistency_fatal_error();
  56. void EntryExitRecord_Corrupted_unrecoverable_error();
  57. void UnexpectedExceptionHandling_fatal_error();
  58. #ifdef LARGEHEAPBLOCK_ENCODING
  59. void LargeHeapBlock_Metadata_Corrupted(
  60. __in ULONG_PTR context, __in unsigned char calculatedCheckSum);
  61. #endif
  62. void FromDOM_NoScriptScope_unrecoverable_error();
  63. void Debugger_AttachDetach_unrecoverable_error(HRESULT hr);
  64. void RpcFailure_unrecoverable_error(HRESULT hr);
  65. void OutOfMemory_unrecoverable_error();
  66. void RecyclerSingleAllocationLimit_unrecoverable_error();
  67. void MemGCSingleAllocationLimit_unrecoverable_error();
  68. void OutOfMemoryTooManyPinnedObjects_unrecoverable_error();
  69. void OutOfMemoryTooManyClosedContexts_unrecoverable_error();
  70. void OutOfMemoryAllocationPolicy_unrecoverable_error();
  71. void OutOfMemoryTooManyPinnedObjects_unrecoverable_error_visible();
  72. void OutOfMemoryTooManyClosedContexts_unrecoverable_error_visible();
  73. void OutOfMemoryAllocationPolicy_unrecoverable_error_visible();
  74. void OutOfMemoryTooManyPinnedObjects_unrecoverable_error_notvisible();
  75. void OutOfMemoryTooManyClosedContexts_unrecoverable_error_notvisible();
  76. void OutOfMemoryAllocationPolicy_unrecoverable_error_notvisible();
  77. void XDataRegistration_unrecoverable_error(HRESULT hr, ULONG_PTR scenario);
  78. inline void OutOfMemoryTooManyPinnedObjects_unrecoverable_error(BYTE visibility)
  79. {
  80. switch (visibility)
  81. {
  82. case 1:
  83. OutOfMemoryTooManyPinnedObjects_unrecoverable_error_visible();
  84. break;
  85. case 2:
  86. OutOfMemoryTooManyPinnedObjects_unrecoverable_error_notvisible();
  87. break;
  88. default:
  89. OutOfMemoryTooManyPinnedObjects_unrecoverable_error();
  90. break;
  91. }
  92. }
  93. inline void OutOfMemoryTooManyClosedContexts_unrecoverable_error(BYTE visibility)
  94. {
  95. switch (visibility)
  96. {
  97. case 1:
  98. OutOfMemoryTooManyClosedContexts_unrecoverable_error_visible();
  99. break;
  100. case 2:
  101. OutOfMemoryTooManyClosedContexts_unrecoverable_error_notvisible();
  102. break;
  103. default:
  104. OutOfMemoryTooManyClosedContexts_unrecoverable_error();
  105. break;
  106. }
  107. }
  108. inline void OutOfMemoryAllocationPolicy_unrecoverable_error(BYTE visibility)
  109. {
  110. switch (visibility)
  111. {
  112. case 1:
  113. OutOfMemoryAllocationPolicy_unrecoverable_error_visible();
  114. break;
  115. case 2:
  116. OutOfMemoryAllocationPolicy_unrecoverable_error_notvisible();
  117. break;
  118. default:
  119. OutOfMemoryAllocationPolicy_unrecoverable_error();
  120. break;
  121. }
  122. }
  123. #ifndef DISABLE_SEH
  124. // RtlReportException is available on Vista and up, but we cannot use it for OOB release.
  125. // Use UnhandleExceptionFilter to let the default handler handles it.
  126. inline LONG FatalExceptionFilter(
  127. __in LPEXCEPTION_POINTERS lpep,
  128. __in void * addressToBlame = nullptr)
  129. {
  130. if (addressToBlame != nullptr)
  131. {
  132. lpep->ExceptionRecord->ExceptionAddress = addressToBlame;
  133. }
  134. LONG rc = UnhandledExceptionFilter(lpep);
  135. // re == EXCEPTION_EXECUTE_HANDLER means there is no debugger attached, let's terminate
  136. // the process. Otherwise give control to the debugger.
  137. // Note: in case when postmortem debugger is registered but no actual debugger attached,
  138. // rc will be 0 (and EXCEPTION_EXECUTE_HANDLER is 1), so it acts as if there is debugger attached.
  139. if (rc == EXCEPTION_EXECUTE_HANDLER)
  140. {
  141. TerminateProcess(GetCurrentProcess(), (UINT)DBG_TERMINATE_PROCESS);
  142. }
  143. else
  144. {
  145. // However, if debugger was not attached for some reason, terminate the process.
  146. if (!IsDebuggerPresent())
  147. {
  148. TerminateProcess(GetCurrentProcess(), (UINT)DBG_TERMINATE_PROCESS);
  149. }
  150. DebugBreak();
  151. }
  152. return EXCEPTION_CONTINUE_SEARCH;
  153. }
  154. #endif // DISABLE_SEH
  155. template<class Fn>
  156. static STDMETHODIMP DebugApiWrapper(Fn fn)
  157. {
  158. // If an assertion or AV is hit, it triggers a SEH exception. SEH exceptions escaped here will be eaten by PDM. To prevent assertions
  159. // from getting unnoticed, we install a SEH exception filter and crash the process.
  160. #if ENABLE_DEBUG_API_WRAPPER
  161. __try
  162. {
  163. #endif
  164. return fn();
  165. #if ENABLE_DEBUG_API_WRAPPER
  166. }
  167. __except(FatalExceptionFilter(GetExceptionInformation()))
  168. {
  169. }
  170. return E_FAIL;
  171. #endif
  172. }