[MacRuby] #1076: Abort occurs when raise a SecurityError within Thread.
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Test Script: {{{ #!ruby a = [1, 2] Thread.start { $SAFE = 4 a.shift }.join }}} Result: {{{ $ macruby tt.rb 2010-12-23 23:14:21.398 macruby[28993:1707] *** Terminating app due to uncaught exception 'SecurityError', reason: 'Insecure: can't modify array (SecurityError) ' *** Call stack at first throw: ( 0 CoreFoundation 0x00007fff83de87b4 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x00007fff8000d0f3 objc_exception_throw + 45 2 libmacruby.dylib 0x0000000100160205 rb_vm_raise + 437 3 libmacruby.dylib 0x00000001000409c9 rb_exc_raise + 9 4 libmacruby.dylib 0x000000010003e7b4 rb_raise + 308 5 libmacruby.dylib 0x0000000100014ec6 rb_mem_clear + 358 6 libmacruby.dylib 0x0000000100017aff rary_reserve + 9407 7 libmacruby.dylib 0x0000000100017cf9 rary_reserve + 9913 8 libmacruby.dylib 0x00000001000ee281 rb_thread_remove_from_group + 81 9 libmacruby.dylib 0x0000000100161a64 rb_vm_thread_run + 212 10 libSystem.B.dylib 0x00007fff883fc536 _pthread_start + 331 11 libSystem.B.dylib 0x00007fff883fc3e9 thread_start + 13 ) terminate called after throwing an instance of 'NSException' zsh: abort macruby tt.rb }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/1076> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by watson1978@…): I think that should not raise an exception in rb_thread_remove_from_group(). Because the exception of rb_thread_remove_from_group() is not caught within rb_vm_thread_run(). Patch: {{{ #!diff diff --git a/NSArray.m b/NSArray.m index 8916881..b1c714e 100644 --- a/NSArray.m +++ b/NSArray.m @@ -1280,6 +1280,17 @@ rb_ary_delete(VALUE ary, VALUE item) } VALUE +rb_ary_delete_force(VALUE ary, VALUE item) +{ + if (IS_RARY(ary)) { + return rary_delete_force(ary, 0, item); + } + else { + return nsary_delete((id)ary, 0, item); + } +} + +VALUE rb_ary_delete_at(VALUE ary, long pos) { if (IS_RARY(ary)) { diff --git a/array.c b/array.c index 2c1c486..2cd818c 100644 --- a/array.c +++ b/array.c @@ -1854,6 +1854,15 @@ rary_delete(VALUE ary, SEL sel, VALUE item) return item; } +VALUE +rary_delete_force(VALUE ary, SEL sel, VALUE item) +{ + if (rary_delete_element(ary, item, true) == false) { + return Qnil; + } + return item; +} + /* * call-seq: * array.delete_at(index) -> obj or nil diff --git a/array.h b/array.h index 4f44716..fb4419a 100644 --- a/array.h +++ b/array.h @@ -146,6 +146,7 @@ VALUE rary_clear(VALUE ary, SEL sel); VALUE rary_reverse_bang(VALUE ary, SEL sel); VALUE rary_includes(VALUE ary, SEL sel, VALUE item); VALUE rary_delete(VALUE ary, SEL sel, VALUE item); +VALUE rary_delete_force(VALUE ary, SEL sel, VALUE item); VALUE rary_delete_at(VALUE ary, SEL sel, VALUE pos); VALUE rary_pop(VALUE ary, SEL sel, int argc, VALUE *argv); VALUE rary_shift(VALUE ary, SEL sel, int argc, VALUE *argv); diff --git a/macruby_internal.h b/macruby_internal.h index 53fad7b..484e857 100644 --- a/macruby_internal.h +++ b/macruby_internal.h @@ -103,6 +103,8 @@ VALUE rb_io_addstr(VALUE, SEL, VALUE); VALUE rb_io_printf(VALUE, SEL, int, VALUE *); VALUE rb_io_print(VALUE, SEL, int, VALUE *); +VALUE rb_ary_delete_force(VALUE ary, VALUE item); + VALUE rb_objc_num_coerce_bin(VALUE x, VALUE Y, SEL sel); VALUE rb_objc_num_coerce_cmp(VALUE, VALUE, SEL sel); VALUE rb_objc_num_coerce_relop(VALUE, VALUE, SEL sel); diff --git a/thread.c b/thread.c index 5c6296b..476c642 100644 --- a/thread.c +++ b/thread.c @@ -1329,7 +1329,7 @@ rb_thread_remove_from_group(VALUE thread) if (t->group != Qnil) { rb_thread_group_t *tg = GetThreadGroupPtr(t->group); thgroup_lock(tg); - if (rb_ary_delete(tg->threads, thread) != thread) { + if (rb_ary_delete_force(tg->threads, thread) != thread) { printf("trying to remove a thread (%p) from a group that doesn't "\ "contain it\n", (void *)thread); abort(); }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:1> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by lsansonetti@…): I think it would be cleaner to just rescue the exception in thread.c. -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:2> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by lsansonetti@…): I tried running the snippet in gdb, and I see that there is a beginning of infinite loop going on here. {{{ (gdb) bt #0 rb_exc_raise (mesg=17184733856) at eval.c:322 #1 0x000000010002b0f4 in rb_raise (exc=<value temporarily unavailable, due to optimizations>, fmt=<value temporarily unavailable, due to optimizations>) at error.c:1145 #2 0x00000001000011d6 in rary_modify (ary=17184733248) at array.h:52 #3 0x0000000100007def in rary_push [inlined] () at /Users/lrz/src /macruby-trunk/array.h:451 #4 0x0000000100007def in rary_push_m (ary=17184733248, sel=<value temporarily unavailable, due to optimizations>, item=17184733184) at array.c:452 #5 0x0000000100143d79 in rb_vm_backtrace (skip=0) at vm.cpp:3695 #6 0x000000010014dbdc in rb_vm_raise (exception=17184732480) at vm.cpp:3477 #7 0x000000010002d309 in rb_exc_raise (mesg=<value temporarily unavailable, due to optimizations>) at eval.c:322 #8 0x000000010002b0f4 in rb_raise (exc=<value temporarily unavailable, due to optimizations>, fmt=<value temporarily unavailable, due to optimizations>) at error.c:1145 #9 0x00000001000011d6 in rary_modify (ary=17184732032) at array.h:52 #10 0x0000000100007def in rary_push [inlined] () at /Users/lrz/src /macruby-trunk/array.h:451 #11 0x0000000100007def in rary_push_m (ary=17184732032, sel=<value temporarily unavailable, due to optimizations>, item=17184731968) at array.c:452 #12 0x0000000100143d79 in rb_vm_backtrace (skip=0) at vm.cpp:3695 #13 0x000000010014dbdc in rb_vm_raise (exception=17184732640) at vm.cpp:3477 #14 0x000000010002d309 in rb_exc_raise (mesg=<value temporarily unavailable, due to optimizations>) at eval.c:322 #15 0x000000010002b0f4 in rb_raise (exc=<value temporarily unavailable, due to optimizations>, fmt=<value temporarily unavailable, due to optimizations>) at error.c:1145 #16 0x00000001000011d6 in rary_modify (ary=17184731296) at array.h:52 #17 0x00000001000094d2 in rary_shift (ary=17184731296, sel=<value temporarily unavailable, due to optimizations>, argc=0, argv=0x0) at array.c:534 #18 0x000000010013875c in rb_vm_dispatch (_vm=0x100bacea0, cache=0x100fda2c0, top=17184153504, self=17184731296, klass=0x40030e340, sel=0x10288b480, block=0x0, opt=0 '\0', argc=0, argv=0x0) at dispatcher.cpp:448 #19 0x0000000102b0663c in ?? () #20 0x0000000102b06cdb in ?? () #21 0x000000010013a169 in rb_vm_block_eval (b=0x100bacea0, argc=<value temporarily unavailable, due to optimizations>, argv=0x0) at dispatcher.cpp:98 #22 0x000000010014fe60 in rb_vm_thread_run (thread=17184731232) at vm.cpp:4552 #23 0x00007fff894c5864 in _pthread_start () #24 0x00007fff894c8575 in thread_start () }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:3> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by lsansonetti@…): First, there is a bug in Array#delete. We check if the array can be modified *after* deleting the item, while it should be done first. {{{ $ ./miniruby -e "a=[1]; a.freeze; a.delete(1) rescue nil; p a" [] $ ruby -e "a=[1]; a.freeze; a.delete(1) rescue nil; p a" [1] }}} This bug is fixed in r5193. -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:4> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by watson1978@…): I modified the Array#delete for CRuby1.9 compatibility with r5099. -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:5> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: blocker | Milestone: MacRuby 0.9 Component: MacRuby | Resolution: fixed Keywords: | ----------------------------------+----------------------------------------- Changes (by lsansonetti@…): * status: new => closed * resolution: => fixed * milestone: => MacRuby 0.9 Comment: I see, thanks for the explanation. I think we should fix the problem differently. This original bug should been fixed in r5195. -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:6> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: blocker | Milestone: MacRuby 0.9 Component: MacRuby | Resolution: fixed Keywords: | ----------------------------------+----------------------------------------- Comment(by lsansonetti@…): I am looking for a better way to fix r5099 but it's tricky :) -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:7> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: blocker | Milestone: MacRuby 0.9 Component: MacRuby | Resolution: fixed Keywords: | ----------------------------------+----------------------------------------- Comment(by lsansonetti@…): This patch should re-implement r5099, however I'm having a ruby spec failure (apparently in rational), so I will commit the patch once I'm sure it does not break anything. {{{ Index: array.c =================================================================== --- array.c (revision 5193) +++ array.c (working copy) @@ -1805,9 +1805,15 @@ VALUE *t = p; VALUE *end = p + RARY(ary)->len; + bool check_modify = true; + if (use_equal) { while (t < end) { if (RTEST(rb_equal_fast(*t, item))) { + if (check_modify) { + rary_modify(ary); + check_modify = false; + } t++; } else { @@ -1820,6 +1826,10 @@ else { while (t < end) { if (*t == item) { + if (check_modify) { + rary_modify(ary); + check_modify = false; + } t++; } else { @@ -1842,7 +1852,6 @@ VALUE rary_delete(VALUE ary, SEL sel, VALUE item) { - rary_modify(ary); const bool changed = rary_delete_element(ary, item, true); if (!changed) { if (rb_block_given_p()) { @@ -2835,7 +2844,6 @@ static VALUE rary_compact_bang(VALUE ary, SEL sel) { - rary_modify(ary); return rary_delete_element(ary, Qnil, false) ? ary : Qnil; } }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:8> MacRuby <http://macruby.org/>
#1076: Abort occurs when raise a SecurityError within Thread. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: blocker | Milestone: MacRuby 0.9 Component: MacRuby | Resolution: fixed Keywords: | ----------------------------------+----------------------------------------- Comment(by lsansonetti@…): Okay I committed a slightly different version of that patch in r5196. -- Ticket URL: <http://www.macruby.org/trac/ticket/1076#comment:9> MacRuby <http://macruby.org/>
participants (1)
-
MacRuby