@@ -38,6 +38,102 @@ static HWND hExitButton;
3838
3939static qtwebapp::LoggerWithFile *crashLogger;
4040
41+ static void appendStackTrace (char *&reportBufferPtr, int &reportBufferRemaining)
42+ {
43+ STACKFRAME64 stack;
44+ CONTEXT context;
45+ HANDLE process;
46+ DWORD64 displacement;
47+ ULONG frame;
48+ BOOL symInit;
49+ char symName[(MAX_PATH * sizeof (TCHAR))];
50+ char storage[sizeof (IMAGEHLP_SYMBOL64) + (sizeof (symName))];
51+ IMAGEHLP_SYMBOL64* symbol;
52+
53+ RtlCaptureContext (&context);
54+ memset (&stack, 0 , sizeof (STACKFRAME64));
55+ #if defined(_AMD64_)
56+ stack.AddrPC .Offset = context.Rip ;
57+ stack.AddrPC .Mode = AddrModeFlat;
58+ stack.AddrStack .Offset = context.Rsp ;
59+ stack.AddrStack .Mode = AddrModeFlat;
60+ stack.AddrFrame .Offset = context.Rbp ;
61+ stack.AddrFrame .Mode = AddrModeFlat;
62+ #else
63+ stack.AddrPC .Offset = context.Eip ;
64+ stack.AddrPC .Mode = AddrModeFlat;
65+ stack.AddrStack .Offset = context.Esp ;
66+ stack.AddrStack .Mode = AddrModeFlat;
67+ stack.AddrFrame .Offset = context.Ebp ;
68+ stack.AddrFrame .Mode = AddrModeFlat;
69+ #endif
70+ displacement = 0 ;
71+ process = GetCurrentProcess ();
72+ symInit = SymInitialize (process, " plugins" , TRUE );
73+ symbol = (IMAGEHLP_SYMBOL64*) storage;
74+
75+ if (!symInit)
76+ {
77+ int written = snprintf (reportBufferPtr, reportBufferRemaining, " (symbol init failed)\r\n " );
78+ if (written > 0 )
79+ {
80+ reportBufferPtr += written;
81+ reportBufferRemaining -= written;
82+ }
83+ return ;
84+ }
85+
86+ for (frame = 0 ; reportBufferRemaining > 0 ; frame++)
87+ {
88+ BOOL result = StackWalk (IMAGE_FILE_MACHINE_AMD64,
89+ process,
90+ GetCurrentThread (),
91+ &stack,
92+ &context,
93+ NULL ,
94+ SymFunctionTableAccess64,
95+ SymGetModuleBase64,
96+ NULL );
97+
98+ if (result)
99+ {
100+ symbol->SizeOfStruct = sizeof (storage);
101+ symbol->MaxNameLength = sizeof (symName);
102+
103+ BOOL symResult = SymGetSymFromAddr64 (process, (ULONG64)stack.AddrPC .Offset , &displacement, symbol);
104+ if (symResult) {
105+ UnDecorateSymbolName (symbol->Name , (PSTR)symName, sizeof (symName), UNDNAME_COMPLETE);
106+ }
107+
108+ int written = snprintf (
109+ reportBufferPtr,
110+ reportBufferRemaining,
111+ " %02u 0x%p %s\r\n " ,
112+ frame,
113+ stack.AddrPC .Offset ,
114+ symResult ? symbol->Name : " Unknown"
115+ );
116+ if (written > 0 )
117+ {
118+ if (written <= reportBufferRemaining)
119+ {
120+ reportBufferPtr += written;
121+ reportBufferRemaining -= written;
122+ }
123+ else
124+ {
125+ reportBufferPtr += reportBufferRemaining;
126+ reportBufferRemaining = 0 ;
127+ }
128+ }
129+ }
130+ else
131+ {
132+ break ;
133+ }
134+ }
135+ }
136+
41137static void ScaleWindow (HWND wnd, int x, int y, int w, int h)
42138{
43139 int dpi = GetDpiForWindow (wnd);
@@ -273,88 +369,7 @@ static LONG crashHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
273369 reportBufferRemaining -= written;
274370
275371 // Create stack trace
276-
277- STACKFRAME64 stack;
278- CONTEXT context;
279- HANDLE process;
280- DWORD64 displacement;
281- ULONG frame;
282- BOOL symInit;
283- char symName[(MAX_PATH * sizeof (TCHAR))];
284- char storage[sizeof (IMAGEHLP_SYMBOL64) + (sizeof (symName))];
285- IMAGEHLP_SYMBOL64* symbol;
286-
287- RtlCaptureContext (&context);
288- memset (&stack, 0 , sizeof (STACKFRAME64));
289- #if defined(_AMD64_)
290- stack.AddrPC .Offset = context.Rip ;
291- stack.AddrPC .Mode = AddrModeFlat;
292- stack.AddrStack .Offset = context.Rsp ;
293- stack.AddrStack .Mode = AddrModeFlat;
294- stack.AddrFrame .Offset = context.Rbp ;
295- stack.AddrFrame .Mode = AddrModeFlat;
296- #else
297- stack.AddrPC .Offset = context.Eip ;
298- stack.AddrPC .Mode = AddrModeFlat;
299- stack.AddrStack .Offset = context.Esp ;
300- stack.AddrStack .Mode = AddrModeFlat;
301- stack.AddrFrame .Offset = context.Ebp ;
302- stack.AddrFrame .Mode = AddrModeFlat;
303- #endif
304- displacement = 0 ;
305- process = GetCurrentProcess ();
306- symInit = SymInitialize (process, " plugins" , TRUE );
307- symbol = (IMAGEHLP_SYMBOL64*) storage;
308-
309- for (frame = 0 ; reportBufferRemaining > 0 ; frame++)
310- {
311- BOOL result = StackWalk (IMAGE_FILE_MACHINE_AMD64,
312- process,
313- GetCurrentThread (),
314- &stack,
315- &context,
316- NULL ,
317- SymFunctionTableAccess64,
318- SymGetModuleBase64,
319- NULL );
320-
321- if (result)
322- {
323- symbol->SizeOfStruct = sizeof (storage);
324- symbol->MaxNameLength = sizeof (symName);
325-
326- BOOL symResult = SymGetSymFromAddr64 (process, (ULONG64)stack.AddrPC .Offset , &displacement, symbol);
327- if (symResult) {
328- UnDecorateSymbolName (symbol->Name , (PSTR)symName, sizeof (symName), UNDNAME_COMPLETE);
329- }
330-
331- written = snprintf (
332- reportBufferPtr,
333- reportBufferRemaining,
334- " %02u 0x%p %s\r\n " ,
335- frame,
336- stack.AddrPC .Offset ,
337- symResult ? symbol->Name : " Unknown"
338- );
339- if (written > 0 )
340- {
341- if (written <= reportBufferRemaining)
342- {
343- reportBufferPtr += written;
344- reportBufferRemaining -= written;
345- }
346- else
347- {
348- reportBufferPtr += reportBufferRemaining;
349- reportBufferRemaining = 0 ;
350- }
351- }
352- }
353- else
354- {
355- break ;
356- }
357- }
372+ appendStackTrace (reportBufferPtr, reportBufferRemaining);
358373
359374 // Append log file
360375 if (crashLogger)
@@ -432,3 +447,22 @@ void installCrashHandler(qtwebapp::LoggerWithFile *logger)
432447 crashLogger = logger;
433448 SetUnhandledExceptionFilter (crashHandler);
434449}
450+
451+ void logWindowsStackTrace ()
452+ {
453+ const int reportBufferSize = 64 * 1024 ;
454+ char *reportBuffer = new char [reportBufferSize];
455+ char *reportBufferPtr = reportBuffer;
456+ int reportBufferRemaining = reportBufferSize;
457+
458+ int written = snprintf (reportBufferPtr, reportBufferRemaining, " Stack trace (DbgHelp):\r\n " );
459+ if (written > 0 )
460+ {
461+ reportBufferPtr += written;
462+ reportBufferRemaining -= written;
463+ }
464+
465+ appendStackTrace (reportBufferPtr, reportBufferRemaining);
466+ qCritical (" %s" , reportBuffer);
467+ delete[] reportBuffer;
468+ }
0 commit comments