Skip to content

Commit

Permalink
eval_intern.h: refine stack overflow detection
Browse files Browse the repository at this point in the history
* 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 ruby#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
  • Loading branch information
nobu committed Nov 18, 2013
1 parent 53953ee commit 3403900
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
10 changes: 9 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
Mon Nov 18 22:47:11 2013 Nobuyoshi Nakada <[email protected]>
Mon Nov 18 22:47:54 2013 Nobuyoshi Nakada <[email protected]>

* 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.
Expand Down
5 changes: 2 additions & 3 deletions eval_intern.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; \
Expand Down Expand Up @@ -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()
Expand Down
8 changes: 8 additions & 0 deletions test/ruby/test_exception.rb
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,14 @@ def test_stackoverflow
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
Expand Down
2 changes: 1 addition & 1 deletion vm_eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit 3403900

Please sign in to comment.