Skip to content

Commit 18f8749

Browse files
committed
Review / new approach.
1 parent 9bb5c59 commit 18f8749

File tree

11 files changed

+4911
-3672
lines changed

11 files changed

+4911
-3672
lines changed

ocaml/configure

Lines changed: 4835 additions & 3645 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ocaml/configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ AS_IF([test x"$enable_runtime5" = xyes],
100100
AC_ARG_ENABLE([stack_checks],
101101
[AS_HELP_STRING([--enable-stack_checks],
102102
[Enable stack checks])])
103+
AS_IF([test x"$enable_stack_checks" = xyes],
104+
[AC_DEFINE([STACK_CHECKS_ENABLED])],
105+
[])
103106

104107
## Output variables
105108

ocaml/otherlibs/systhreads/st_stubs.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,16 @@ static void caml_thread_leave_blocking_section(void)
354354
restore_runtime_state(th);
355355
}
356356

357+
int get_pthreads_stack_size(void) {
358+
pthread_attr_t attr;
359+
size_t res = 8388608;
360+
if (pthread_attr_init(&attr) == 0) {
361+
pthread_attr_getstacksize(&attr, &res);
362+
}
363+
pthread_attr_destroy(&attr);
364+
return res;
365+
}
366+
357367
/* Create and setup a new thread info block.
358368
This block has no associated thread descriptor and
359369
is not inserted in the list of threads. */
@@ -362,7 +372,7 @@ static caml_thread_t caml_thread_new_info(void)
362372
{
363373
caml_thread_t th;
364374
caml_domain_state *domain_state;
365-
uintnat stack_wsize = caml_get_init_stack_wsize(false);
375+
uintnat stack_wsize = caml_get_init_stack_wsize(get_pthreads_stack_size());
366376

367377
domain_state = Caml_state;
368378
th = NULL;

ocaml/runtime/amd64.S

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -545,11 +545,11 @@ LBL(caml_call_gc):
545545
CFI_ENDPROC
546546
ENDFUNCTION(G(caml_call_gc))
547547

548-
FUNCTION(G(caml_raise_stack_overflow))
548+
FUNCTION(G(caml_raise_stack_overflow_nat))
549549
CFI_STARTPROC
550550
CFI_SIGNAL_FRAME
551551
ENTER_FUNCTION
552-
LBL(caml_raise_stack_overflow):
552+
LBL(caml_raise_stack_overflow_nat):
553553
SAVE_ALL_REGS
554554
movq %r15, Caml_state(gc_regs)
555555
SWITCH_OCAML_TO_C
@@ -560,7 +560,7 @@ LBL(caml_raise_stack_overflow):
560560
LEAVE_FUNCTION
561561
ret
562562
CFI_ENDPROC
563-
ENDFUNCTION(G(caml_raise_stack_overflow))
563+
ENDFUNCTION(G(caml_raise_stack_overflow_nat))
564564

565565
FUNCTION(G(caml_alloc1))
566566
CFI_STARTPROC
@@ -817,16 +817,10 @@ LBL(117):
817817
movq %rax, %r12 /* Save exception bucket */
818818
movq Caml_state(c_stack), %rsp
819819
movq %rax, C_ARG_1 /* arg 1: exception bucket */
820-
#ifdef WITH_FRAME_POINTERS
821-
movq 8(%r10), C_ARG_2 /* arg 2: pc of raise */
822-
leaq 16(%r10), C_ARG_3 /* arg 3: sp at raise */
823-
#else
824-
movq (%r10), C_ARG_2 /* arg 2: pc of raise */
825-
leaq 8(%r10), C_ARG_3 /* arg 3: sp at raise */
826-
#endif
827-
movq Caml_state(exn_handler), C_ARG_4
828-
/* arg 4: sp of handler */
829-
C_call (GCALL(caml_stash_backtrace))
820+
movq %r10, C_ARG_2 /* arg 2: passed rsp */
821+
movq Caml_state(exn_handler), C_ARG_3
822+
/* arg 3: sp of handler */
823+
C_call (GCALL(caml_stash_backtrace_wrapper))
830824
movq %r12, %rax /* Recover exception bucket */
831825
RESTORE_EXN_HANDLER_OCAML
832826
ret

ocaml/runtime/backtrace_nat.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <stdio.h>
2121
#include <stdlib.h>
2222
#include <string.h>
23+
#include <unistd.h>
2324

2425
#include "caml/alloc.h"
2526
#include "caml/backtrace.h"
@@ -132,6 +133,32 @@ void caml_stash_backtrace(value exn, uintnat pc, char * sp, char* trapsp)
132133
}
133134
}
134135

136+
void caml_stash_backtrace_wrapper(value exn, char* rsp, char* trapsp) {
137+
#if defined(NATIVE_CODE) && !defined(STACK_CHECKS_ENABLED)
138+
/* if we have protected part of the memory, and get an rsp in the
139+
* protected range, just do nothing - using rsp would trigger another
140+
* segfault, while we are probably in the process of raising the
141+
* exception from a segfault... */
142+
struct stack_info *block = Caml_state->current_stack;
143+
int page_size = getpagesize();
144+
char* protected_low = (char *) block + page_size;
145+
char* protected_high = protected_low + page_size;
146+
if ((rsp >= protected_low) && (rsp < protected_high)) {
147+
return;
148+
}
149+
#endif
150+
char* pc;
151+
char* sp;
152+
#ifdef WITH_FRAME_POINTERS
153+
pc = rsp + 8;
154+
sp = rsp + 16;
155+
#else
156+
pc = rsp;
157+
sp = rsp + 8;
158+
#endif
159+
caml_stash_backtrace(exn, *((uintnat*) pc), sp, trapsp);
160+
}
161+
135162
/* minimum size to allocate a backtrace (in slots) */
136163
#define MIN_BACKTRACE_SIZE 16
137164

ocaml/runtime/caml/fiber.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
#ifdef CAML_INTERNALS
2323

24-
#include <stdbool.h>
2524
#include "misc.h"
2625
#include "mlvalues.h"
2726
#include "roots.h"
@@ -258,7 +257,7 @@ struct stack_info* caml_alloc_stack_noexc(mlsize_t wosize, value hval,
258257
/* try to grow the stack until at least required_size words are available.
259258
returns nonzero on success */
260259
CAMLextern int caml_try_realloc_stack (asize_t required_wsize);
261-
CAMLextern uintnat caml_get_init_stack_wsize(bool is_main_thread);
260+
CAMLextern uintnat caml_get_init_stack_wsize(int thread_stack_wsz);
262261
void caml_change_max_stack_size (uintnat new_max_wsize);
263262
void caml_maybe_expand_stack(void);
264263
CAMLextern void caml_free_stack(struct stack_info* stk);

ocaml/runtime/caml/m.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,5 @@
101101
#undef USE_MMAP_MAP_STACK
102102

103103
#undef STACK_ALLOCATION
104+
105+
#undef STACK_CHECKS_ENABLED

ocaml/runtime/domain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ static void domain_create(uintnat initial_minor_heap_wsize,
545545
dom_internal* d = 0;
546546
caml_domain_state* domain_state;
547547
struct interruptor* s;
548-
uintnat stack_wsize = caml_get_init_stack_wsize(true);
548+
uintnat stack_wsize = caml_get_init_stack_wsize(-1 /* main thread */);
549549

550550
CAMLassert (domain_self == 0);
551551

ocaml/runtime/fiber.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,17 @@
4949

5050
static _Atomic int64_t fiber_id = 0;
5151

52-
uintnat caml_get_init_stack_wsize (bool is_main_thread)
52+
uintnat caml_get_init_stack_wsize (int thread_stack_wsz)
5353
{
54+
#if defined(NATIVE_CODE) && !defined(STACK_CHECKS_ENABLED)
5455
uintnat init_stack_wsize =
55-
is_main_thread
56+
thread_stack_wsz < 0
5657
? caml_params->init_main_stack_wsz
57-
: caml_params->init_thread_stack_wsz;
58+
: caml_params->init_thread_stack_wsz > 0 ? caml_params->init_thread_stack_wsz : thread_stack_wsz;
59+
#else
60+
(void) thread_stack_wsz;
61+
uintnat init_stack_wsize = Wsize_bsize(Stack_init_bsize);
62+
#endif
5863
uintnat stack_wsize;
5964

6065
if (init_stack_wsize < caml_max_stack_wsize)
@@ -114,7 +119,7 @@ Caml_inline struct stack_info* alloc_for_stack (mlsize_t wosize)
114119
si->size = len;
115120
return si;
116121
#else
117-
#ifdef NATIVE_CODE
122+
#if defined(NATIVE_CODE) && !defined(STACK_CHECKS_ENABLED)
118123
/* (We use the following strategy only in native code, because bytecode
119124
* has its own way of dealing with stack checks.)
120125
*
@@ -136,7 +141,7 @@ Caml_inline struct stack_info* alloc_for_stack (mlsize_t wosize)
136141
* for the page that will act as the guard.
137142
*
138143
* The reasoning behind this convoluted process is that if we only
139-
* mmap and then mprotect, we incur the disk of splitting a huge page
144+
* mmap and then mprotect, we incur the risk of splitting a huge page
140145
* and losing its benefits while causing more bookkeeping.
141146
*/
142147
size_t bsize = Bsize_wsize(wosize);
@@ -871,7 +876,7 @@ void caml_free_stack (struct stack_info* stack)
871876
CAMLassert(cache != NULL);
872877

873878
#ifndef USE_MMAP_MAP_STACK
874-
#ifdef NATIVE_CODE
879+
#if defined(NATIVE_CODE) && !defined(STACK_CHECKS_ENABLED)
875880
int page_size = getpagesize();
876881
mprotect((void *) ((char *) stack + page_size),
877882
page_size,
@@ -894,7 +899,7 @@ void caml_free_stack (struct stack_info* stack)
894899
#ifdef USE_MMAP_MAP_STACK
895900
munmap(stack, stack->size);
896901
#else
897-
#ifdef NATIVE_CODE
902+
#if defined(NATIVE_CODE) && !defined(STACK_CHECKS_ENABLED)
898903
munmap(stack, stack->size);
899904
#else
900905
caml_stat_free(stack);

ocaml/runtime/signals_nat.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ void caml_garbage_collection(void)
9797
sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \
9898
sigact.sa_flags = SA_SIGINFO
9999

100+
#if defined(NATIVE_CODE) && !defined(STACK_CHECKS_ENABLED)
100101

101-
CAMLextern void caml_raise_stack_overflow(void);
102+
CAMLextern void caml_raise_stack_overflow_nat(void);
102103

103104
DECLARE_SIGNAL_HANDLER(segv_handler)
104105
{
@@ -109,7 +110,7 @@ DECLARE_SIGNAL_HANDLER(segv_handler)
109110
char* protected_low = (char *) block + page_size;
110111
char* protected_high = protected_low + page_size;
111112
if ((fault_addr >= protected_low) && (fault_addr < protected_high)) {
112-
context->uc_mcontext.gregs[REG_RIP]= (greg_t) &caml_raise_stack_overflow;
113+
context->uc_mcontext.gregs[REG_RIP]= (greg_t) &caml_raise_stack_overflow_nat;
113114
} else {
114115
act.sa_handler = SIG_DFL;
115116
act.sa_flags = 0;
@@ -126,3 +127,11 @@ void caml_init_nat_signals(void)
126127
sigemptyset(&act.sa_mask);
127128
sigaction(SIGSEGV, &act, NULL);
128129
}
130+
131+
#else
132+
133+
void caml_init_nat_signals(void)
134+
{
135+
}
136+
137+
#endif

ocaml/runtime/startup_aux.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ static void init_startup_params(void)
7171
params.init_custom_minor_ratio = Custom_minor_ratio_def;
7272
params.init_custom_minor_max_bsz = Custom_minor_max_bsz_def;
7373
params.init_main_stack_wsz = init_main_stack_wsz;
74-
params.init_thread_stack_wsz = init_main_stack_wsz / 4;
74+
params.init_thread_stack_wsz = 0;
7575
params.init_max_stack_wsz = Max_stack_def;
7676
params.runtime_events_log_wsize = Default_runtime_events_log_wsize;
7777

0 commit comments

Comments
 (0)