1
1
#include " stdafx.h"
2
2
#pragma hdrstop
3
3
4
+ #include < SDL.h>
5
+ #include < SDL_syswm.h>
6
+
4
7
#include " xrDebug.h"
5
8
#include " os_clipboard.h"
6
9
#include " log.h"
@@ -58,11 +61,11 @@ static BOOL bException = FALSE;
58
61
#endif
59
62
60
63
#if defined XR_X64
61
- # define MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
64
+ #define MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
62
65
#elif defined XR_X86
63
- # define MACHINE_TYPE IMAGE_FILE_MACHINE_I386
66
+ #define MACHINE_TYPE IMAGE_FILE_MACHINE_I386
64
67
#else
65
- # error CPU architecture is not supported.
68
+ #error CPU architecture is not supported.
66
69
#endif
67
70
68
71
namespace
@@ -92,6 +95,83 @@ ICN void* GetInstructionPtr()
92
95
}
93
96
}
94
97
98
+ enum MessageBoxResult
99
+ {
100
+ resultUndefined = -1 ,
101
+ resultContinue = 0 ,
102
+ resultTryAgain = 1 ,
103
+ resultCancel = 2
104
+ };
105
+
106
+ constexpr SDL_MessageBoxButtonData buttons[] =
107
+ {
108
+ /* .flags, .buttonid, .text */
109
+ { 0 , resultContinue, " Continue" },
110
+ { 0 , resultTryAgain, " Try again" },
111
+ { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT |
112
+ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
113
+ resultCancel, " Cancel" }
114
+ };
115
+
116
+ SDL_MessageBoxData messageboxdata =
117
+ {
118
+ SDL_MESSAGEBOX_ERROR,
119
+ nullptr ,
120
+ " Fatal error" ,
121
+ " Vse clomalocb, tashite novyy dvizhok" ,
122
+ SDL_arraysize (buttons),
123
+ buttons,
124
+ nullptr
125
+ };
126
+
127
+ int xrDebug::ShowMessage (pcstr title, pcstr message, bool simple)
128
+ {
129
+ #ifdef WINDOWS // because Windows default Message box is fancy
130
+ HWND hwnd = nullptr ;
131
+
132
+ if (applicationWindow)
133
+ {
134
+ SDL_SysWMinfo info;
135
+ SDL_VERSION (&info.version );
136
+ if (SDL_GetWindowWMInfo (applicationWindow, &info))
137
+ {
138
+ switch (info.subsystem )
139
+ {
140
+ case SDL_SYSWM_WINDOWS:
141
+ hwnd = info.info .win .window ;
142
+ break ;
143
+ default : break ;
144
+ }
145
+ }
146
+ }
147
+
148
+ if (simple)
149
+ return MessageBox (hwnd, message, title, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
150
+
151
+ const int result = MessageBox (hwnd, message, title,
152
+ MB_CANCELTRYCONTINUE | MB_ICONERROR | MB_SYSTEMMODAL);
153
+
154
+ switch (result)
155
+ {
156
+ case IDCANCEL: return resultCancel;
157
+ case IDTRYAGAIN: return resultTryAgain;
158
+ case IDCONTINUE: return resultContinue;
159
+ default : return resultUndefined;
160
+ }
161
+ #else
162
+ if (simple)
163
+ return SDL_ShowSimpleMessageBox (SDL_MESSAGEBOX_ERROR, title, message, applicationWindow);
164
+
165
+ messageboxdata.window = applicationWindow;
166
+ messageboxdata.title = title;
167
+ messageboxdata.message = message;
168
+ int button = resultUndefined;
169
+ SDL_ShowMessageBox (&messageboxdata, &button);
170
+ return button;
171
+ #endif
172
+ }
173
+
174
+ SDL_Window* xrDebug::applicationWindow = nullptr ;
95
175
xrDebug::UnhandledExceptionFilter xrDebug::PrevFilter = nullptr ;
96
176
xrDebug::OutOfMemoryCallbackFunc xrDebug::OutOfMemoryCallback = nullptr ;
97
177
xrDebug::CrashHandler xrDebug::OnCrash = nullptr ;
@@ -103,9 +183,9 @@ bool xrDebug::symEngineInitialized = false;
103
183
Lock xrDebug::dbgHelpLock;
104
184
105
185
#if defined(WINDOWS)
106
- void xrDebug::SetBugReportFile (const char * fileName) { strcpy_s (BugReportFile, fileName); }
186
+ void xrDebug::SetBugReportFile (const char * fileName) { xr_strcpy (BugReportFile, fileName); }
107
187
#elif defined(LINUX)
108
- void xrDebug::SetBugReportFile (const char * fileName) { strcpy_s (BugReportFile, 0 , fileName); }
188
+ void xrDebug::SetBugReportFile (const char * fileName) { xr_strcpy (BugReportFile, 0 , fileName); }
109
189
#endif
110
190
111
191
#if defined(WINDOWS)
@@ -245,7 +325,7 @@ xr_vector<xr_string> xrDebug::BuildStackTrace(PCONTEXT threadCtx, u16 maxFramesC
245
325
stackFrame.AddrFrame .Mode = AddrModeFlat;
246
326
stackFrame.AddrFrame .Offset = threadCtx->Ebp ;
247
327
#else
248
- # error CPU architecture is not supported.
328
+ #error CPU architecture is not supported.
249
329
#endif
250
330
251
331
while (GetNextStackFrameString (&stackFrame, threadCtx, frameStr) && traceResult.size () <= maxFramesCount)
@@ -377,7 +457,7 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
377
457
string4096 assertionInfo;
378
458
GatherInfo (assertionInfo, loc, expr, desc, arg1, arg2);
379
459
#ifdef USE_OWN_ERROR_MESSAGE_WINDOW
380
- strcat (assertionInfo,
460
+ xr_strcat (assertionInfo,
381
461
" \r\n "
382
462
" Press CANCEL to abort execution\r\n "
383
463
" Press TRY AGAIN to continue execution\r\n "
@@ -389,25 +469,29 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
389
469
if (OnDialog)
390
470
OnDialog (true );
391
471
FlushLog ();
392
- #if defined(WINDOWS)
393
472
if (Core.PluginMode )
394
- MessageBox ( NULL , assertionInfo, " X-Ray error" , MB_OK | MB_ICONERROR | MB_SYSTEMMODAL );
473
+ ShowMessage ( " X-Ray error" , assertionInfo );
395
474
else
396
475
{
397
476
#ifdef USE_OWN_ERROR_MESSAGE_WINDOW
398
- int result = MessageBox (NULL , assertionInfo, " Fatal error" ,
399
- MB_CANCELTRYCONTINUE | MB_ICONERROR | MB_SYSTEMMODAL);
400
- switch (result)
477
+ switch (ShowMessage (" Fatal error" , assertionInfo, false ))
401
478
{
402
- case IDCANCEL:
479
+ case resultUndefined:
480
+ xr_strcat (assertionInfo, SDL_GetError ());
481
+ [[fallthrough]];
482
+
483
+ case resultCancel:
403
484
#ifdef USE_BUG_TRAP
404
485
BT_SetUserMessage (assertionInfo);
405
486
#endif
406
487
DEBUG_BREAK;
407
488
break ;
408
- case IDTRYAGAIN: ErrorAfterDialog = false ;
489
+
490
+ case resultTryAgain:
491
+ ErrorAfterDialog = false ;
409
492
break ;
410
- case IDCONTINUE:
493
+
494
+ case resultContinue:
411
495
ErrorAfterDialog = false ;
412
496
ignoreAlways = true ;
413
497
break ;
@@ -420,7 +504,6 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
420
504
DEBUG_BREAK;
421
505
#endif
422
506
}
423
- #endif
424
507
if (OnDialog)
425
508
OnDialog (false );
426
509
@@ -436,8 +519,8 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
436
519
void xrDebug::DoExit (const std::string& message)
437
520
{
438
521
FlushLog ();
522
+ ShowMessage (" Error" , message.c_str ());
439
523
#if defined(WINDOWS)
440
- MessageBox (NULL , message.c_str (), " Error" , MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
441
524
TerminateProcess (GetCurrentProcess (), 1 );
442
525
#endif
443
526
}
@@ -491,13 +574,13 @@ void WINAPI xrDebug::PreErrorHandler(INT_PTR)
491
574
string256 currentDir;
492
575
_getcwd (currentDir, sizeof (currentDir));
493
576
string256 relDir;
494
- strcpy_s (relDir, logDir);
577
+ xr_strcpy (relDir, logDir);
495
578
strconcat (sizeof (logDir), logDir, currentDir, " \\ " , relDir);
496
579
}
497
580
}
498
581
__except (EXCEPTION_EXECUTE_HANDLER)
499
582
{
500
- strcpy_s (logDir, " logs" );
583
+ xr_strcpy (logDir, " logs" );
501
584
}
502
585
string_path temp;
503
586
strconcat (sizeof (temp), temp, logDir, log_name ());
@@ -573,7 +656,7 @@ void xrDebug::SaveMiniDump(EXCEPTION_POINTERS *exPtrs)
573
656
__except (EXCEPTION_EXECUTE_HANDLER)
574
657
{
575
658
string_path temp;
576
- strcpy_s (temp, dumpPath);
659
+ xr_strcpy (temp, dumpPath);
577
660
sprintf (dumpPath, " logs/%s" , temp);
578
661
}
579
662
WriteMiniDump (MINIDUMP_TYPE (MiniDumpFilterMemory | MiniDumpScanMemory), dumpPath, GetCurrentThreadId (), exPtrs);
@@ -628,7 +711,7 @@ LONG WINAPI xrDebug::UnhandledFilter(EXCEPTION_POINTERS* exPtrs)
628
711
{
629
712
if (shared_str_initialized)
630
713
Msg (" \n %s" , errMsg);
631
- strcat (errMsg, " \r\n " );
714
+ xr_strcat (errMsg, " \r\n " );
632
715
#ifdef DEBUG
633
716
if (!IsDebuggerPresent ())
634
717
os_clipboard::update_clipboard (buffer);
@@ -646,10 +729,9 @@ LONG WINAPI xrDebug::UnhandledFilter(EXCEPTION_POINTERS* exPtrs)
646
729
{
647
730
if (OnDialog)
648
731
OnDialog (true );
649
- MessageBox (NULL ,
650
- " Fatal error occurred\n\n "
651
- " Press OK to abort program execution" ,
652
- " Fatal error" , MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
732
+ constexpr pcstr msg = " Fatal error occurred\n\n "
733
+ " Press OK to abort program execution" ;
734
+ ShowMessage (" Fatal error" , msg);
653
735
}
654
736
#endif
655
737
ReportFault (exPtrs, 0 );
@@ -671,11 +753,11 @@ void _terminate()
671
753
#if defined(WINDOWS)
672
754
if (strstr (GetCommandLine (), " -silent_error_mode" ))
673
755
exit (-1 );
756
+ #endif
674
757
string4096 assertionInfo;
675
758
xrDebug::GatherInfo (assertionInfo, DEBUG_INFO, nullptr , " Unexpected application termination" );
676
- strcat (assertionInfo, " Press OK to abort execution\r\n " );
677
- MessageBox (GetTopWindow (NULL ), assertionInfo, " Fatal Error" , MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
678
- #endif
759
+ xr_strcat (assertionInfo, " Press OK to abort execution\r\n " );
760
+ ShowMessage (" Fatal Error" , assertionInfo);
679
761
exit (-1 );
680
762
}
681
763
#endif // USE_BUG_TRAP
0 commit comments