debug.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // FILE: debug.cpp ////////////////////////////////////////////////////////
  19. // Minmal debug info
  20. // Author: Matthew D. Campbell, Sept 2002
  21. #include <windows.h>
  22. #include "debug.h"
  23. #include <cstdio>
  24. char* TheCurrentIgnoreCrashPtr;
  25. #define LARGE_BUFFER 8192
  26. static char theBuffer[ LARGE_BUFFER ]; // make it big to avoid weird overflow bugs in debug mode
  27. static int doCrashBox(const char *buffer, bool logResult)
  28. {
  29. int result;
  30. result = ::MessageBox(NULL, buffer, "Assertion Failure", MB_ABORTRETRYIGNORE|MB_APPLMODAL|MB_ICONWARNING);
  31. switch(result)
  32. {
  33. case IDABORT:
  34. #ifdef DEBUG_LOGGING
  35. if (logResult)
  36. DebugLog("[Abort]\n");
  37. #endif
  38. _exit(1);
  39. break;
  40. case IDRETRY:
  41. #ifdef DEBUG_LOGGING
  42. if (logResult)
  43. DebugLog("[Retry]\n");
  44. #endif
  45. ::DebugBreak();
  46. break;
  47. case IDIGNORE:
  48. #ifdef DEBUG_LOGGING
  49. // do nothing, just keep going
  50. if (logResult)
  51. DebugLog("[Ignore]\n");
  52. #endif
  53. break;
  54. }
  55. return result;
  56. }
  57. #ifdef DEBUG
  58. void DebugLog(const char *fmt, ...)
  59. {
  60. va_list va;
  61. va_start( va, fmt );
  62. vsnprintf(theBuffer, LARGE_BUFFER, fmt, va );
  63. theBuffer[LARGE_BUFFER-1] = 0;
  64. va_end( va );
  65. OutputDebugString(theBuffer);
  66. printf( "%s", theBuffer );
  67. }
  68. #endif // DEBUG
  69. #ifdef DEBUG_CRASHING
  70. void DebugCrash(const char *format, ...)
  71. {
  72. theBuffer[0] = 0;
  73. strcat(theBuffer, "ASSERTION FAILURE: ");
  74. va_list arg;
  75. va_start(arg, format);
  76. vsprintf(theBuffer + strlen(theBuffer), format, arg);
  77. va_end(arg);
  78. if (strlen(theBuffer) >= sizeof(theBuffer))
  79. ::MessageBox(NULL, "String too long for debug buffers", "", MB_OK|MB_APPLMODAL);
  80. OutputDebugString(theBuffer);
  81. printf( "%s", theBuffer );
  82. strcat(theBuffer, "\n\nAbort->exception; Retry->debugger; Ignore->continue\n");
  83. int result = doCrashBox(theBuffer, true);
  84. if (result == IDIGNORE && TheCurrentIgnoreCrashPtr != NULL)
  85. {
  86. int yn;
  87. yn = ::MessageBox(NULL, "Ignore this crash from now on?", "", MB_YESNO|MB_APPLMODAL);
  88. if (yn == IDYES)
  89. *TheCurrentIgnoreCrashPtr = 1;
  90. }
  91. }
  92. #endif