diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-04-04 08:37:25 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-04-04 08:37:25 +0000 |
commit | c3699626dadc317196805e487b18e44cfe937cad (patch) | |
tree | cf85518579827252a449b5b2dc5e3bfcd1c23afe | |
parent | e18259424ea6f1baafacab442d57c05d51c2548b (diff) | |
download | ruby-c3699626dadc317196805e487b18e44cfe937cad.tar.gz |
signal.c: check stack overflow by SP
* signal.c (check_stack_overflow): raise SystemStackError if SP
register and fault address is in the same page, on x86 linux.
[EXPERIMENTAL]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45517 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | signal.c | 24 |
1 files changed, 22 insertions, 2 deletions
@@ -635,21 +635,41 @@ rb_get_next_signal(void) #if defined(USE_SIGALTSTACK) || defined(_WIN32) +NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); +#if defined __linux__ && (defined __i386__ || defined __x86_64__) +static void +check_stack_overflow(const uintptr_t addr, const ucontext_t *ctx) +{ +# if defined REG_RSP + const greg_t sp = ctx->uc_mcontext.gregs[REG_RSP]; +# else + const greg_t sp = ctx->uc_mcontext.gregs[REG_ESP]; +# endif + enum {pagesize = 4096}; + if ((uintptr_t)sp / pagesize == addr / pagesize) { + ruby_thread_stack_overflow(GET_THREAD()); + } +} +#else static void check_stack_overflow(const void *addr) { int ruby_stack_overflowed_p(const rb_thread_t *, const void *); - NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); rb_thread_t *th = GET_THREAD(); if (ruby_stack_overflowed_p(th, addr)) { ruby_thread_stack_overflow(th); } } +#endif #ifdef _WIN32 #define CHECK_STACK_OVERFLOW() check_stack_overflow(0) #else #define FAULT_ADDRESS info->si_addr -#define CHECK_STACK_OVERFLOW() check_stack_overflow(FAULT_ADDRESS) +#if defined __linux__ && (defined __i386__ || defined __x86_64__) +# define CHECK_STACK_OVERFLOW() check_stack_overflow((uintptr_t)FAULT_ADDRESS, ctx) +#else +# define CHECK_STACK_OVERFLOW() check_stack_overflow(FAULT_ADDRESS) +#endif #define MESSAGE_FAULT_ADDRESS " at %p", FAULT_ADDRESS #endif #else |