"Verbose" backtracing

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? :wink: Any idea about it?

Sorry if the question sounds stupid :stuck_out_tongue:

Thank you all in advance.

···

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

Imobach González Sosa wrote:

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.

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

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? :wink: Any idea about it?

Sorry if the question sounds stupid :stuck_out_tongue:

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

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

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.softwareverify.com

Stephen

···

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