linux: use /proc/self/maps to find precise stack base
This commit is contained in:
parent
060b4e9b32
commit
5dfd17d0b9
|
@ -203,6 +203,7 @@
|
||||||
# define SIGSET_IS_SIGNAL
|
# define SIGSET_IS_SIGNAL
|
||||||
# define SIGSET_NEEDS_REINSTALL
|
# define SIGSET_NEEDS_REINSTALL
|
||||||
|
|
||||||
|
# define LINUX_FIND_STACK_BASE
|
||||||
# define USE_DYNAMIC_FDSET_SIZE
|
# define USE_DYNAMIC_FDSET_SIZE
|
||||||
|
|
||||||
# define USE_TIMEZONE_VAR_W_DLS
|
# define USE_TIMEZONE_VAR_W_DLS
|
||||||
|
@ -1307,6 +1308,9 @@
|
||||||
WINDOWS_FIND_STACK_BOUNDS figures out the maximum stack position
|
WINDOWS_FIND_STACK_BOUNDS figures out the maximum stack position
|
||||||
under Windows (uses GC_find_stack_base())
|
under Windows (uses GC_find_stack_base())
|
||||||
MACOS_FIND_STACK_BOUNDS figures out the stack limit on the Mac.
|
MACOS_FIND_STACK_BOUNDS figures out the stack limit on the Mac.
|
||||||
|
LINUX_FIND_STACK_BASE figures out the stack base under Linux
|
||||||
|
by reading from /proc/self/maps and looking for "[stack]"
|
||||||
|
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.
|
||||||
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. */
|
||||||
|
|
|
@ -426,6 +426,54 @@ scheme_handle_stack_overflow(Scheme_Object *(*k)(void))
|
||||||
return NULL; /* never gets here */
|
return NULL; /* never gets here */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LINUX_FIND_STACK_BASE
|
||||||
|
uintptr_t adjust_stack_base(uintptr_t bnd) {
|
||||||
|
if (bnd == scheme_get_primordial_thread_stack_base()) {
|
||||||
|
/* The address `base' might be far from the actual stack base
|
||||||
|
if Exec Sheild is enabled. Use "/proc/self/maps" to get
|
||||||
|
exacty the stack base. */
|
||||||
|
FILE *f;
|
||||||
|
char *buf;
|
||||||
|
f = fopen("/proc/self/maps", "r");
|
||||||
|
if (f) {
|
||||||
|
buf = malloc(256);
|
||||||
|
while (fgets(buf, 256, f)) {
|
||||||
|
int len;
|
||||||
|
len = strlen(buf);
|
||||||
|
if ((len > 8) && !strcmp("[stack]\n", buf + len - 8)) {
|
||||||
|
uintptr_t p = 0;
|
||||||
|
int i;
|
||||||
|
/* find separator: */
|
||||||
|
for (i = 0; buf[i]; i++) {
|
||||||
|
if (buf[i] == '-') {
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* parse number after separator: */
|
||||||
|
for (; buf[i]; i++) {
|
||||||
|
if ((buf[i] >= '0') && (buf[i] <= '9')) {
|
||||||
|
p = (p << 4) | (buf[i] - '0');
|
||||||
|
} else if ((buf[i] >= 'a') && (buf[i] <= 'f')) {
|
||||||
|
p = (p << 4) | (buf[i] - 'a' + 10);
|
||||||
|
} else if ((buf[i] >= 'A') && (buf[i] <= 'F')) {
|
||||||
|
p = (p << 4) | (buf[i] - 'A' + 10);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* printf("%p vs. %p: %d\n", (void*)bnd, (void*)p, p - bnd); */
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bnd;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void scheme_init_stack_check()
|
void scheme_init_stack_check()
|
||||||
/* Finds the C stack limit --- platform-specific. */
|
/* Finds the C stack limit --- platform-specific. */
|
||||||
{
|
{
|
||||||
|
@ -503,6 +551,10 @@ void scheme_init_stack_check()
|
||||||
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();
|
||||||
|
|
||||||
|
# ifdef LINUX_FIND_STACK_BASE
|
||||||
|
bnd = adjust_stack_base(bnd);
|
||||||
|
# endif
|
||||||
|
|
||||||
lim = (uintptr_t)rl.rlim_cur;
|
lim = (uintptr_t)rl.rlim_cur;
|
||||||
# ifdef UNIX_STACK_MAXIMUM
|
# ifdef UNIX_STACK_MAXIMUM
|
||||||
if (lim > UNIX_STACK_MAXIMUM)
|
if (lim > UNIX_STACK_MAXIMUM)
|
||||||
|
|
|
@ -74,7 +74,7 @@ int scheme_thread_local_offset = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int scheme_num_copied_stacks;
|
extern int scheme_num_copied_stacks;
|
||||||
SHARED_OK static uintptr_t scheme_primordial_os_thread_stack_base;
|
SHARED_OK static uintptr_t primordial_os_thread_stack_base;
|
||||||
THREAD_LOCAL_DECL(static uintptr_t scheme_os_thread_stack_base);
|
THREAD_LOCAL_DECL(static uintptr_t scheme_os_thread_stack_base);
|
||||||
#ifdef USE_THREAD_LOCAL
|
#ifdef USE_THREAD_LOCAL
|
||||||
SHARED_OK Thread_Local_Variables *scheme_vars; /* for debugging */
|
SHARED_OK Thread_Local_Variables *scheme_vars; /* for debugging */
|
||||||
|
@ -118,8 +118,8 @@ void scheme_set_stack_base(void *base, int no_auto_statics) XFORM_SKIP_PROC
|
||||||
scheme_register_traversers();
|
scheme_register_traversers();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
scheme_primordial_os_thread_stack_base = (uintptr_t) base;
|
primordial_os_thread_stack_base = (uintptr_t) base;
|
||||||
scheme_os_thread_stack_base = (uintptr_t) base;
|
scheme_os_thread_stack_base = (uintptr_t) base;
|
||||||
|
|
||||||
#if defined(MZ_PRECISE_GC) || defined(USE_SENORA_GC)
|
#if defined(MZ_PRECISE_GC) || defined(USE_SENORA_GC)
|
||||||
GC_set_stack_base(base);
|
GC_set_stack_base(base);
|
||||||
|
@ -152,6 +152,11 @@ uintptr_t scheme_get_current_os_thread_stack_base()
|
||||||
return scheme_os_thread_stack_base;
|
return scheme_os_thread_stack_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uintptr_t scheme_get_primordial_thread_stack_base()
|
||||||
|
{
|
||||||
|
return primordial_os_thread_stack_base;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Scheme_Env_Main _main;
|
Scheme_Env_Main _main;
|
||||||
int argc;
|
int argc;
|
||||||
|
|
|
@ -130,7 +130,8 @@ int scheme_num_types(void);
|
||||||
|
|
||||||
void scheme_reset_finalizations(void);
|
void scheme_reset_finalizations(void);
|
||||||
|
|
||||||
extern uintptr_t scheme_get_current_os_thread_stack_base(void);
|
uintptr_t scheme_get_primordial_thread_stack_base(void);
|
||||||
|
uintptr_t scheme_get_current_os_thread_stack_base(void);
|
||||||
void scheme_set_current_os_thread_stack_base(void *base);
|
void scheme_set_current_os_thread_stack_base(void *base);
|
||||||
|
|
||||||
int scheme_propagate_ephemeron_marks(void);
|
int scheme_propagate_ephemeron_marks(void);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user