[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

"Verbose" backtracing

Imobach González Sosa

5/17/2005 4:40:00 PM

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.

--
Imobach González Sosa
imobachgs at gmail dot com
osoh at jabberes dot org


5 Answers

Florian Groß

5/17/2005 6:55:00 PM

0

Paul Brannan

5/17/2005 8:37:00 PM

0

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 :old_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




Robert Klemme

5/18/2005 7:27:00 AM

0

Imobach González Sosa wrote:
> 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.ht...

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

Stephen Kellett

5/18/2005 12:15:00 PM

0

>Imobach González Sosa wrote:
>> 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.

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.software...

Stephen
--
Stephen Kellett
Object Media Limited
Computer Consultancy, Software Development
Windows C++, Java, Assembler, Performance Analysis, Troubleshooting

Mark Hubbart

5/18/2005 4:39:00 PM

0

Hi,

On 5/17/05, Imobach González Sosa <imobachgs@gmail.com> wrote:
> 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.

Until a better solution comes up, you could simplify it by creating a module:
-----

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 => e
unless e.respond_to? :environments
class << e; e.attr_accessor :environments; end
end
e.environments ||= []
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