threads/interrupted_backtraces.rb
tests/_examples/threads/interrupted_backtraces.rb in the metorex repository.
# An exception handed to a sleeping thread is raised where it sleeps, so its
# backtrace starts at `Kernel#sleep`, and a thread's block is named by how
# many blocks deep it was written.
def short(lines)
lines.map { |line| line.sub(/\A.*\//, "") }
end
[1].each do
sleeper = Thread.new do
Thread.current.report_on_exception = false
sleep
end
Thread.pass until sleeper.stop?
sleeper.raise "wake up"
begin
sleeper.join
rescue => woken
p short(woken.backtrace)
end
end
# A backtrace the exception was given, or one it was raised with before, is
# the one it keeps.
given = StandardError.new "given"
given.set_backtrace ["somewhere:1"]
begin
raise given
rescue => kept
p kept.backtrace
end
# `\#` in a regex stays an escaped `#`, interpolation or not, so extended
# mode reads it as a character rather than the start of a comment.
number = 1
p(/a\##{number}/x.source)
p(/a\##{number}/x.match?("a#1"))
# The file a fiber's code runs from is its own, so `__FILE__` reads the same
# after a thread written elsewhere has run.
before = __FILE__
Thread.new { :other }.join
p __FILE__ == before
Output:
["interrupted_backtraces.rb:11:in 'Kernel#sleep'", "interrupted_backtraces.rb:11:in 'block (2 levels) in <main>'"]
["somewhere:1"]
"a\\#1"
true
true