Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
4.5 KiB

  1. // Copyright (c) 2000 Microsoft Corporation
  2. //
  3. // ASSERT macro
  4. //
  5. // 3 Mar 2000 sburns
  6. #include "headers.hxx"
  7. int
  8. AddStackTraceLine(
  9. DWORD64 traceAddress,
  10. char* buffer,
  11. size_t bufferMax)
  12. {
  13. if (!buffer || ! traceAddress || !bufferMax)
  14. {
  15. return 0;
  16. }
  17. char ansiSymbol[Burnslib::StackTrace::SYMBOL_NAME_MAX];
  18. char ansiModule[Burnslib::StackTrace::MODULE_NAME_MAX];
  19. char ansiSource[MAX_PATH];
  20. DWORD64 displacement = 0;
  21. DWORD line = 0;
  22. // REVIEWED-2002/03/05-sburns correct byte counts passed.
  23. ::ZeroMemory(ansiSymbol, Burnslib::StackTrace::SYMBOL_NAME_MAX);
  24. ::ZeroMemory(ansiModule, Burnslib::StackTrace::MODULE_NAME_MAX);
  25. ::ZeroMemory(ansiSource, MAX_PATH);
  26. Burnslib::StackTrace::LookupAddress(
  27. traceAddress,
  28. ansiModule,
  29. 0,
  30. ansiSymbol,
  31. &displacement,
  32. &line,
  33. ansiSource);
  34. return
  35. // ISSUE-2002/03/05-sburns consider strsafe.h replacement
  36. _snprintf(
  37. buffer,
  38. bufferMax,
  39. " %016I64X %s%!%s+0x%I64X %s (%d)\n",
  40. traceAddress,
  41. ansiModule,
  42. ansiSymbol,
  43. displacement,
  44. ansiSource,
  45. line);
  46. }
  47. bool
  48. Burnslib::FireAssertionFailure(const char* file, int line, const char* expr)
  49. {
  50. //
  51. // DON'T CALL ASSERT() IN THIS FUNCTION!
  52. //
  53. // also don't call new, or any other code that could call ASSERT.
  54. bool result = false;
  55. char processName[128];
  56. char* pProcessName = processName;
  57. if (!::GetModuleFileNameA(0, processName, 128))
  58. {
  59. pProcessName = "Unknown";
  60. }
  61. static const int MAX_MSG = 2047;
  62. // NTRAID#NTBUG9-541418-2002/03/28-sburns
  63. char details[MAX_MSG + 1];
  64. // REVIEWED-2002/03/05-sburns correct byte count passed.
  65. ::ZeroMemory(details, MAX_MSG + 1);
  66. DWORD tid = ::GetCurrentThreadId();
  67. DWORD pid = ::GetCurrentProcessId();
  68. int used =
  69. // ISSUE-2002/03/05-sburns consider strsafe.h replacement
  70. _snprintf(
  71. details,
  72. // reserve space so that we can guarantee null-termination
  73. MAX_MSG - 1,
  74. " Expression: %s \n"
  75. "\n"
  76. " File \t : %s \n"
  77. " Line \t : %d \n"
  78. // " Module \t : %s \n"
  79. " Process\t : 0x%X (%d) %s\n"
  80. " Thread \t : 0x%X (%d)\n"
  81. "\n"
  82. " Click Retry to debug.\n"
  83. "\n",
  84. expr,
  85. file,
  86. line,
  87. // pModuleName,
  88. pid,
  89. pid,
  90. pProcessName,
  91. tid,
  92. tid);
  93. if (used < 0)
  94. {
  95. // ISSUE-2002/03/05-sburns consider strsafe.h replacement, use 'n'
  96. // variant
  97. strcpy(details, "details too detailed.\n");
  98. }
  99. else
  100. {
  101. // grab a stack trace
  102. static const size_t TRACE_MAX = 10;
  103. DWORD64 stackTrace[TRACE_MAX];
  104. Burnslib::StackTrace::Trace(stackTrace, TRACE_MAX);
  105. // build a stack trace dump
  106. // skip the first entry, which corresponds to this function, so that
  107. // the dump reflects the call stack at the point of assertion failure.
  108. // so there will be at most TRACE_MAX - 1 lines output.
  109. for (int i = 1; stackTrace[i] && i < TRACE_MAX; ++i)
  110. {
  111. int used2 =
  112. AddStackTraceLine(
  113. stackTrace[i],
  114. details + used,
  115. MAX_MSG - used);
  116. if (used2 < 0)
  117. {
  118. break;
  119. }
  120. used += used2;
  121. }
  122. }
  123. static const char* TITLE = "Assertion Failed!";
  124. ::OutputDebugStringA(TITLE);
  125. ::OutputDebugStringA("\n");
  126. ::OutputDebugStringA(details);
  127. switch (
  128. ::MessageBoxA(
  129. 0,
  130. details,
  131. TITLE,
  132. MB_SETFOREGROUND
  133. // ICONHAND + SYSTEMMODAL gets us the special low-memory
  134. // message box.
  135. // NTRAID#NTBUG9-556530-2002/03/28-sburns
  136. | MB_ICONHAND
  137. | MB_SYSTEMMODAL
  138. | MB_ABORTRETRYIGNORE))
  139. {
  140. case IDABORT:
  141. {
  142. _exit(3);
  143. }
  144. case IDRETRY:
  145. {
  146. // user wants to drop into the debugger.
  147. result = true;
  148. break;
  149. }
  150. case IDIGNORE:
  151. case IDCANCEL:
  152. default:
  153. {
  154. // do nothing
  155. break;
  156. }
  157. }
  158. return result;
  159. }