"Verbose" backtracing

  • Thread starter Imobach González Sosa
  • Start date
I

Imobach González Sosa

Hi all,

We're interested in doing some backtracing in our code, but not just
the "filename:line in method" thing, we'd like to retrieve the status
of each object referenced.

For example, we have three objects A, B and C. A calls a B's method
and B calls an C's method. That's ok. But the C methods raises and
exception. At A, we could get a backtrace containing files, lines and
methods called. But, what about some extra info as, for example, B
status?

We've implemented such a thing using begin-end-rescue in all those
called methods, so in the rescue they do some extra work to register
the status. Ok?

But write a lot of methods with begin-end-rescue could be painful, at
least for me.

Does anybody understand me? ;-) Any idea about it?

Sorry if the question sounds stupid :p

Thank you all in advance.
 
F

Florian Groß

Imobach said:
We're interested in doing some backtracing in our code, but not just
the "filename:line in method" thing, we'd like to retrieve the status
of each object referenced.

This has already been suggested before, but oddly I was not able to find
an RCR for it. The mention I was talking about:

http://pezra.barelyenough.org/blog/2005/04/ruby-backtraces/

I think this would indeed be a nice idea and its implications (what
about complex Object graphs as arguments that would generate really long
inspect representations? Should .to_s be used instead?) should IMHO be
discussed. Submitting an RCR at http://www.rcrchive.net/ would be a nice
way of achieving just that, I think.
 
P

Paul Brannan

If you are using a ruby later than 1.8 and you only need to know the
state of objects when an exception is raised, you could do something
like this:

class Exception
alias_method :eek:ld_init, :initialize

attr_reader :state

def initialize(*args)
old_init(*args)
@state = STATE_OBJS.map { |obj| obj.dup }
end

STATE_OBJS = []
end

def foo
bar
end

def bar
raise "testing!"
end

obj1 = [ 1, 2, 3 ]
obj2 = "foo"
Exception::STATE_OBJS << obj1
Exception::STATE_OBJS << obj2

begin
foo()
rescue => exc
p exc.state #=> [[1, 2, 3], "foo"]
end

Paul
 
R

Robert Klemme

Imobach said:
Hi all,

We're interested in doing some backtracing in our code, but not just
the "filename:line in method" thing, we'd like to retrieve the status
of each object referenced.

For example, we have three objects A, B and C. A calls a B's method
and B calls an C's method. That's ok. But the C methods raises and
exception. At A, we could get a backtrace containing files, lines and
methods called. But, what about some extra info as, for example, B
status?

We've implemented such a thing using begin-end-rescue in all those
called methods, so in the rescue they do some extra work to register
the status. Ok?

But write a lot of methods with begin-end-rescue could be painful, at
least for me.

Yes, this *is* painful.
Does anybody understand me? ;-) Any idea about it?

Sorry if the question sounds stupid :p

Not at all. I'd have a look at set_trace_func:
http://www.ruby-doc.org/core/classes/Kernel.html#M001743

You have bindings available that contain the current value of "self".
Here's a very small example:

09:24:36 [4.5_Versions]: ruby <<EOF
def foo(s)
puts s.length
end
set_trace_func proc { |event, file, line, id, binding, classname|
printf "%20s %s\n", event, eval("self",binding).inspect
}
foo "hello"
EOF
line main
call main
line main
c-call "hello"
c-return "hello"
c-call main
c-call 5
c-return 5
c-call 5
c-return 5
c-call #<IO:0x100ede40>
5 c-return #<IO:0x100ede40>
c-call #<IO:0x100ede40>

c-return #<IO:0x100ede40>
c-return main
return main
09:24:53 [4.5_Versions]:

You can instrument all call and return events to store self on a stack and
retrieve those values in case of an exception.

Kind regards

robert
 
S

Stephen Kellett

If you are using Windows and would like a tool to flow trace your code
you may want to look at Ruby Bug Validator. Tracks params and local
variables, as well as function calls, line visits, exceptions...

http://www.softwareverify.com

Stephen
 
M

Mark Hubbart

Hi,

Hi all,
=20
We're interested in doing some backtracing in our code, but not just
the "filename:line in method" thing, we'd like to retrieve the status
of each object referenced.
=20
For example, we have three objects A, B and C. A calls a B's method
and B calls an C's method. That's ok. But the C methods raises and
exception. At A, we could get a backtrace containing files, lines and
methods called. But, what about some extra info as, for example, B
status?
=20
We've implemented such a thing using begin-end-rescue in all those
called methods, so in the rescue they do some extra work to register
the status. Ok?
=20
But write a lot of methods with begin-end-rescue could be painful, at
least for me.

Until a better solution comes up, you could simplify it by creating a modu=
le:
-----

module DebugWrappable
def debug_wrap(*names)
names.each{|name| eval <<-END }
alias_method :___#{name}, :#{name}
def #{name}(*args, &block)
begin
___#{name}(*args, &block)
rescue Exception =3D> e
unless e.respond_to? :environments
class << e; e.attr_accessor :environments; end
end
e.environments ||=3D []
e.environments << [binding, self]
raise e
end
end
END
end
end

class A
def foo
# do stuff
end
def Bar
# do more stuff
end
include DebugWrappable
debug_wrap :foo, :bar
end

-----

Okay, I haven't actually tried this code, so there are probably bugs.
But the idea is sound.

cheers,
Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,474
Latest member
AntoniaDea

Latest Threads

Top