Project

General

Profile

Bug #15911

Updated by cfis (Charlie Savage) almost 5 years ago

While updating ruby-prof, I ran into an issue while profiling rails that caused ruby-prof to show an incorrect method invocation tree. This is caused by the use of the ||= operator in minitest. 

 Here is a small test case: 

 ``` 
 class Operators 
   def self.should_be_called_by_test 
   end 

   def self.test 
     self.a 
     should_be_called_by_test 
   end 

   def self.b=(value) 
   end 

   def self.b 
   end 

   def self.a 
     self.b ||= :random 
   end 
 end 

 tp = TracePoint.new(:call, :c_call, :return, :c_return) do |event| 
   p [event.event, event.method_id] 
 end 

 tp.enable do 
   Operators.test 
 end 
 ``` 

 This is the result: 

 ``` 
 [:call, :test] 
 [:call, :a] 
 [:call, :b] 
 [:return, :b] 
 [:call, :b=] 
 [:return, :b=] 
                                     <---------- Missing [:return, :a] 
 [:call, :should_be_called_by_test] 
 [:return, :should_be_called_by_test] 
 [:return, :test] 

 ``` 
 Notice there is a missing :return event for the :a method. From my experiments, ||= works if the left hand side is not a method call (say @b ||=1) but fails if it is. 

 Note this works correctly on the latest version of ruby 2.5    - ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-darwin18]. 

 The minitest code which this bug is triggered by: 

 ``` 
 module ActiveSupport 
   class TestCase < ::Minitest::Test 
     Assertion = Minitest::Assertion 

     class << self 
       def test_order=(new_order) 
         ActiveSupport.test_order = new_order 
       end 

       def test_order 
         ActiveSupport.test_order ||= :random 
       end 
     end 
   end 
 end 

 ```

Back