]>
Commit | Line | Data |
---|---|---|
c9597d78 JB |
1 | From 632563b19ca72ec0ae10c7ed767a025c342d3155 Mon Sep 17 00:00:00 2001 |
2 | From: Xavier Leroy <xavier.leroy@college-de-france.fr> | |
3 | Date: Tue, 2 Mar 2021 19:06:56 +0100 | |
4 | Subject: [PATCH 1/3] Dynamically allocate the alternate signal stack | |
5 | ||
6 | In Glibc 2.34 and later, SIGSTKSZ may not be a compile-time constant. | |
7 | It is no longer possible to statically allocate the alternate signal | |
8 | stack for the main thread, as we've been doing for the last 25 years. | |
9 | ||
10 | This commit implements dynamic allocation of the alternate signal stack | |
11 | even for the main thread. It reuses the code already in place to allocate | |
12 | the alternate signal stack for other threads. | |
13 | ||
14 | Fixes: #10250. | |
15 | --- | |
16 | runtime/caml/signals.h | 2 +- | |
17 | runtime/signals_byt.c | 2 +- | |
18 | runtime/signals_nat.c | 25 ++++++++++++++----------- | |
19 | 3 files changed, 16 insertions(+), 13 deletions(-) | |
20 | ||
0c7e9815 JR |
21 | diff -urNp -x '*.orig' ocaml-4.12.0.org/Changes ocaml-4.12.0/Changes |
22 | --- ocaml-4.12.0.org/Changes 2021-02-24 14:49:29.000000000 +0100 | |
23 | +++ ocaml-4.12.0/Changes 2021-11-21 10:33:11.184661387 +0100 | |
24 | @@ -276,6 +276,11 @@ OCaml 4.12.0 (24 February 2021) | |
25 | - #10062: set ARCH_INT64_PRINTF_FORMAT correctly for both modes of mingw-w64 | |
26 | (David Allsopp, review by Xavier Leroy) | |
27 | ||
28 | +- #10250, #10266: Dynamically allocate alternate signal stacks to | |
29 | + accommodate changes in Glibc 2.34. | |
30 | + (Xavier Leroy, reports by Tomasz Kłoczko and R.W.M. Jones, review by Anil | |
31 | + Madhavapeddy, Stephen Dolan, and Florian Angeletti) | |
32 | + | |
33 | ### Code generation and optimizations: | |
34 | ||
35 | - #9551: ocamlc no longer loads DLLs at link time to check that | |
36 | diff -urNp -x '*.orig' ocaml-4.12.0.org/runtime/caml/signals.h ocaml-4.12.0/runtime/caml/signals.h | |
37 | --- ocaml-4.12.0.org/runtime/caml/signals.h 2021-02-24 14:49:29.000000000 +0100 | |
38 | +++ ocaml-4.12.0/runtime/caml/signals.h 2021-11-21 10:33:11.184661387 +0100 | |
39 | @@ -87,7 +87,7 @@ value caml_do_pending_actions_exn (void) | |
c9597d78 JB |
40 | value caml_process_pending_actions_with_root (value extra_root); // raises |
41 | value caml_process_pending_actions_with_root_exn (value extra_root); | |
42 | int caml_set_signal_action(int signo, int action); | |
43 | -CAMLextern void caml_setup_stack_overflow_detection(void); | |
44 | +CAMLextern int caml_setup_stack_overflow_detection(void); | |
45 | ||
46 | CAMLextern void (*caml_enter_blocking_section_hook)(void); | |
47 | CAMLextern void (*caml_leave_blocking_section_hook)(void); | |
0c7e9815 JR |
48 | diff -urNp -x '*.orig' ocaml-4.12.0.org/runtime/signals_byt.c ocaml-4.12.0/runtime/signals_byt.c |
49 | --- ocaml-4.12.0.org/runtime/signals_byt.c 2021-02-24 14:49:29.000000000 +0100 | |
50 | +++ ocaml-4.12.0/runtime/signals_byt.c 2021-11-21 10:33:11.184661387 +0100 | |
51 | @@ -81,4 +81,4 @@ int caml_set_signal_action(int signo, in | |
c9597d78 JB |
52 | return 0; |
53 | } | |
54 | ||
55 | -CAMLexport void caml_setup_stack_overflow_detection(void) {} | |
56 | +CAMLexport int caml_setup_stack_overflow_detection(void) { return 0; } | |
0c7e9815 JR |
57 | diff -urNp -x '*.orig' ocaml-4.12.0.org/runtime/signals_nat.c ocaml-4.12.0/runtime/signals_nat.c |
58 | --- ocaml-4.12.0.org/runtime/signals_nat.c 2021-02-24 14:49:29.000000000 +0100 | |
59 | +++ ocaml-4.12.0/runtime/signals_nat.c 2021-11-21 10:33:11.184661387 +0100 | |
60 | @@ -181,8 +181,6 @@ DECLARE_SIGNAL_HANDLER(trap_handler) | |
c9597d78 JB |
61 | #error "CONTEXT_SP is required if HAS_STACK_OVERFLOW_DETECTION is defined" |
62 | #endif | |
63 | ||
64 | -static char sig_alt_stack[SIGSTKSZ]; | |
65 | - | |
66 | /* Code compiled with ocamlopt never accesses more than | |
67 | EXTRA_STACK bytes below the stack pointer. */ | |
68 | #define EXTRA_STACK 256 | |
0c7e9815 | 69 | @@ -276,28 +274,33 @@ void caml_init_signals(void) |
c9597d78 JB |
70 | #endif |
71 | ||
72 | #ifdef HAS_STACK_OVERFLOW_DETECTION | |
73 | - { | |
74 | - stack_t stk; | |
75 | + if (caml_setup_stack_overflow_detection() != -1) { | |
76 | struct sigaction act; | |
77 | - stk.ss_sp = sig_alt_stack; | |
78 | - stk.ss_size = SIGSTKSZ; | |
79 | - stk.ss_flags = 0; | |
80 | SET_SIGACT(act, segv_handler); | |
81 | act.sa_flags |= SA_ONSTACK | SA_NODEFER; | |
82 | sigemptyset(&act.sa_mask); | |
83 | - if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); } | |
84 | + sigaction(SIGSEGV, &act, NULL); | |
85 | } | |
86 | #endif | |
87 | } | |
88 | ||
89 | -CAMLexport void caml_setup_stack_overflow_detection(void) | |
90 | +/* Allocate and select an alternate stack for handling signals, | |
91 | + especially SIGSEGV signals. | |
92 | + Each thread needs its own alternate stack. | |
93 | + The alternate stack used to be statically-allocated for the main thread, | |
0c7e9815 | 94 | + but this is incompatible with Glibc 2.34 and newer, where SIGSTKSZ |
c9597d78 JB |
95 | + may not be a compile-time constant (issue #10250). */ |
96 | + | |
97 | +CAMLexport int caml_setup_stack_overflow_detection(void) | |
98 | { | |
99 | #ifdef HAS_STACK_OVERFLOW_DETECTION | |
100 | stack_t stk; | |
101 | stk.ss_sp = malloc(SIGSTKSZ); | |
102 | + if (stk.ss_sp == NULL) return -1; | |
103 | stk.ss_size = SIGSTKSZ; | |
104 | stk.ss_flags = 0; | |
105 | - if (stk.ss_sp) | |
106 | - sigaltstack(&stk, NULL); | |
107 | + return sigaltstack(&stk, NULL); | |
108 | +#else | |
109 | + return 0; | |
110 | #endif | |
111 | } |