Here’s a program that demonstrates some unhelpful output:
def countdown(n)
if n == 0
raise Exception.new
else
countdown(n-1)
end
end
a = Thread.new { countdown(5) }
begin
a.join
rescue Exception => ex
print “#{ex}\n"
print ex.backtrace.join(”\n")
print "\n"
end
The backtrace I see looks like this:
Exception
bt:3:in countdown' bt:12:in
join’
bt:12
Problem is that only the first line of the backtrace belongs to the thread
which threw the exception (whereas I should see 5 nested calls to
’countdown’). I’m trying to weed out an exception in a multithreaded
application and one line of backtrace isn’t enough; is there any way of
getting hold of the thread’s full backtrace?
···
–
Matthew
Matthew Bloch wrote:
Here’s a program that demonstrates some unhelpful output:
def countdown(n)
if n == 0
raise Exception.new
else
countdown(n-1)
end
end
a = Thread.new { countdown(5) }
begin
a.join
rescue Exception => ex
print “#{ex}\n”
print ex.backtrace.join(“\n”)
print “\n”
end
The backtrace I see looks like this:
Exception
bt:3:in countdown' bt:12:in
join’
bt:12
Problem is that only the first line of the backtrace belongs to the thread
which threw the exception (whereas I should see 5 nested calls to
‘countdown’). I’m trying to weed out an exception in a multithreaded
application and one line of backtrace isn’t enough; is there any way of
getting hold of the thread’s full backtrace?
Has anyone got a better solution than overriding Thread and using this kind
of setup?
class EThread < Thread
def initialize(*args)
super(*args) do |a|
begin
yield(*a)
rescue Exception => e
# deal with exception here, not outside
···
Log.error "thread #{self} exception '#{e.type} : #{e.message}'"
Log.backtrace(e)
raise
end
end
end
end
–
Matthew