Skip to content

Commit

Permalink
Merge pull request #643 from psafont/new408
Browse files Browse the repository at this point in the history
  • Loading branch information
psafont committed Jun 5, 2023
2 parents 55a7ee5 + e648eb7 commit d1337c4
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 6 deletions.
189 changes: 189 additions & 0 deletions packages/ocaml/ocaml-base-compiler.4.08.1/files/alt-signal-stack.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
From 17df117b4939486d3285031900587afce5262c8c Mon Sep 17 00:00:00 2001
From: Xavier Leroy <xavierleroy@users.noreply.github.com>
Date: Fri, 5 Mar 2021 19:14:07 +0100
Subject: [PATCH] Dynamically allocate the alternate signal stack

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.

The alternate signal stack is freed when the main OCaml code / an OCaml thread
stops.

(partial back-port of PR#10266 and PR#10726)
---
runtime/fail_nat.c | 7 ++++-
runtime/signals_nat.c | 64 +++++++++++++++++++++++++++++++++++++------
runtime/startup_nat.c | 7 ++++-
runtime/sys.c | 5 ++++
4 files changed, 72 insertions(+), 11 deletions(-)

diff --git a/runtime/fail_nat.c b/runtime/fail_nat.c
index ec5bfebc961e..c372bc14f8ee 100644
--- a/runtime/fail_nat.c
+++ b/runtime/fail_nat.c
@@ -31,6 +31,8 @@
#include "caml/roots.h"
#include "caml/callback.h"

+extern void caml_terminate_signals(void);
+
/* The globals holding predefined exceptions */

typedef value caml_generated_constant[1];
@@ -60,7 +62,10 @@ char * caml_exception_pointer = NULL;
void caml_raise(value v)
{
Unlock_exn();
- if (caml_exception_pointer == NULL) caml_fatal_uncaught_exception(v);
+ if (caml_exception_pointer == NULL) {
+ caml_terminate_signals();
+ caml_fatal_uncaught_exception(v);
+ }

while (caml_local_roots != NULL &&
(char *) caml_local_roots < caml_exception_pointer) {
diff --git a/runtime/signals_nat.c b/runtime/signals_nat.c
index 29a5f49e6251..351b575a08e5 100644
--- a/runtime/signals_nat.c
+++ b/runtime/signals_nat.c
@@ -182,7 +182,6 @@ DECLARE_SIGNAL_HANDLER(trap_handler)
#ifdef HAS_STACK_OVERFLOW_DETECTION

static char * system_stack_top;
-static char sig_alt_stack[SIGSTKSZ];

#if defined(SYS_linux)
/* PR#4746: recent Linux kernels with support for stack randomization
@@ -275,14 +274,61 @@ void caml_init_signals(void)
{
stack_t stk;
struct sigaction act;
- stk.ss_sp = sig_alt_stack;
- stk.ss_size = SIGSTKSZ;
- stk.ss_flags = 0;
- SET_SIGACT(act, segv_handler);
- act.sa_flags |= SA_ONSTACK | SA_NODEFER;
- sigemptyset(&act.sa_mask);
- system_stack_top = (char *) &act;
- if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); }
+ /* Allocate and select an alternate stack for handling signals,
+ especially SIGSEGV signals.
+ The alternate stack used to be statically-allocated for the main thread,
+ but this is incompatible with Glibc 2.34 and newer, where SIGSTKSZ
+ may not be a compile-time constant. */
+ stk.ss_sp = malloc(SIGSTKSZ);
+ if (stk.ss_sp != NULL) {
+ stk.ss_size = SIGSTKSZ;
+ stk.ss_flags = 0;
+ SET_SIGACT(act, segv_handler);
+ act.sa_flags |= SA_ONSTACK | SA_NODEFER;
+ sigemptyset(&act.sa_mask);
+ system_stack_top = (char *) &act;
+ if (sigaltstack(&stk, NULL) == 0)
+ sigaction(SIGSEGV, &act, NULL);
+ else
+ free(stk.ss_sp);
+ }
+ }
+#endif
+}
+
+/* Termination of signal stuff */
+
+#if defined(TARGET_power) || defined(TARGET_s390x) \
+ || defined(HAS_STACK_OVERFLOW_DETECTION)
+static void set_signal_default(int signum)
+{
+ struct sigaction act;
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+ sigaction(signum, &act, NULL);
+}
+#endif
+
+void caml_terminate_signals(void)
+{
+#if defined(TARGET_power)
+ set_signal_default(SIGTRAP);
+#endif
+
+#if defined(TARGET_s390x)
+ set_signal_default(SIGFPE);
+#endif
+
+#ifdef HAS_STACK_OVERFLOW_DETECTION
+ set_signal_default(SIGSEGV);
+ stack_t oldstk, stk;
+ stk.ss_flags = SS_DISABLE;
+ if (sigaltstack(&stk, &oldstk) == 0) {
+ /* If caml_init_signals failed, we are not using an alternate signal stack.
+ SS_DISABLE will be set in oldstk, and there is nothing to free in this
+ case. */
+ if (! (oldstk.ss_flags & SS_DISABLE)) free(oldstk.ss_sp);
}
#endif
}
diff --git a/runtime/startup_nat.c b/runtime/startup_nat.c
index 5b200362f7e2..0cfa61dc4eca 100644
--- a/runtime/startup_nat.c
+++ b/runtime/startup_nat.c
@@ -92,6 +92,7 @@ void (*caml_termination_hook)(void *) = NULL;
extern value caml_start_program (void);
extern void caml_init_ieee_floats (void);
extern void caml_init_signals (void);
+extern void caml_terminate_signals(void);
#ifdef _WIN32
extern void caml_win32_overflow_detection (void);
#endif
@@ -106,6 +107,7 @@ extern void caml_install_invalid_parameter_handler();
value caml_startup_common(char_os **argv, int pooling)
{
char_os * exe_name, * proc_self_exe;
+ value res;
char tos;

/* Determine options */
@@ -153,10 +155,13 @@ value caml_startup_common(char_os **argv, int pooling)
exe_name = caml_search_exe_in_path(exe_name);
caml_sys_init(exe_name, argv);
if (sigsetjmp(caml_termination_jmpbuf.buf, 0)) {
+ caml_terminate_signals();
if (caml_termination_hook != NULL) caml_termination_hook(NULL);
return Val_unit;
}
- return caml_start_program();
+ res = caml_start_program();
+ caml_terminate_signals();
+ return res;
}

value caml_startup_exn(char_os **argv)
diff --git a/runtime/sys.c b/runtime/sys.c
index c019ee9f7e73..e951c636eb68 100644
--- a/runtime/sys.c
+++ b/runtime/sys.c
@@ -112,6 +112,8 @@ static void caml_sys_check_path(value name)
}
}

+extern void caml_terminate_signals(void);
+
CAMLprim value caml_sys_exit(value retcode_v)
{
int retcode = Int_val(retcode_v);
@@ -155,6 +157,9 @@ CAMLprim value caml_sys_exit(value retcode_v)
caml_shutdown();
#ifdef _WIN32
caml_restore_win32_terminal();
+#endif
+#ifdef NATIVE_CODE
+ caml_terminate_signals();
#endif
exit(retcode);
}
7 changes: 1 addition & 6 deletions packages/ocaml/ocaml-base-compiler.4.08.1/opam
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,9 @@ dev-repo: "git+https://github.com/ocaml/ocaml"
extra-files: [
["fix-gcc10.patch" "md5=17ecd696a8f5647a4c543280599f6974"]
["ocaml-base-compiler.install" "md5=3e969b841df1f51ca448e6e6295cb451"]
["alt-signal-stack.patch" "sha256=35403384714b7d9961cc30b775fe9a03a762810c6693d0a4e05fff37c429d521"]
]
url {
src: "https://github.com/ocaml/ocaml/archive/4.08.1.tar.gz"
checksum: "md5=723b6bfe8cf5abcbccc6911143f71055"
}
extra-source "alt-signal-stack.patch" {
src:
"https://github.com/ocaml/ocaml/commit/17df117b4939486d3285031900587afce5262c8c.patch"
checksum:
"sha256=16ad0b9a6f901dd26aa64ff8708a3f24d36237cbf4b34d9eb68a88ed00b96cf3"
}

0 comments on commit d1337c4

Please sign in to comment.