Project

General

Profile

Bug #18730

Updated by hurricup (Alexandr Evstigneev) over 2 years ago

I'm not sure if this is a bug or intentional behavior, but feels a bit unexpected. Ruby 3.0.x, 3.1.x affected. 

 Here is the script demonstrating the issue: 
 ``` 
 def bar 
   42 #bp here 
 end 

 tp_line = TracePoint.new(:line) do |tp0| 
   puts "Got line event from #{tp0.path}:#{tp0.lineno}" 

   tp_multi1 = TracePoint.new(:return, :b_return, :line) do |tp| 
     if tp.lineno == 3 
       puts "Got first return `#{tp.event}` from #{tp.path}:#{tp.lineno}" 
       tp.disable 
       # tp0.disable # uncommenting this line changes things to the more expected  


       

       tp_multi2 = TracePoint.new(:return, :b_return, :line) do |tps| 
         puts "Got second return `#{tps.event}` from #{tps.path}:#{tps.lineno}" 
       end 
       tp_multi2.enable(target: RubyVM::InstructionSequence.of(method :bar)) 
     end 
   end 
   tp_multi1.enable 
 end 

 tp_line.enable(target: RubyVM::InstructionSequence.of(method :bar)) 

 bar 
 ``` 
 1. We set a line TP to the `bar` method `iseq` (consider it a line breakpoint) 
 2. When line event is triggered we setting another untargeted tracepoint for the same method, to catch `line`, `return` and `b_return` events (consider it attempt to step into something) 
 3. When return event of the `bar` method is triggered, we disabling second tracepoint and setting another one, targeted to the same method and multiple events. 

 Output i get: 
 ``` 
 Got line event from /home/hurricup/test.rb:2 
 Got first return `return` from /home/hurricup/test.rb:3 
 Got second return `return` from /home/hurricup/test.rb:3 
 ``` 
 The questions are:  
 1. question is: why return triggered on the second tracepoint, when we already handeled it? 
 2. why disabling line tracepoint changes behavior? 

Back