Project

General

Profile

Bug #15911

Missing TracePoint return event for ||=

Added by cfis (Charlie Savage) about 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
[ruby-core:93039]

Description

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


Related issues

Related to Ruby master - Bug #15578: Missing TracePoint return event when a conditional is used before a rescueClosedActions

Also available in: Atom PDF