From: Jurij Smakov Date: 2011-10-07T00:33:27+09:00 Subject: [ruby-core:39989] [Ruby 1.9 - Bug #5244] Continuation causes Bus Error on Debian sparc Issue #5244 has been updated by Jurij Smakov. I looked at it some more (ruby1.9.1-1.9.3~preview1+svn33236 now), and tried to figure out what goes wrong by comparing the binaries compiled with -O0 and -O2. The call to ruby_longjmp does not look suspicious, I've verified that in both cases comp->setjmpbuf gets correctly passed to the function. Eventually we get to the point where the actual long jump is performed, which is __longjmp in eglibc-2.13/sysdeps/sparc/sparc32/__longjmp.S. Actual jumping is done with the following code: LOC(thread): /* * Do a "flush register windows trap". The trap handler in the * kernel writes all the register windows to their stack slots, and * marks them all as invalid (needing to be sucked up from the * stack when used). This ensures that all information needed to * unwind to these callers is in memory, not in the register * windows. */ ta ST_FLUSH_WINDOWS #ifdef PTR_DEMANGLE ld ENV(g1,JB_PC), %g5 /* Set return PC. */ ld ENV(g1,JB_SP), %g1 /* Set saved SP on restore below. */ PTR_DEMANGLE2 (%o7, %g5, %g4) PTR_DEMANGLE2 (%fp, %g1, %g4) #else ld ENV(g1,JB_PC), %o7 /* Set return PC. */ ld ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */ #endif sub %fp, 64, %sp /* Allocate a register frame. */ st %g3, RW_FP /* Set saved FP on restore below. */ retl restore %g2, 0, %o0 /* Restore values from above register frame. */ I've verified that in both cases the value of %o7 which is used by retl (it's essentially %o7 + 8) is correct, pointing to the address from where setjmp has been previously called. However, in the optimized case (built with -O2) something goes wrong with the register frame restore (which is executed in retl delay slot), and we jump to the correct address, but with an obviously broken value of 0x5 in %fp, which eventually leads to a SIGBUS once we start dereferencing memory with it. I'll need to do quite a bit of reading here to understand why the broken values end up on the register frame, so it may take a while. ---------------------------------------- Bug #5244: Continuation causes Bus Error on Debian sparc http://redmine.ruby-lang.org/issues/5244 Author: Lucas Nussbaum Status: Feedback Priority: Normal Assignee: Naohisa Goto Category: Target version: ruby -v: - Hi, $ ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -rcontinuation -e 'callcc { |c| c.call }' -e:1: [BUG] Bus Error ruby 1.9.3dev (2011-08-26) [sparc-linux] -- Control frame information ----------------------------------------------- c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :callcc c:0003 p:0009 s:0006 b:0006 l:000fcc d:001d74 EVAL -e:1 c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH c:0001 p:0000 s:0002 b:0002 l:000fcc d:000fcc TOP -- Ruby level backtrace information ---------------------------------------- -e:1:in `
' -e:1:in `callcc' -- C level backtrace information ------------------------------------------- Bus error gdb says: (gdb) run -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -rcontinuation -e 'callcc { |c| c.call }' Starting program: /home/lucas/ruby1.9.1-1.9.3~preview1+svn33077/miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -rcontinuation -e 'callcc { |c| c.call }' [Thread debugging using libthread_db enabled] [New Thread 0xf7fc7b70 (LWP 31418)] [Thread 0xf7fc7b70 (LWP 31418) exited] process 31417 is executing new program: /home/lucas/ruby1.9.1-1.9.3~preview1+svn33077/ruby1.9.1 [Thread debugging using libthread_db enabled] [New Thread 0xf79e5b70 (LWP 31419)] Program received signal SIGBUS, Bus error. 0xf7f4d304 in cont_capture (stat=Cannot access memory at address 0x49 ) at cont.c:439 439 if (ruby_setjmp(cont->jmpbuf)) { (gdb) print cont Cannot access memory at address 0xfffffff9 -- http://redmine.ruby-lang.org