Skip to content

Commit fc95347

Browse files
authored
Dynamically allocate the alternate signal stack (#10266)
In Glibc 2.34 and later, SIGSTKSZ may not be a compile-time constant. It is no longer possible to statically allocate the alternate signal stack for the main thread, as we've been doing for the last 25 years. This commit implements dynamic allocation of the alternate signal stack even for the main thread. It reuses the code already in place to allocate the alternate signal stack for other threads. Fixes: #10250.
1 parent 7a9a8dd commit fc95347

4 files changed

Lines changed: 21 additions & 13 deletions

File tree

Changes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ Working version
6969
to the debugger via a socket.
7070
(Antonin Décimo, review by Xavier Leroy)
7171

72+
- #10250, #10266: Dynamically allocate alternate signal stacks to
73+
accommodate changes in Glibc 2.34.
74+
(Xavier Leroy, reports by Tomasz Kłoczko and R.W.M. Jones, review by Anil
75+
Madhavapeddy, Stephen Dolan, and Florian Angeletti)
76+
7277
### Code generation and optimizations:
7378

7479
- #9876: do not cache the young_limit GC variable in a processor register.

runtime/caml/signals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ value caml_do_pending_actions_exn (void);
8787
value caml_process_pending_actions_with_root (value extra_root); // raises
8888
value caml_process_pending_actions_with_root_exn (value extra_root);
8989
int caml_set_signal_action(int signo, int action);
90-
CAMLextern void caml_setup_stack_overflow_detection(void);
90+
CAMLextern int caml_setup_stack_overflow_detection(void);
9191

9292
CAMLextern void (*caml_enter_blocking_section_hook)(void);
9393
CAMLextern void (*caml_leave_blocking_section_hook)(void);

runtime/signals_byt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,4 @@ int caml_set_signal_action(int signo, int action)
8181
return 0;
8282
}
8383

84-
CAMLexport void caml_setup_stack_overflow_detection(void) {}
84+
CAMLexport int caml_setup_stack_overflow_detection(void) { return 0; }

runtime/signals_nat.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,6 @@ DECLARE_SIGNAL_HANDLER(trap_handler)
174174
#error "CONTEXT_SP is required if HAS_STACK_OVERFLOW_DETECTION is defined"
175175
#endif
176176

177-
static char sig_alt_stack[SIGSTKSZ];
178-
179177
/* Code compiled with ocamlopt never accesses more than
180178
EXTRA_STACK bytes below the stack pointer. */
181179
#define EXTRA_STACK 256
@@ -269,28 +267,33 @@ void caml_init_signals(void)
269267
#endif
270268

271269
#ifdef HAS_STACK_OVERFLOW_DETECTION
272-
{
273-
stack_t stk;
270+
if (caml_setup_stack_overflow_detection() != -1) {
274271
struct sigaction act;
275-
stk.ss_sp = sig_alt_stack;
276-
stk.ss_size = SIGSTKSZ;
277-
stk.ss_flags = 0;
278272
SET_SIGACT(act, segv_handler);
279273
act.sa_flags |= SA_ONSTACK | SA_NODEFER;
280274
sigemptyset(&act.sa_mask);
281-
if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); }
275+
sigaction(SIGSEGV, &act, NULL);
282276
}
283277
#endif
284278
}
285279

286-
CAMLexport void caml_setup_stack_overflow_detection(void)
280+
/* Allocate and select an alternate stack for handling signals,
281+
especially SIGSEGV signals.
282+
Each thread needs its own alternate stack.
283+
The alternate stack used to be statically-allocated for the main thread,
284+
but this is incompatible with Glibc 2.34 and newer, where SIGSTKSZ
285+
may not be a compile-time constant (issue #10250). */
286+
287+
CAMLexport int caml_setup_stack_overflow_detection(void)
287288
{
288289
#ifdef HAS_STACK_OVERFLOW_DETECTION
289290
stack_t stk;
290291
stk.ss_sp = malloc(SIGSTKSZ);
292+
if (stk.ss_sp == NULL) return -1;
291293
stk.ss_size = SIGSTKSZ;
292294
stk.ss_flags = 0;
293-
if (stk.ss_sp)
294-
sigaltstack(&stk, NULL);
295+
return sigaltstack(&stk, NULL);
296+
#else
297+
return 0;
295298
#endif
296299
}

0 commit comments

Comments
 (0)