eval_intern.h: refine stack overflow detection

* eval_intern.h (TH_PUSH_TAG, TH_EXEC_TAG): refine stack overflow
  detection.  chain local tag after setjmp() successed on it, because
  calling setjmp() also can overflow the stack.
  [ruby-dev:47804] [Bug #9109]
* vm_eval.c (rb_catch_obj): now th->tag points previous tag until
  TH_EXEC_TAG().


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43707 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-11-18 13:47:56 +00:00
Родитель 53953eee7c
Коммит 340390093b
4 изменённых файлов: 20 добавлений и 5 удалений

Просмотреть файл

@ -1,4 +1,12 @@
Mon Nov 18 22:47:11 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
Mon Nov 18 22:47:54 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval_intern.h (TH_PUSH_TAG, TH_EXEC_TAG): refine stack overflow
detection. chain local tag after setjmp() successed on it, because
calling setjmp() also can overflow the stack.
[ruby-dev:47804] [Bug #9109]
* vm_eval.c (rb_catch_obj): now th->tag points previous tag until
TH_EXEC_TAG().
* thread_pthread.c (ruby_init_stack): set stack_start properly by
get_main_stack() if possible.

Просмотреть файл

@ -95,8 +95,7 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval
rb_thread_t * const _th = (th); \
struct rb_vm_tag _tag; \
_tag.tag = 0; \
_tag.prev = _th->tag; \
_th->tag = &_tag;
_tag.prev = _th->tag;
#define TH_POP_TAG() \
_th->tag = _tag.prev; \
@ -129,7 +128,7 @@ rb_threadptr_tag_jump(rb_thread_t *th, int st)
[ISO/IEC 9899:1999] 7.13.1.1
*/
#define TH_EXEC_TAG() \
(ruby_setjmp(_th->tag->buf) ? rb_threadptr_tag_state(_th) : 0)
(ruby_setjmp(_tag.buf) ? rb_threadptr_tag_state(_th) : (_th->tag = &_tag, 0))
#define EXEC_TAG() \
TH_EXEC_TAG()

Просмотреть файл

@ -477,6 +477,14 @@ end.join
assert_raise(SystemStackError){m}
end
def test_machine_stackoverflow
bug9109 = '[ruby-dev:47804] [Bug #9109]'
assert_separately([], <<-SRC)
h = {a: ->{h[:a].call}}
assert_raise(SystemStackError, #{bug9109.dump}) {h[:a].call}
SRC
end
def test_cause
msg = "[Feature #8257]"
cause = nil

Просмотреть файл

@ -1823,7 +1823,7 @@ rb_catch_obj(VALUE t, VALUE (*func)(), VALUE data)
TH_PUSH_TAG(th);
th->tag->tag = tag;
_tag.tag = tag;
if ((state = TH_EXEC_TAG()) == 0) {
/* call with argc=1, argv = [tag], block = Qnil to insure compatibility */