mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Move to tool/lib from test/lib.
This commit is contained in:
parent
142617c8e1
commit
c3c0e3f5c9
22 changed files with 7 additions and 6 deletions
126
tool/lib/tracepointchecker.rb
Normal file
126
tool/lib/tracepointchecker.rb
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
# frozen_string_literal: true
|
||||
module TracePointChecker
|
||||
STATE = {
|
||||
count: 0,
|
||||
running: false,
|
||||
}
|
||||
|
||||
module ZombieTraceHunter
|
||||
def tracepoint_capture_stat_get
|
||||
TracePoint.stat.map{|k, (activated, deleted)|
|
||||
deleted = 0 unless @tracepoint_captured_singlethread
|
||||
[k, activated, deleted]
|
||||
}
|
||||
end
|
||||
|
||||
def before_setup
|
||||
@tracepoint_captured_singlethread = (Thread.list.size == 1)
|
||||
@tracepoint_captured_stat = tracepoint_capture_stat_get()
|
||||
super
|
||||
end
|
||||
|
||||
def after_teardown
|
||||
super
|
||||
|
||||
# detect zombie traces.
|
||||
assert_equal(
|
||||
@tracepoint_captured_stat,
|
||||
tracepoint_capture_stat_get(),
|
||||
"The number of active/deleted trace events was changed"
|
||||
)
|
||||
# puts "TracePoint - deleted: #{deleted}" if deleted > 0
|
||||
|
||||
TracePointChecker.check if STATE[:running]
|
||||
end
|
||||
end
|
||||
|
||||
MAIN_THREAD = Thread.current
|
||||
TRACES = []
|
||||
|
||||
def self.prefix event
|
||||
case event
|
||||
when :call, :return
|
||||
:n
|
||||
when :c_call, :c_return
|
||||
:c
|
||||
when :b_call, :b_return
|
||||
:b
|
||||
end
|
||||
end
|
||||
|
||||
def self.clear_call_stack
|
||||
Thread.current[:call_stack] = []
|
||||
end
|
||||
|
||||
def self.call_stack
|
||||
stack = Thread.current[:call_stack]
|
||||
stack = clear_call_stack unless stack
|
||||
stack
|
||||
end
|
||||
|
||||
def self.verbose_out label, method
|
||||
puts label => call_stack, :count => STATE[:count], :method => method
|
||||
end
|
||||
|
||||
def self.method_label tp
|
||||
"#{prefix(tp.event)}##{tp.method_id}"
|
||||
end
|
||||
|
||||
def self.start verbose: false, stop_at_failure: false
|
||||
call_events = %i(a_call)
|
||||
return_events = %i(a_return)
|
||||
clear_call_stack
|
||||
|
||||
STATE[:running] = true
|
||||
|
||||
TRACES << TracePoint.new(*call_events){|tp|
|
||||
next if Thread.current != MAIN_THREAD
|
||||
|
||||
method = method_label(tp)
|
||||
call_stack.push method
|
||||
STATE[:count] += 1
|
||||
|
||||
verbose_out :psuh, method if verbose
|
||||
}
|
||||
|
||||
TRACES << TracePoint.new(*return_events){|tp|
|
||||
next if Thread.current != MAIN_THREAD
|
||||
STATE[:count] += 1
|
||||
|
||||
method = "#{prefix(tp.event)}##{tp.method_id}"
|
||||
verbose_out :pop1, method if verbose
|
||||
|
||||
stored_method = call_stack.pop
|
||||
next if stored_method.nil?
|
||||
|
||||
verbose_out :pop2, method if verbose
|
||||
|
||||
if stored_method != method
|
||||
stop if stop_at_failure
|
||||
RubyVM::SDR() if defined? RubyVM::SDR()
|
||||
call_stack.clear
|
||||
raise "#{stored_method} is expected, but #{method} (count: #{STATE[:count]})"
|
||||
end
|
||||
}
|
||||
|
||||
TRACES.each{|trace| trace.enable}
|
||||
end
|
||||
|
||||
def self.stop
|
||||
STATE[:running] = true
|
||||
TRACES.each{|trace| trace.disable}
|
||||
TRACES.clear
|
||||
end
|
||||
|
||||
def self.check
|
||||
TRACES.each{|trace|
|
||||
raise "trace #{trace} should not be deactivated" unless trace.enabled?
|
||||
}
|
||||
end
|
||||
end if defined?(TracePoint.stat)
|
||||
|
||||
class ::Test::Unit::TestCase
|
||||
include TracePointChecker::ZombieTraceHunter
|
||||
end if defined?(TracePointChecker)
|
||||
|
||||
# TracePointChecker.start verbose: false
|
||||
Loading…
Add table
Add a link
Reference in a new issue