[MacRuby-devel] Debugging MacRuby?

Thibault Martin-Lagardette thibault.ml at gmail.com
Fri Jul 9 11:32:08 PDT 2010


Hi!

I'm not sure exactly why you are having these problems, but I'll show you how we usually do debugging.

Please note, however, that the current problem seems to be a very know issue, where we sometimes have a threading problem (the assertion is always the same).
It's a very, very tricky bug that is not easy to fix at all. I'm just saying, so that you do not lose too many time trying to fix it thinking it's an easy one :-).

But for further reference, or in case you really want to dig into this, here's an example on how you can use GDB to understand what is going on in the program.
There is obviously more to it, I'm just providing a rapid overview of what is available to you for debugging.

(Note that I will assume you are already working with trunk ; commands will be underlined)



macruby-dir$ rake clean # make sure you have clean objects
macruby-dir$ mkdir doc # avoid generating new doc
macruby-dir$ rake jobs=4 # because I have 4 cores
macruby-dir$ sudo rake install # will install macruby on the system, not necessary though
macruby-dir$ cd /tmp
/tmp$ DYLD_LIBRARY_PATH=/path/to/macruby-dir gdb --args macruby test_webrick.rb # DYLD_... is necessary here to use the dylib without stripped symbols
(gdb) r # alias to run
Starting program: /usr/local/bin/macruby test_webrick.rb
Reading symbols for shared libraries .++++........................ done
[...]
[2010-07-09 11:02:05] INFO  WEBrick 1.3.1
[2010-07-09 11:02:05] INFO  ruby 1.9.2 (2008-06-03) [universal-darwin10.0]
[2010-07-09 11:02:05] INFO  WEBrick::HTTPServer#start: pid=62321 port=8000
Assertion failed: ((b->flags & flags) == flags), function rb_vm_prepare_block, file dispatcher.cpp, line 1343.

Program received signal SIGABRT, Aborted.
0x00007fff85089dce in select$DARWIN_EXTSN ()
(gdb) thread apply all bt # ask GDB to display the backtrace (bt) of all threads. In our case, only thread 4 is interesting because that's where abort is called

Thread 6 (process 62321):
Thread 5 (process 62321):
Thread 4 (process 62321):
#0  0x00007fff850b8b6e in __semwait_signal_nocancel ()
#1  0x00007fff850b8a70 in nanosleep$NOCANCEL ()
#2  0x00007fff851153c6 in usleep$NOCANCEL ()
#3  0x00007fff8513497c in abort ()
#4  0x00007fff851219b4 in __assert_rtn ()
#5  0x000000010012e640 in rb_vm_prepare_block (function=0x101489b60, flags=64, self=8592424896, arity=<value temporarily unavailable, due to optimizations>, parent_var_uses=0x10177c1c8, parent_block=0x20020a720, dvars_size=0) at dispatcher.cpp:1343
#6  0x00000001035b7863 in ?? ()
#7  0x00000001001333e7 in rb_vm_yield_args (_vm=0x10704a3d0, argc=<value temporarily unavailable, due to optimizations>, argv=0x2002c2e00) at dispatcher.cpp:104
#8  0x00000001000ed518 in rb_yield (val=8593375200) at vm_eval.c:196
#9  0x000000010003d5a7 in each_pair_i (key=8593375200, value=0) at hash.c:1077
#10 0x000000010003d0d6 in foreach_safe_i (key=<value temporarily unavailable, due to optimizations>, value=<value temporarily unavailable, due to optimizations>, arg=<value temporarily unavailable, due to optimizations>) at hash.c:69
#11 0x00000001000b0641 in st_foreach (table=0x2003800e0, func=0x10003d0c0 <foreach_safe_i>, arg=4319594144) at st.c:669
#12 0x000000010003e5fb in st_foreach_safe [inlined] () at /Users/naixn/Documents/Projets/MacRuby/hash.c:84
#13 0x000000010003e5fb in rhash_foreach [inlined] () at /Users/naixn/Documents/Projets/MacRuby/hash.h:64
#14 0x000000010003e5fb in rhash_each_pair (hash=8593215584, sel=0x100f517e0) at hash.c:1086
#15 0x0000000100130856 in rb_vm_dispatch (_vm=0x10704a3d0, cache=0x107728980, top=8592424896, self=8593215584, klass=0x200075340, sel=0x100f517e0, block=0x20020a720, opt=0 '\0', argc=<value temporarily unavailable, due to optimizations>, argv=0x0) at dispatcher.cpp:161
#16 0x000000010355ac00 in ?? ()
#17 0x0000000103577f58 in ?? ()
#18 0x000000010013083b in rb_vm_dispatch (_vm=0x10704a3d0, cache=0x107723700, top=8592757280, self=8592424896, klass=0x20025ff80, sel=0x101487420, block=0x0, opt=0 '\0', argc=<value temporarily unavailable, due to optimizations>, argv=0x10177e1c8) at dispatcher.cpp:163
#19 0x000000010355ac00 in ?? ()
#20 0x00000001035b6df5 in ?? ()
#21 0x000000010013083b in rb_vm_dispatch (_vm=0x10704a3d0, cache=0x10771cec0, top=8592757280, self=8592757280, klass=0x2002de220, sel=0x104c105e0, block=0x0, opt=2 '\002', argc=<value temporarily unavailable, due to optimizations>, argv=0x10177ef58) at dispatcher.cpp:163
#22 0x000000010355ac00 in ?? ()
#23 0x00000001035b2a12 in ?? ()
#24 0x000000010013083b in rb_vm_dispatch (_vm=0x10704a3d0, cache=0x10771e6c0, top=8593309248, self=8592757280, klass=0x2002de220, sel=0x107090660, block=0x0, opt=0 '\0', argc=<value temporarily unavailable, due to optimizations>, argv=0x10177fcd8) at dispatcher.cpp:163
#25 0x000000010355ac00 in ?? ()
#26 0x00000001035a69fd in ?? ()
#27 0x000000010013083b in rb_vm_dispatch (_vm=0x10704a3d0, cache=0x107712510, top=8593309248, self=8593309248, klass=0x20034b8c0, sel=0x7fff84e14103, block=0x0, opt=2 '\002', argc=<value temporarily unavailable, due to optimizations>, argv=0x101780a88) at dispatcher.cpp:163
#28 0x000000010355ac00 in ?? ()
#29 0x00000001035b1599 in ?? ()
#30 0x00000001001321f9 in rb_vm_block_eval (b=0x10704a3d0, argc=<value temporarily unavailable, due to optimizations>, argv=0x1) at dispatcher.cpp:100
#31 0x0000000100146440 in rb_vm_thread_run (thread=8592676096) at vm.cpp:4378
#32 0x00007fff8507f456 in _pthread_start ()
#33 0x00007fff8507f309 in thread_start ()

Thread 2 (process 62321):
Thread 1 (process 62321):

####
# rb_vm_dispatch receives "klass" (the class of the object, which is an Obj-C class) and "sel" (the obj-c selector, aka the sent message). Let's use that to understand what is going on
####
(gdb) p (char *)class_getName(0x200075340) # Using the obj-c runtime to have information about the class
$10 = 0x100ff9b20 "Hash"
(gdb) p (char *)0x100f517e0 # The sel=0x... value in rb_vm_dispatch is a selector, aka a char *, easy to display
$1 = 0x100f517e0 "each"
(gdb) p (char *)class_getName(0x20025ff80)
$9 = 0x104b707c0 "HTTPUtils"
(gdb) p (char *)0x101487420
$2 = 0x101487420 "parse_header:" # this means that "parse_header" was called on a HTTPUtils object

(gdb) call rb_symbolicate(0x0000000103577f58) # rb_symbolicate can be used to display those ruby parts where gdb only displays "??"
addr 0x103577f58 start 0x103577d00 selector parse_header: location /Library/Frameworks/MacRuby.framework/Versions/0.7/usr/lib/ruby/1.9.2/webrick/httputils.rb:120
(gdb) call rb_symbolicate(0x00000001035b7863) # This is the block that seems to be causing a problem, note that we even thacve the file + line information
addr 0x1035b7863 start 0x1035b77e0 selector block location /Library/Frameworks/MacRuby.framework/Versions/0.7/usr/lib/ruby/1.9.2/webrick/httputils.rb:140

(gdb) thread 4 # Switch to thread 4, where the problem happens ; you can also type "thr 4"
[Switching to thread 4 (process 62321)]
0x00007fff850b8b6e in __semwait_signal_nocancel ()
(gdb) frame 5 # Go to frame #5, where the assert is called ; you can also type "fr 5"
#5  0x000000010012e640 in rb_vm_prepare_block (function=0x101489b60, flags=64, self=8592424896, arity=<value temporarily unavailable, due to optimizations>, parent_var_uses=0x10177c1c8, parent_block=0x20020a720, dvars_size=0) at dispatcher.cpp:1343
1343		assert((b->flags & flags) == flags);
(gdb) list #display the current code ; you can also type l (the letter L)
1338		b->parent_var_uses = NULL;
1339		b->parent_block = NULL;
1340	    }
1341	    else {
1342		assert(b->dvars_size == dvars_size);
1343		assert((b->flags & flags) == flags);
1344	    }
1345	
1346	    b->proc = Qnil;
1347	    b->self = self;
(gdb) #Happing debugging! :D


-- 
Thibault Martin-Lagardette



On Jul 9, 2010, at 10:50, Alexander v. Below wrote:

> Hello,
> 
> dear list, allow me another stupid question: I want to go into MacRuby's guts, and throw gdb at it.
> 
> Attempting to look at issue #753, I did the naive thing:
> 
> % gdb macruby
> (gdb) break dispatcher.cpp:1343
> 
> The answer here was: 
> "No symbol table is loaded.  Use the "file" command.
> Make breakpoint pending on future shared library load? (y or [n]) y
> Breakpoint 1 (dispatcher.cpp:1343) pending."
> 
> Question 1:
> Do I need to build MacRuby differently to get a symbol file? Or is it just hidden away somewhere?
> 
> When I continue:
> 
> (gdb) run test_webrick.rb
> 
> After a while, what I get is:
> 
> [2010-07-09 19:42:21] ERROR Errno::EINTR: Interrupted system call - select(2) failed
> 	/Library/Frameworks/MacRuby.framework/Versions/0.7/usr/lib/ruby/1.9.2/webrick/server.rb:83:in `block'
> 
> Which is way off from the error I would expect.
> 
> If I do not try to set a breakpoint, I get the expected console output ("Assertion failed: ((b->flags & flags) == flags), function rb_vm_prepare_block, file dispatcher.cpp, line 1343."), and a SIGABRT. The backtrace looks, well, not really nice.
> 
> Question 2: Am I even approaching this right? Or do I need to take special precautions?
> 
> 
> Thanks a lot
> 
> Alex
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-devel/attachments/20100709/af972ae8/attachment-0001.html>


More information about the MacRuby-devel mailing list