From 40c222593f3df403133be7340dd0fc1d7f13ca63 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 1 Jan 2015 14:25:49 -0800 Subject: [PATCH] fix #9544. call jl_throw directly in JL_SIGATOMIC_END rather than indirectly through raise --- src/debuginfo.cpp | 4 +-- src/init.c | 78 ++++++++++++++++++++++++++++++++++++++--------- src/julia.h | 6 ++-- test/core.jl | 3 ++ 4 files changed, 73 insertions(+), 18 deletions(-) diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index d3be4972df775..1efa5ec69f7f8 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -213,8 +213,8 @@ class JuliaJITEventListener: public JITEventListener StringRef sName; #endif #ifdef _OS_WINDOWS_ - uint64_t SectionAddr; - uint64_t SectionSize; + uint64_t SectionAddr = 0; + uint64_t SectionSize = 0; uint64_t SectionAddrCheck = 0; // assert that all of the Sections are at the same location #endif diff --git a/src/init.c b/src/init.c index 47e1dc9f95330..28e960bf98d88 100644 --- a/src/init.c +++ b/src/init.c @@ -126,21 +126,55 @@ static void jl_find_stack_bottom(void) } #ifdef _OS_WINDOWS_ -void __cdecl fpe_handler(int arg, int num) +static char *strsignal(int sig) { - (void)arg; - fpreset(); - signal(SIGFPE, (void (__cdecl *)(int))fpe_handler); - switch(num) { - case _FPE_INVALID: - case _FPE_OVERFLOW: - case _FPE_UNDERFLOW: - default: - jl_errorf("Unexpected FPE Error 0x%X", num); + switch (sig) { + case SIGINT: return "SIGINT"; break; + case SIGILL: return "SIGILL"; break; + case SIGABRT_COMPAT: return "SIGABRT_COMPAT"; break; + case SIGFPE: return "SIGFPE"; break; + case SIGSEGV: return "SIGSEGV"; break; + case SIGTERM: return "SIGTERM"; break; + case SIGBREAK: return "SIGBREAK"; break; + case SIGABRT: return "SIGABRT"; break; + } + return "?"; +} + +void __cdecl crt_sig_handler(int sig, int num) +{ + switch (sig) { + case SIGFPE: + fpreset(); + signal(SIGFPE, (void (__cdecl *)(int))crt_sig_handler); + switch(num) { + case _FPE_INVALID: + case _FPE_OVERFLOW: + case _FPE_UNDERFLOW: + default: + jl_errorf("Unexpected FPE Error 0x%X", num); + break; + case _FPE_ZERODIVIDE: + jl_throw(jl_diverror_exception); + break; + } break; - case _FPE_ZERODIVIDE: - jl_throw(jl_diverror_exception); + case SIGINT: + signal(SIGINT, (void (__cdecl *)(int))crt_sig_handler); + if (exit_on_sigint) jl_exit(0); + if (jl_defer_signal) { + jl_signal_pending = sig; + } + else { + jl_signal_pending = 0; + jl_throw(jl_interrupt_exception); + } break; + default: // SIGSEGV, (SSIGTERM, IGILL) + ios_printf(ios_stderr,"\nsignal (%d): %s\n", sig, strsignal(sig)); + bt_size = rec_backtrace(bt_data, MAX_BT_SIZE); + jlbacktrace(); + raise(sig); } } #else @@ -260,7 +294,7 @@ static BOOL WINAPI sigint_handler(DWORD wsig) //This needs winapi types to guara { if (exit_on_sigint) jl_exit(0); int sig; - //windows signals use different numbers from unix + //windows signals use different numbers from unix (raise) switch(wsig) { case CTRL_C_EVENT: sig = SIGINT; break; //case CTRL_BREAK_EVENT: sig = SIGTERM; break; @@ -1114,10 +1148,26 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_exit(1); } #else // defined(_OS_WINDOWS_) - if (signal(SIGFPE, (void (__cdecl *)(int))fpe_handler) == SIG_ERR) { + if (signal(SIGFPE, (void (__cdecl *)(int))crt_sig_handler) == SIG_ERR) { JL_PRINTF(JL_STDERR, "fatal error: Couldn't set SIGFPE\n"); jl_exit(1); } + if (signal(SIGILL, (void (__cdecl *)(int))crt_sig_handler) == SIG_ERR) { + JL_PRINTF(JL_STDERR, "fatal error: Couldn't set SIGILL\n"); + jl_exit(1); + } + if (signal(SIGINT, (void (__cdecl *)(int))crt_sig_handler) == SIG_ERR) { + JL_PRINTF(JL_STDERR, "fatal error: Couldn't set SIGINT\n"); + jl_exit(1); + } + if (signal(SIGSEGV, (void (__cdecl *)(int))crt_sig_handler) == SIG_ERR) { + JL_PRINTF(JL_STDERR, "fatal error: Couldn't set SIGSEGV\n"); + jl_exit(1); + } + if (signal(SIGTERM, (void (__cdecl *)(int))crt_sig_handler) == SIG_ERR) { + JL_PRINTF(JL_STDERR, "fatal error: Couldn't set SIGTERM\n"); + jl_exit(1); + } SetUnhandledExceptionFilter(exception_handler); #endif diff --git a/src/julia.h b/src/julia.h index 37e1ddf4e4ca9..011f4b5415018 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1107,8 +1107,10 @@ DLLEXPORT extern volatile sig_atomic_t jl_defer_signal; #define JL_SIGATOMIC_END() \ do { \ jl_defer_signal--; \ - if (jl_defer_signal == 0 && jl_signal_pending != 0) \ - raise(jl_signal_pending); \ + if (jl_defer_signal == 0 && jl_signal_pending != 0) { \ + jl_signal_pending = 0; \ + jl_throw(jl_interrupt_exception); \ + } \ } while(0) DLLEXPORT void restore_signals(void); diff --git a/test/core.jl b/test/core.jl index 21d805f929e7b..202e3973af0be 100644 --- a/test/core.jl +++ b/test/core.jl @@ -2020,3 +2020,6 @@ let x = [1,2,3] @test ccall(:jl_new_bits, Any, (Any,Ptr{Void},), (Int,Int,Int), x) === (1,2,3) @test (ccall(:jl_new_bits, Any, (Any,Ptr{Void},), (Int16,(Void,),Int8,(),Int,Void,Int), x)::Tuple)[[2,4,5,6,7]] === ((nothing,),(),2,nothing,3) end + +# sig 2 is SIGINT per the POSIX.1-1990 standard +@test_throws InterruptException ccall(:raise, Void, (Cint,), 2)