Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a stack trace object in Ruby?

I need to get a stack trace object in Ruby; not to print it, just to get it to do some recording and dumping for later analysis. Is that possible? How?

like image 461
pupeno Avatar asked Sep 30 '10 09:09

pupeno


People also ask

How do I get a stack trace?

You can obtain a stack trace from a thread – by calling the getStackTrace method on that Thread instance. This invocation returns an array of StackTraceElement, from which details about stack frames of the thread can be extracted.

What is backtrace in Ruby?

This blog is part of our Ruby 2.5 series. Stack trace or backtrace is a sequential representation of the stack of method calls in a program which gets printed when an exception is raised. It is often used to find out the exact location in a program from where the exception was raised.

What is stack trace in rails?

Stack trace or backtrace is a representation of the call stack at any point of time while running the program. Stack trace will be printed when an exception is raised. So let's raise an error with a few method calls to understand it.

What is a call stack trace?

a call stack is a stack data structure that stores information about the active subroutines of a computer program. A stack trace is a report of the active stack frames at a certain point in time during the execution of a program.


4 Answers

You can use Kernel.caller for this. The same method is used when generating stack traces for exceptions.

From the docs:

def a(skip)   caller(skip) end def b(skip)   a(skip) end def c(skip)   b(skip) end c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"] c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"] c(2) #=> ["prog:8:in `c'", "prog:12"] c(3) #=> ["prog:13"] 
like image 189
Sven Koschnicke Avatar answered Nov 15 '22 23:11

Sven Koschnicke


Try

Thread.current.backtrace.join("\n") 
like image 25
Alex Bondar Avatar answered Nov 16 '22 00:11

Alex Bondar


Try error.backtrace:

# Returns any backtrace associated with the exception.  
# The backtrace is an array of strings, each containing either ``filename:lineNo: in `method’’’ or ``filename:lineNo.’‘

def a
  raise "boom"
end

def b
  a()
end

begin
  b()
rescue => detail
  print detail.backtrace.join("\n")
end

produces:

prog.rb:2:in `a'
prog.rb:6:in `b'
prog.rb:10
like image 36
Nikita Rybak Avatar answered Nov 16 '22 01:11

Nikita Rybak


For Ruby 2.0+, you can use Kernel#caller_locations. It is essentially the same as Kernel#caller (covered in Sven Koschnicke's answer), except that instead of returning an array of strings, it returns an array of Thread::Backtrace::Location objects. Thread::Backtrace::Location provides methods such as path, lineno, and base_label, which may be useful when you need access to specific details about the stack trace, and not just a raw string.

From the docs:

caller_locations(start=1, length=nil) → array or nil

caller_locations(range) → array or nil

Returns the current execution stack—an array containing backtrace location objects.

See Thread::Backtrace::Location for more information.

The optional start parameter determines the number of initial stack entries to omit from the top of the stack.

A second optional length parameter can be used to limit how many entries are returned from the stack.

Returns nil if start is greater than the size of current execution stack.

Optionally you can pass a range, which will return an array containing the entries within the specified range.

Usage example:

def a
  caller_locations(0)
end
def b
  a
end
def c
  b
end

c.map(&:base_label)
#=> ["a", "b", "c", "<main>"]
like image 21
Ajedi32 Avatar answered Nov 16 '22 01:11

Ajedi32