OpenBSD: another approach to finding stack bounds

OpenBSD provides pthread_stackseg_np(), which directly reports
the stack-bounds information that Racket needs, so we can use
that instead of the approach used on other Unix variants. The
approach used for other Unix variants seems not to work for OpenBSD
because the stack location at the point that main() is called
is already significantly far from the stack base (on the order
of 100k on a 32-bit system in my test using OpenBSD 5.2).
This commit is contained in:
Matthew Flatt 2013-10-15 08:41:41 -06:00
parent 91ac5138ca
commit 3a9ad7746b
5 changed files with 25 additions and 14 deletions

View File

@ -322,15 +322,12 @@
# endif # endif
# include <sys/param.h> # include <sys/param.h>
# if OpenBSD < 201211
/* This is needed for (pre-5.2) userspace threads: */
# define ASSUME_FIXED_STACK_SIZE
# define FIXED_STACK_SIZE 1048576
# endif
# include "uconfig.h" # include "uconfig.h"
# undef HAS_STANDARD_IOB # undef HAS_STANDARD_IOB
# define HAS_BSD_IOB # define HAS_BSD_IOB
# undef UNIX_FIND_STACK_BOUNDS
# define PTHREAD_STACKSEG_FIND_STACK_BOUNDS
/* Default UNIX_STACK_MAXIMUM is too big for a non-root user. */ /* Default UNIX_STACK_MAXIMUM is too big for a non-root user. */
# undef UNIX_STACK_MAXIMUM # undef UNIX_STACK_MAXIMUM
@ -1515,6 +1512,8 @@
line. line.
ASSUME_FIXED_STACK_SIZE assumes that the main stack size is ASSUME_FIXED_STACK_SIZE assumes that the main stack size is
always FIXED_STACK_SIZE. always FIXED_STACK_SIZE.
PTHREAD_STACKSEG_FIND_STACK_BOUNDS finds stack bounds using
pthread_stackseg_np().
Use only one of these if DO_STACK_CHECK is used, or none otherwise. */ Use only one of these if DO_STACK_CHECK is used, or none otherwise. */
/* FIXED_STACK_SIZE <X> sets the stack size to <X> when the /* FIXED_STACK_SIZE <X> sets the stack size to <X> when the

View File

@ -144,6 +144,11 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#ifdef PTHREAD_STACKSEG_FIND_STACK_BOUNDS
# include <sys/signal.h>
# include <pthread.h>
# include <pthread_np.h>
#endif
#ifdef WINDOWS_FIND_STACK_BOUNDS #ifdef WINDOWS_FIND_STACK_BOUNDS
#include <windows.h> #include <windows.h>
#endif #endif
@ -595,9 +600,6 @@ void scheme_init_stack_check()
{ {
int *v, stack_grows_up; int *v, stack_grows_up;
uintptr_t deeper; uintptr_t deeper;
#ifdef UNIX_FIND_STACK_BOUNDS
struct rlimit rl;
#endif
deeper = scheme_get_deeper_address(); deeper = scheme_get_deeper_address();
stack_grows_up = (deeper > (uintptr_t)&v); stack_grows_up = (deeper > (uintptr_t)&v);
@ -665,12 +667,14 @@ void scheme_init_stack_check()
# endif # endif
# ifdef UNIX_FIND_STACK_BOUNDS # ifdef UNIX_FIND_STACK_BOUNDS
getrlimit(RLIMIT_STACK, &rl);
{ {
struct rlimit rl;
uintptr_t bnd, lim; uintptr_t bnd, lim;
bnd = (uintptr_t)scheme_get_current_os_thread_stack_base(); bnd = (uintptr_t)scheme_get_current_os_thread_stack_base();
getrlimit(RLIMIT_STACK, &rl);
# ifdef LINUX_FIND_STACK_BASE # ifdef LINUX_FIND_STACK_BASE
bnd = adjust_stack_base(bnd); bnd = adjust_stack_base(bnd);
# endif # endif
@ -689,6 +693,14 @@ void scheme_init_stack_check()
scheme_stack_boundary = bnd; scheme_stack_boundary = bnd;
} }
# endif # endif
# ifdef PTHREAD_STACKSEG_FIND_STACK_BOUNDS
{
stack_t stack;
pthread_stackseg_np(pthread_self(), &stack);
scheme_stack_boundary = (uintptr_t)((char *)stack.ss_sp - (stack.ss_size - STACK_SAFETY_MARGIN));
}
# endif
} }
#endif #endif

View File

@ -28,7 +28,7 @@
#include "schmach.h" #include "schmach.h"
#include "schexpobs.h" #include "schexpobs.h"
#define MIN(l,o) ((l) < (o) ? (l) : (o)) #define mz_MIN(l,o) ((l) < (o) ? (l) : (o))
/* globals */ /* globals */
SHARED_OK Scheme_Object *(*scheme_module_demand_hook)(int, Scheme_Object **); SHARED_OK Scheme_Object *(*scheme_module_demand_hook)(int, Scheme_Object **);
@ -3673,7 +3673,7 @@ int scheme_resolved_module_path_value_matches(Scheme_Object *rmp, Scheme_Object
else if (SCHEME_BYTE_STRINGP(rmp_val) && SCHEME_SYMBOLP(o)) { else if (SCHEME_BYTE_STRINGP(rmp_val) && SCHEME_SYMBOLP(o)) {
return !strncmp(SCHEME_BYTE_STR_VAL(rmp_val), return !strncmp(SCHEME_BYTE_STR_VAL(rmp_val),
SCHEME_SYM_VAL(o), SCHEME_SYM_VAL(o),
MIN(SCHEME_BYTE_STRLEN_VAL(rmp_val), SCHEME_SYM_LEN(o))); mz_MIN(SCHEME_BYTE_STRLEN_VAL(rmp_val), SCHEME_SYM_LEN(o)));
} else { } else {
scheme_arg_mismatch("scheme_resolved_module_path_value_matches", scheme_arg_mismatch("scheme_resolved_module_path_value_matches",
"internal error: unknown type of resolved_module_path_value", "internal error: unknown type of resolved_module_path_value",

View File

@ -21,7 +21,7 @@
# if defined(UNIX_FIND_STACK_BOUNDS) || defined(WINDOWS_FIND_STACK_BOUNDS) \ # if defined(UNIX_FIND_STACK_BOUNDS) || defined(WINDOWS_FIND_STACK_BOUNDS) \
|| defined(MACOS_FIND_STACK_BOUNDS) || defined(ASSUME_FIXED_STACK_SIZE) \ || defined(MACOS_FIND_STACK_BOUNDS) || defined(ASSUME_FIXED_STACK_SIZE) \
|| defined(BEOS_FIND_STACK_BOUNDS) || defined(OSKIT_FIXED_STACK_BOUNDS) \ || defined(BEOS_FIND_STACK_BOUNDS) || defined(OSKIT_FIXED_STACK_BOUNDS) \
|| defined(PALM_FIND_STACK_BOUNDS) || defined(PALM_FIND_STACK_BOUNDS) || defined(PTHREAD_STACKSEG_FIND_STACK_BOUNDS)
uintptr_t _stk_pos; uintptr_t _stk_pos;
_stk_pos = (uintptr_t)&_stk_pos; _stk_pos = (uintptr_t)&_stk_pos;

View File

@ -1705,7 +1705,7 @@ typedef struct Scheme_Overflow {
#if defined(UNIX_FIND_STACK_BOUNDS) || defined(WINDOWS_FIND_STACK_BOUNDS) \ #if defined(UNIX_FIND_STACK_BOUNDS) || defined(WINDOWS_FIND_STACK_BOUNDS) \
|| defined(MACOS_FIND_STACK_BOUNDS) || defined(ASSUME_FIXED_STACK_SIZE) \ || defined(MACOS_FIND_STACK_BOUNDS) || defined(ASSUME_FIXED_STACK_SIZE) \
|| defined(BEOS_FIND_STACK_BOUNDS) || defined(OSKIT_FIXED_STACK_BOUNDS) \ || defined(BEOS_FIND_STACK_BOUNDS) || defined(OSKIT_FIXED_STACK_BOUNDS) \
|| defined(PALM_FIND_STACK_BOUNDS) || defined(PALM_FIND_STACK_BOUNDS) || defined(PTHREAD_STACKSEG_FIND_STACK_BOUNDS)
# define USE_STACK_BOUNDARY_VAR # define USE_STACK_BOUNDARY_VAR
THREAD_LOCAL_DECL(extern uintptr_t scheme_stack_boundary); THREAD_LOCAL_DECL(extern uintptr_t scheme_stack_boundary);
/* Same as scheme_stack_boundary, but set to an extreme value when feul auto-expires, /* Same as scheme_stack_boundary, but set to an extreme value when feul auto-expires,