@@ -77,13 +77,27 @@ void __cdecl crt_sig_handler(int sig, int num)
7777 }
7878}
7979
80- BOOL (* pSetThreadStackGuarantee )(PULONG );
80+ static JL_THREAD LPVOID collect_backtrace_fiber ;
81+ static JL_THREAD PCONTEXT error_ctx ;
82+ static VOID NOINLINE NORETURN CALLBACK start_backtrace_fiber (PVOID lpParameter )
83+ {
84+ while (1 ) {
85+ // collect the backtrace
86+ bt_size = rec_backtrace_ctx (bt_data , MAX_BT_SIZE , error_ctx );
87+ // switch back to the execution fiber
88+ SwitchToFiber (jl_current_task -> fiber );
89+ }
90+ }
91+
92+ static LONG WINAPI exception_handler (struct _EXCEPTION_POINTERS * ExceptionInfo );
8193void restore_signals (void )
8294{
95+ SetUnhandledExceptionFilter (exception_handler );
8396 SetConsoleCtrlHandler (NULL , 0 ); //turn on ctrl-c handler
97+ collect_backtrace_fiber = CreateFiberEx (sig_stack_size , sig_stack_size , FIBER_FLAG_FLOAT_SWITCH , start_backtrace_fiber , NULL );
8498}
8599
86- void jl_throw_in_ctx (jl_value_t * excpt , CONTEXT * ctxThread , int bt )
100+ void jl_throw_in_ctx (jl_value_t * excpt , PCONTEXT ctxThread )
87101{
88102 assert (excpt != NULL );
89103#if defined(_CPU_X86_64_ )
@@ -93,7 +107,13 @@ void jl_throw_in_ctx(jl_value_t *excpt, CONTEXT *ctxThread, int bt)
93107#else
94108#error WIN16 not supported :P
95109#endif
96- bt_size = bt ? rec_backtrace_ctx (bt_data , MAX_BT_SIZE , ctxThread ) : 0 ;
110+ if (excpt != jl_stackovf_exception ) {
111+ bt_size = rec_backtrace_ctx (bt_data , MAX_BT_SIZE , ctxThread );
112+ }
113+ else {
114+ error_ctx = ctxThread ;
115+ SwitchToFiber (collect_backtrace_fiber );
116+ }
97117 jl_exception_in_transit = excpt ;
98118#if defined(_CPU_X86_64_ )
99119 * (DWORD64 * )Rsp = 0 ;
@@ -137,7 +157,7 @@ static BOOL WINAPI sigint_handler(DWORD wsig) //This needs winapi types to guara
137157 jl_safe_printf ("error: GetThreadContext failed\n" );
138158 return 0 ;
139159 }
140- jl_throw_in_ctx (jl_interrupt_exception , & ctxThread , 1 );
160+ jl_throw_in_ctx (jl_interrupt_exception , & ctxThread );
141161 ctxThread .ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER ;
142162 if (!SetThreadContext (hMainThread ,& ctxThread )) {
143163 jl_safe_printf ("error: SetThreadContext failed\n" );
@@ -153,20 +173,20 @@ static BOOL WINAPI sigint_handler(DWORD wsig) //This needs winapi types to guara
153173 return 1 ;
154174}
155175
156- static LONG WINAPI _exception_handler (struct _EXCEPTION_POINTERS * ExceptionInfo , int in_ctx )
176+ static LONG WINAPI _exception_handler (struct _EXCEPTION_POINTERS * ExceptionInfo )
157177{
158178 if (ExceptionInfo -> ExceptionRecord -> ExceptionFlags == 0 ) {
159179 switch (ExceptionInfo -> ExceptionRecord -> ExceptionCode ) {
160180 case EXCEPTION_INT_DIVIDE_BY_ZERO :
161181 fpreset ();
162- jl_throw_in_ctx (jl_diverror_exception , ExceptionInfo -> ContextRecord , in_ctx );
182+ jl_throw_in_ctx (jl_diverror_exception , ExceptionInfo -> ContextRecord );
163183 return EXCEPTION_CONTINUE_EXECUTION ;
164184 case EXCEPTION_STACK_OVERFLOW :
165- jl_throw_in_ctx (jl_stackovf_exception , ExceptionInfo -> ContextRecord , in_ctx && pSetThreadStackGuarantee );
185+ jl_throw_in_ctx (jl_stackovf_exception , ExceptionInfo -> ContextRecord );
166186 return EXCEPTION_CONTINUE_EXECUTION ;
167187 case EXCEPTION_ACCESS_VIOLATION :
168188 if (ExceptionInfo -> ExceptionRecord -> ExceptionInformation [0 ] == 1 ) { // writing to read-only memory (e.g. mmap)
169- jl_throw_in_ctx (jl_readonlymemory_exception , ExceptionInfo -> ContextRecord , in_ctx );
189+ jl_throw_in_ctx (jl_readonlymemory_exception , ExceptionInfo -> ContextRecord );
170190 return EXCEPTION_CONTINUE_EXECUTION ;
171191 }
172192 }
@@ -230,7 +250,7 @@ static LONG WINAPI _exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo,
230250
231251static LONG WINAPI exception_handler (struct _EXCEPTION_POINTERS * ExceptionInfo )
232252{
233- return _exception_handler (ExceptionInfo , 1 );
253+ return _exception_handler (ExceptionInfo );
234254}
235255
236256#if defined(_CPU_X86_64_ )
@@ -241,7 +261,7 @@ EXCEPTION_DISPOSITION _seh_exception_handler(PEXCEPTION_RECORD ExceptionRecord,
241261 ExceptionInfo .ContextRecord = ContextRecord ;
242262
243263 EXCEPTION_DISPOSITION rval ;
244- switch (_exception_handler (& ExceptionInfo , 1 )) {
264+ switch (_exception_handler (& ExceptionInfo )) {
245265 case EXCEPTION_CONTINUE_EXECUTION :
246266 rval = ExceptionContinueExecution ; break ;
247267 case EXCEPTION_CONTINUE_SEARCH :
@@ -334,10 +354,6 @@ DLLEXPORT void jl_profile_stop_timer(void)
334354
335355void jl_install_default_signal_handlers (void )
336356{
337- ULONG StackSizeInBytes = sig_stack_size ;
338- pSetThreadStackGuarantee = (BOOL (* )(PULONG )) jl_dlsym_e (jl_kernel32_handle , "SetThreadStackGuarantee" );
339- if (!pSetThreadStackGuarantee || !pSetThreadStackGuarantee (& StackSizeInBytes ))
340- pSetThreadStackGuarantee = NULL ;
341357 if (signal (SIGFPE , (void (__cdecl * )(int ))crt_sig_handler ) == SIG_ERR ) {
342358 jl_error ("fatal error: Couldn't set SIGFPE" );
343359 }
@@ -353,5 +369,4 @@ void jl_install_default_signal_handlers(void)
353369 if (signal (SIGTERM , (void (__cdecl * )(int ))crt_sig_handler ) == SIG_ERR ) {
354370 jl_error ("fatal error: Couldn't set SIGTERM" );
355371 }
356- SetUnhandledExceptionFilter (exception_handler );
357372}
0 commit comments