Skip to content

Commit 8ff89cf

Browse files
committed
Don't show native stacktrace when root thread is terminated
1 parent 7ad8171 commit 8ff89cf

File tree

3 files changed

+20
-51
lines changed

3 files changed

+20
-51
lines changed

src/main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ static LONG WINAPI show_stack_trace(EXCEPTION_POINTERS *ep)
366366
EXCEPTION_RECORD *er = ep->ExceptionRecord;
367367
void *exceptionAddress = er? er->ExceptionAddress: NULL;
368368
int exceptionCode = er? er->ExceptionCode: 0;
369+
if (exceptionCode == SG_THREAD_TERMINAT_CODE) {
370+
/* terminating root thread..., don't bother */
371+
return EXCEPTION_EXECUTE_HANDLER;
372+
}
369373
__try {
370374
EnterCriticalSection(&lock);
371375
fprintf(stderr, "Native error occurred at %p (%x)\n",
@@ -397,6 +401,10 @@ static LONG show_stack_trace_handler(PEXCEPTION_POINTERS ep)
397401
{
398402
void *exceptionAddress = ep->ExceptionRecord->ExceptionAddress;
399403
int exceptionCode = ep->ExceptionRecord->ExceptionCode;
404+
if (exceptionCode == SG_THREAD_TERMINAT_CODE) {
405+
/* terminating root thread..., don't bother */
406+
return EXCEPTION_EXECUTE_HANDLER;
407+
}
400408
fprintf(stderr, "\nNative error occurred at %p (%x)\n",
401409
exceptionAddress, exceptionCode);
402410
fflush(stderr); /* not needed but for my mental health */

src/os/win/thread.c

Lines changed: 6 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -42,52 +42,7 @@
4242
#include "../../gc-incl.inc"
4343
#include "win_util.c"
4444

45-
/* From winerror.h */
46-
//
47-
// Note: There is a slightly modified layout for HRESULT values below,
48-
// after the heading "COM Error Codes".
49-
//
50-
// Search for "**** Available SYSTEM error codes ****" to find where to
51-
// insert new error codes
52-
//
53-
// Values are 32 bit values laid out as follows:
54-
//
55-
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
56-
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
57-
// +---+-+-+-----------------------+-------------------------------+
58-
// |Sev|C|R| Facility | Code |
59-
// +---+-+-+-----------------------+-------------------------------+
60-
//
61-
// where
62-
//
63-
// Sev - is the severity code
64-
//
65-
// 00 - Success
66-
// 01 - Informational
67-
// 10 - Warning
68-
// 11 - Error
69-
//
70-
// C - is the Customer code flag
71-
//
72-
// R - is a reserved bit
73-
//
74-
// Facility - is the facility code
75-
//
76-
// Code - is the facility's status code
77-
//
78-
//
79-
// Define the facility codes
80-
//
81-
#define MAKE_HRESULT_CODE(sev, fac, code) \
82-
((DWORD)( ((sev) << 30) | /* sev code */ \
83-
(1 << 29) | /* 1 = customer */ \
84-
(0 << 28) | /* R */ \
85-
((fac) << 16) | /* facility */ \
86-
((code) << 0 ) /* code */ \
87-
))
88-
#define SEV_ERROR 0x03
89-
#define TERMINATION_CODE MAKE_HRESULT_CODE(SEV_ERROR, 0xBAD, 0xDEAD)
90-
#define SIZEOF_EXCEPTION_INFO 2
45+
#define EXCEPTION_INFO_N SG_TERMINATION_INFO_N
9146
#define EXCEPTION_CANCEL 0
9247
#define EXCEPTION_EXIT 1
9348

@@ -123,9 +78,9 @@ void Sg_DestroyMutex(SgInternalMutex *mutex)
12378
static DWORD exception_filter(EXCEPTION_POINTERS *ep, ULONG_PTR *ei)
12479
{
12580
switch (ep->ExceptionRecord->ExceptionCode) {
126-
case TERMINATION_CODE: {
81+
case SG_THREAD_TERMINAT_CODE: {
12782
DWORD i;
128-
DWORD n = min(ep->ExceptionRecord->NumberParameters, SIZEOF_EXCEPTION_INFO);
83+
DWORD n = min(ep->ExceptionRecord->NumberParameters, EXCEPTION_INFO_N);
12984
for (i = 0; i < n; i++) {
13085
ei[i] = ep->ExceptionRecord->ExceptionInformation[i];
13186
}
@@ -163,7 +118,7 @@ static unsigned int __stdcall win32_thread_entry(void *params)
163118
{
164119
unsigned int status;
165120
SgInternalThread *me = ((ThreadParams *)params)->me;
166-
ULONG_PTR ei[SIZEOF_EXCEPTION_INFO];
121+
ULONG_PTR ei[EXCEPTION_INFO_N];
167122
__try {
168123
status = win32_thread_entry_inner(params);
169124
} __except(exception_filter(GetExceptionInformation(), ei)) {
@@ -368,11 +323,11 @@ int Sg_WaitWithTimeout(SgInternalCond *cond, SgInternalMutex *mutex,
368323

369324
static void throw_exception(int code, int status)
370325
{
371-
ULONG_PTR exceptionInfo[SIZEOF_EXCEPTION_INFO];
326+
ULONG_PTR exceptionInfo[EXCEPTION_INFO_N];
372327
exceptionInfo[0] = code;
373328
exceptionInfo[1] = status;
374329

375-
RaiseException(TERMINATION_CODE, 0, SIZEOF_EXCEPTION_INFO, exceptionInfo);
330+
RaiseException(SG_THREAD_TERMINAT_CODE, 0, EXCEPTION_INFO_N, exceptionInfo);
376331
}
377332

378333
void Sg_ExitThread(SgInternalThread *thread, void *ret)

src/sagittarius/private/thread.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ typedef struct SgInternalSemaphoreRec
141141
#define SG_INTERNAL_COND_TIMEDOUT 1
142142
#define SG_INTERNAL_COND_INTR 2
143143

144+
/* https://learn.microsoft.com/en-us/cpp/cpp/raising-software-exceptions
145+
Exception code structure.
146+
winerror.h contains a bit more detail */
147+
#define SG_THREAD_TERMINAT_CODE 0xEBADDEAD
148+
#define SG_TERMINATION_INFO_N 2
149+
144150
/* dummies */
145151
#define SG_INTERRUPTED_THREAD() if (TRUE)
146152
#define SG_INTERRUPTED_THREAD_ELSE() else

0 commit comments

Comments
 (0)