😎
[Bug #21298] TracePointでObjectSpace.allocation_class_pathの挙動が変わるバグ報告
[Bug #21298] ObjectSpace.allocation_class_path returns inconsistent results depending on TracePoint state
-
ObjectSpace.trace_object_allocationsを利用すると次のように『対象のオブジェクトがどこで生成されたのか』の情報がトレースされて取得できる
# test.rb
require "objspace"
class Foo
def test
"hoge"
end
end
ObjectSpace.trace_object_allocations do
obj = Foo.new.test
# obj が生成されたファイル名
pp ObjectSpace.allocation_sourcefile(obj) # => "/path/to/test.rb"
# obj が生成された行番号
pp ObjectSpace.allocation_sourceline(obj) # => 5
# obj が生成されたクラス
pp ObjectSpace.allocation_class_path(obj) # => "Foo"
end
- このチケットは『
objが生成されたクラス』を取得するObjectSpace.allocation_class_pathに関するチケット - この
ObjectSpace.allocation_class_pathなんですがClass#newでオブジェクトを生成した場合に『そのClass#newでオブジェクトを生成した』という実装に依存しており次のようにClassを返すような挙動になっていた
require "objspace"
class Hoge
end
class Foo
def test
Hoge.new
end
end
ObjectSpace.trace_object_allocations do
obj = Foo.new.test
# Foo 内でオブジェクトを生成はしているが実際には Class#new 内で生成していることになる
pp ObjectSpace.allocation_class_path(obj)
# => "Class"
end
- これが開発版の Ruby 3.5-dev では『
Class#newから呼び出すフレームがなくなった』影響でFooを返すようになった- これは最適化の影響を受けているらしい
require "objspace"
class Hoge
end
class Foo
def test
Hoge.new
end
end
ObjectSpace.trace_object_allocations do
obj = Foo.new.test
# Ruby 3.5-dev では Foo を返す
pp ObjectSpace.allocation_class_path(obj)
# => "Foo"
end
- これが
TracePointを有効にすると『最適化が無効になる』ので『Ruby 3.4 の挙動に戻ってしまう』というのがこのチケットで指摘されている内容になる- 以下のように
TracePointが無効か有効かで実行結果が変わってしまう
- 以下のように
require "objspace"
class Hoge
end
class Foo
def test
Hoge.new
end
end
ObjectSpace.trace_object_allocations do
# TracePoint が無効な場合は Foo を返す
obj = Foo.new.test
pp ObjectSpace.allocation_class_path(obj)
# => "Foo"
# TracePoint が有効な場合は Class を返す
TracePoint.new {}.enable do
obj = Foo.new.test
pp ObjectSpace.allocation_class_path(obj)
# => "Class"
end
end
-
TracePointを利用している coverage を有効にしているとこれに依存しているテストが落ちてしまっていて困っているみたいですね -
2025-07-07T10:44:21Z master 482f4cad82時点では開発版の Ruby 3.5-dev では『TracePointが有効でもFooを返す』ような対応がされている - ちなみに互換性の問題でいうと非互換になってしまうんですが新しい挙動のほうが直感的で便利ということでこのチケットではそこまで言及はされていないですね
- ただし、これの影響で
power_assertのテストが落ちてしまった事象もあったので何かしら影響があるかもしれない
- ただし、これの影響で
Discussion