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:
parent
1b11ba706d
commit
8fe95fea9d
2 changed files with 44 additions and 0 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue