1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

thread_pthread.c: Fix intermittent SIGBUS on Linux

* thread_pthread.c (reserve_stack): fix intermittent SIGBUS on
  Linux, by reserving the stack virtual address space at process
  start up so that it will not clash with the heap space.
  [Fix GH-822]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49452 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-01-31 03:06:26 +00:00
parent 1b11ba706d
commit 8fe95fea9d
2 changed files with 44 additions and 0 deletions

View file

@ -1,3 +1,10 @@
Sat Jan 31 12:06:23 2015 Scott Francis <scott.francis@shopify.com>
* thread_pthread.c (reserve_stack): fix intermittent SIGBUS on
Linux, by reserving the stack virtual address space at process
start up so that it will not clash with the heap space.
[Fix GH-822]
Fri Jan 30 17:28:29 2015 gogotanaka <mail@tanakakazuki.com> Fri Jan 30 17:28:29 2015 gogotanaka <mail@tanakakazuki.com>
* math.c (num2dbl_with_to_f): make faster when Bignum passed by * math.c (num2dbl_with_to_f): make faster when Bignum passed by

View file

@ -653,6 +653,42 @@ space_size(size_t stack_size)
} }
} }
#ifdef __linux__
static __attribute__((noinline)) void
reserve_stack(volatile char *limit, size_t size)
{
# ifdef C_ALLOCA
# error needs alloca()
# endif
struct rlimit rl;
volatile char buf[0x100];
STACK_GROW_DIR_DETECTION;
if (!getrlimit(RLIMIT_STACK, &rl) && rl.rlim_cur == RLIM_INFINITY)
return;
size -= sizeof(buf); /* margin */
if (IS_STACK_DIR_UPPER()) {
const volatile char *end = buf + sizeof(buf);
limit += size;
if (limit > end) {
size = limit - end;
limit = alloca(size);
limit[size-1] = 0;
}
}
else {
limit -= size;
if (buf > limit) {
limit = alloca(buf - limit);
limit[0] = 0;
}
}
}
#else
# define reserve_stack(limit, size) ((void)(limit), (void)(size))
#endif
#undef ruby_init_stack #undef ruby_init_stack
/* Set stack bottom of Ruby implementation. /* Set stack bottom of Ruby implementation.
* *
@ -674,6 +710,7 @@ ruby_init_stack(volatile VALUE *addr
if (get_main_stack(&stackaddr, &size) == 0) { if (get_main_stack(&stackaddr, &size) == 0) {
native_main_thread.stack_maxsize = size; native_main_thread.stack_maxsize = size;
native_main_thread.stack_start = stackaddr; native_main_thread.stack_start = stackaddr;
reserve_stack(stackaddr, size);
return; return;
} }
} }