Getting gdb backtrace from ruby exception

Hi

I'm working on a C extension and somewhere in itsomething is raising a NoMethodError. The exception is reported with the line of ruby code that triggered the bad call in the C extension.

As the C code is large and complex (it's a big SWIG project), I'm having trouble finding the problem in the C code. I would use gdb or Microsoft's debugger to look at the stack if it was a C error - but when a Ruby exception is raised, the process exits and there's no stack to inspect.

Ruby's debugger isn't helpful because it only knows about ruby written in ruby.

Is there any way I can get at the C stack at the point of ruby 'raise' from a C extension?

Thanks
alex

There was a way how to run ruby under gdb with the ability to debug at
"ruby level" while still having the "C view" at hand.

http://eigenclass.org/hiki.rb?ruby+live+process+introspection
http://weblog.jamisbuck.org/2006/9/25/gdb-wrapper-for-ruby
http://redhanded.hobix.com/inspect/theRubyGdbArmsRaceNowAtAStandoff.html

J.

···

On 7/12/07, Alex Fenton <aff28@deleteme.cam.ac.uk> wrote:

Hi

I'm working on a C extension and somewhere in itsomething is raising a
NoMethodError. The exception is reported with the line of ruby code that
triggered the bad call in the C extension.

As the C code is large and complex (it's a big SWIG project), I'm having
trouble finding the problem in the C code. I would use gdb or
Microsoft's debugger to look at the stack if it was a C error - but when
a Ruby exception is raised, the process exits and there's no stack to
inspect.

Ruby's debugger isn't helpful because it only knows about ruby written
in ruby.

Is there any way I can get at the C stack at the point of ruby 'raise'
from a C extension?

Thanks
alex

Hi,

i don't know how to build stack traces, but you can start ruby in gdb.

first call gdb with ruby as argument. On liux it looks like:

  det@datengrab:~/Desktop$ gdb /usr/bin/ruby

and then in gdb start your ruby program with "run"

  (gdb) run ./my-prg.rb

Cheers
detlef

···

Am Donnerstag, den 12.07.2007, 23:10 +0900 schrieb Alex Fenton:

Hi

I'm working on a C extension and somewhere in itsomething is raising a
NoMethodError. The exception is reported with the line of ruby code that
triggered the bad call in the C extension.

As the C code is large and complex (it's a big SWIG project), I'm having
trouble finding the problem in the C code. I would use gdb or
Microsoft's debugger to look at the stack if it was a C error - but when
a Ruby exception is raised, the process exits and there's no stack to
inspect.

Ruby's debugger isn't helpful because it only knows about ruby written
in ruby.

Is there any way I can get at the C stack at the point of ruby 'raise'
>from a C extension?

Thanks
alex

cfp:~ > cat core.rb
BEGIN{ at_exit{ Process.kill 'SIGSEGV', Process.pid if $! } }

cfp:~ > cat a.rb
#! /usr/bin/env ruby
require 'core'
p 42
cfp:~ > ruby a.rb
42

cfp:~ > cat b.rb
#! /usr/bin/env ruby
require 'core'
raise

cfp:~ > ruby b.rb
./core.rb:1: [BUG] Segmentation fault
ruby 1.8.6 (2007-03-13) [i686-darwin8.9.1]

Abort trap (core dumped)

-a

···

On Jul 12, 2007, at 8:10 AM, Alex Fenton wrote:

Hi

I'm working on a C extension and somewhere in itsomething is raising a NoMethodError. The exception is reported with the line of ruby code that triggered the bad call in the C extension.

As the C code is large and complex (it's a big SWIG project), I'm having trouble finding the problem in the C code. I would use gdb or Microsoft's debugger to look at the stack if it was a C error - but when a Ruby exception is raised, the process exits and there's no stack to inspect.

Ruby's debugger isn't helpful because it only knows about ruby written in ruby.

Is there any way I can get at the C stack at the point of ruby 'raise' from a C extension?

Thanks
alex

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Jano Svitok wrote:

Is there any way I can get at the C stack at the point of ruby 'raise'
from a C extension?

There was a way how to run ruby under gdb with the ability to debug at
"ruby level" while still having the "C view" at hand.

http://eigenclass.org/hiki.rb?ruby+live+process+introspection
Buckblog: GDB wrapper for Ruby
http://redhanded.hobix.com/inspect/theRubyGdbArmsRaceNowAtAStandoff.html

Thanks for the pointer - that's really interesting stuff. I got round it a bit more prosaically by simply setting a breakpoint in gdb where ruby calls the exception raising class

(gdb) b rb_exc_raise
Breakpoint 1, rb_exc_raise (mesg=3057353380) at eval.c:4583
4583 rb_longjmp(TAG_RAISE, mesg);
(gdb) whe

.... tasty stacktrace

cheers
alex

···

On 7/12/07, Alex Fenton <aff28@deleteme.cam.ac.uk> wrote:

ara.t.howard wrote:

Hi

I'm working on a C extension and somewhere in itsomething is raising a NoMethodError. The exception is reported with the line of ruby code that triggered the bad call in the C extension.

As the C code is large and complex (it's a big SWIG project), I'm having trouble finding the problem in the C code. I would use gdb or Microsoft's debugger to look at the stack if it was a C error - but when a Ruby exception is raised, the process exits and there's no stack to inspect.

Ruby's debugger isn't helpful because it only knows about ruby written in ruby.

Is there any way I can get at the C stack at the point of ruby 'raise' from a C extension?

Thanks
alex

cfp:~ > cat core.rb
BEGIN{ at_exit{ Process.kill 'SIGSEGV', Process.pid if $! } }

cfp:~ > cat a.rb
#! /usr/bin/env ruby
require 'core'
p 42
cfp:~ > ruby a.rb
42

cfp:~ > cat b.rb
#! /usr/bin/env ruby
require 'core'
raise

cfp:~ > ruby b.rb
./core.rb:1: [BUG] Segmentation fault
ruby 1.8.6 (2007-03-13) [i686-darwin8.9.1]

Abort trap (core dumped)

Doesn't that only give you the C stack at the time the ruby process exits, not at the time the exception is raised?

···

On Jul 12, 2007, at 8:10 AM, Alex Fenton wrote:

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

yeah - it's a short leap though...

-a

···

On Jul 12, 2007, at 4:25 PM, Joel VanderWerf wrote:

Doesn't that only give you the C stack at the time the ruby process exits, not at the time the exception is raised?

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama