Skip to content

Commit 2a85dfd

Browse files
committed
mach-spawn: fix spurious InterruptException
this was a bug in our libuv fork triggering a bug in the mach kernel code must be careful to never use sigprocmask, setjmp, longjmp, or similar such thread-unsafe functions to avoid this documented unspecified behavior
1 parent ca3b06e commit 2a85dfd

File tree

13 files changed

+49
-17
lines changed

13 files changed

+49
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0e6ec181c8bfd322a17dbd843b2b8ebb
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
4bf9c8b16617691b70ea43c667ecc575d2a06b3d0c347b949d10360c012138585a13ecea5e18de81b1585a96cf7734b7cc3d6072490898f1d5531c702cf5afab

deps/checksums/libuv-8d5131b6c1595920dd30644cd1435b4f344b46c8.tar.gz/md5

-1
This file was deleted.

deps/checksums/libuv-8d5131b6c1595920dd30644cd1435b4f344b46c8.tar.gz/sha512

-1
This file was deleted.

deps/libuv.version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
LIBUV_BRANCH=julia-uv1.9.0
2-
LIBUV_SHA1=8d5131b6c1595920dd30644cd1435b4f344b46c8
2+
LIBUV_SHA1=52d72a52cc7ccd570929990f010ed16e2ec604c8

src/flisp/builtins.c

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <stdlib.h>
66
#include <stdio.h>
77
#include <string.h>
8-
#include <setjmp.h>
98
#include <stdarg.h>
109
#include <assert.h>
1110
#include <ctype.h>

src/flisp/flisp.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
#include <stdlib.h>
3333
#include <stdio.h>
3434
#include <string.h>
35-
#include <setjmp.h>
3635
#include <stdint.h>
3736
#include <stdarg.h>
3837
#include <assert.h>
@@ -117,7 +116,7 @@ static void free_readstate(fl_readstate_t *rs)
117116
fl_exception_context_t _ctx; int l__tr, l__ca; \
118117
_ctx.sp=fl_ctx->SP; _ctx.frame=fl_ctx->curr_frame; _ctx.rdst=fl_ctx->readstate; _ctx.prev=fl_ctx->exc_ctx; \
119118
_ctx.ngchnd = fl_ctx->N_GCHND; fl_ctx->exc_ctx = &_ctx; \
120-
if (!setjmp(_ctx.buf)) \
119+
if (!fl_setjmp(_ctx.buf)) \
121120
for (l__tr=1; l__tr; l__tr=0, (void)(fl_ctx->exc_ctx=fl_ctx->exc_ctx->prev))
122121

123122
#define FL_CATCH(fl_ctx) \
@@ -156,7 +155,7 @@ void fl_raise(fl_context_t *fl_ctx, value_t e)
156155
fl_exception_context_t *thisctx = fl_ctx->exc_ctx;
157156
if (fl_ctx->exc_ctx->prev) // don't throw past toplevel
158157
fl_ctx->exc_ctx = fl_ctx->exc_ctx->prev;
159-
longjmp(thisctx->buf, 1);
158+
fl_longjmp(thisctx->buf, 1);
160159
}
161160

162161
static value_t make_error_msg(fl_context_t *fl_ctx, const char *format, va_list args)

src/flisp/flisp.h

+19-2
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,25 @@ fixnum_t tofixnum(fl_context_t *fl_ctx, value_t v, const char *fname);
167167
char *tostring(fl_context_t *fl_ctx, value_t v, const char *fname);
168168

169169
/* error handling */
170+
#if defined(_OS_WINDOWS_)
171+
#define fl_jmp_buf jmp_buf
172+
#if defined(_COMPILER_MINGW_)
173+
int __attribute__ ((__nothrow__,__returns_twice__)) (jl_setjmp)(jmp_buf _Buf);
174+
__declspec(noreturn) __attribute__ ((__nothrow__)) void (jl_longjmp)(jmp_buf _Buf, int _Value);
175+
#else
176+
int (jl_setjmp)(jmp_buf _Buf);
177+
void (jl_longjmp)(jmp_buf _Buf, int _Value);
178+
#endif
179+
#define fl_setjmp(a) (jl_setjmp)((a))
180+
#define fl_longjmp(a, b) (jl_longjmp)((a), (b))
181+
#else // !_OS_WINDOWS_
182+
#define fl_jmp_buf sigjmp_buf
183+
#define fl_setjmp(a) sigsetjmp((a), 0)
184+
#define fl_longjmp(a, b) siglongjmp((a), (b))
185+
#endif
186+
170187
typedef struct _ectx_t {
171-
jmp_buf buf;
188+
fl_jmp_buf buf;
172189
uint32_t sp;
173190
uint32_t frame;
174191
uint32_t ngchnd;
@@ -179,7 +196,7 @@ typedef struct _ectx_t {
179196
#define FL_TRY_EXTERN(fl_ctx) \
180197
fl_exception_context_t _ctx; int l__tr, l__ca; \
181198
fl_savestate(fl_ctx, &_ctx); fl_ctx->exc_ctx = &_ctx; \
182-
if (!setjmp(_ctx.buf)) \
199+
if (!fl_setjmp(_ctx.buf)) \
183200
for (l__tr=1; l__tr; l__tr=0, (void)(fl_ctx->exc_ctx=fl_ctx->exc_ctx->prev))
184201

185202
#define FL_CATCH_EXTERN(fl_ctx) \

src/flisp/iostream.c

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include <string.h>
55
#include <assert.h>
66
#include <sys/types.h>
7-
#include <setjmp.h>
87
#include "flisp.h"
98

109
#ifdef __cplusplus

src/flisp/string.c

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include <stdlib.h>
55
#include <stdio.h>
66
#include <string.h>
7-
#include <setjmp.h>
87
#include <stdarg.h>
98
#include <assert.h>
109
#include <ctype.h>

src/flisp/table.c

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include <string.h>
55
#include <assert.h>
66
#include <sys/types.h>
7-
#include <setjmp.h>
87
#include "flisp.h"
98
#include "equalhash.h"
109

src/julia.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -1562,11 +1562,11 @@ JL_DLLEXPORT void jl_pop_handler(int n);
15621562

15631563
#if defined(_OS_WINDOWS_)
15641564
#if defined(_COMPILER_MINGW_)
1565-
int __attribute__ ((__nothrow__,__returns_twice__)) jl_setjmp(jmp_buf _Buf);
1566-
__declspec(noreturn) __attribute__ ((__nothrow__)) void jl_longjmp(jmp_buf _Buf,int _Value);
1565+
int __attribute__ ((__nothrow__,__returns_twice__)) (jl_setjmp)(jmp_buf _Buf);
1566+
__declspec(noreturn) __attribute__ ((__nothrow__)) void (jl_longjmp)(jmp_buf _Buf, int _Value);
15671567
#else
1568-
int jl_setjmp(jmp_buf _Buf);
1569-
void jl_longjmp(jmp_buf _Buf,int _Value);
1568+
int (jl_setjmp)(jmp_buf _Buf);
1569+
void (jl_longjmp)(jmp_buf _Buf, int _Value);
15701570
#endif
15711571
#define jl_setjmp_f jl_setjmp
15721572
#define jl_setjmp_name "jl_setjmp"

src/signals-unix.c

+21-1
Original file line numberDiff line numberDiff line change
@@ -527,10 +527,30 @@ static void *signal_listener(void *arg)
527527
unw_context_t *signal_context;
528528
int sig, critical, profile;
529529
int i;
530+
// prevent this thread from being used to run other,
531+
// potentially blocking signal handlers
532+
sigfillset(&sset);
533+
sigdelset(&sset, SIGSEGV);
534+
sigdelset(&sset, SIGILL);
535+
sigdelset(&sset, SIGKILL);
536+
sigdelset(&sset, SIGBUS);
537+
sigdelset(&sset, SIGABRT);
538+
sigdelset(&sset, SIGSYS);
539+
pthread_sigmask(SIG_SETMASK, &sset, 0);
540+
530541
jl_sigsetset(&sset);
531542
while (1) {
532543
profile = 0;
533-
sigwait(&sset, &sig);
544+
sig = 0;
545+
errno = 0;
546+
if (sigwait(&sset, &sig)) {
547+
sig = SIGABRT; // this branch can't occur, unless we had stack memory corruption of sset
548+
}
549+
if (!sig) {
550+
// this should never happen, but it has been observed to occur on some buggy kernels (mach)
551+
// when sigprocmask is incorrectly used on some other thread, instead of pthread_sigmask
552+
continue;
553+
}
534554
#ifndef HAVE_MACH
535555
# ifdef HAVE_ITIMER
536556
profile = (sig == SIGPROF);

0 commit comments

Comments
 (0)