TracePoint.allow_reentry
# File tmp/rubies/ruby-4.0.0/trace_point.rb, line 200
def self.allow_reentry
Primitive.attr! :use_block
Primitive.tracepoint_allow_reentry
end
Generally, while a TracePoint callback is running, other registered callbacks are not called to avoid confusion from reentrance. This method allows reentrance within a given block. Use this method carefully to avoid infinite callback invocation.
If called when reentrance is already allowed, it raises a RuntimeError.
Example:
# Without reentry # --------------- line_handler = TracePoint.new(:line) do |tp| next if tp.path != __FILE__ # Only works in this file puts "Line handler" binding.eval("class C; end") end.enable class_handler = TracePoint.new(:class) do |tp| puts "Class handler" end.enable class B end # This script will print "Class handler" only once: when inside the :line # handler, all other handlers are ignored. # With reentry # ------------ line_handler = TracePoint.new(:line) do |tp| next if tp.path != __FILE__ # Only works in this file next if (__LINE__..__LINE__+3).cover?(tp.lineno) # Prevent infinite calls puts "Line handler" TracePoint.allow_reentry { binding.eval("class C; end") } end.enable class_handler = TracePoint.new(:class) do |tp| puts "Class handler" end.enable class B end # This will print "Class handler" twice: inside the allow_reentry block in the :line # handler, other handlers are enabled.
Note that the example shows the principal effect of the method, but its practical usage is for debugging libraries that sometimes require other libraries’ hooks to not be affected by the debugger being inside trace point handling. Precautions should be taken against infinite recursion in this case (note that we needed to filter out calls by itself from the :line handler, otherwise it would call itself infinitely).
Ruby version changes
-
3.1
-
TracePoint.allow_reentryis added to allow reenter whileTracePointcallback. [Feature #15912]
-