debug icon indicating copy to clipboard operation
debug copied to clipboard

Basic Object crashes record

Open pointlessone opened this issue 5 months ago • 0 comments

Your environment

  • ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-darwin24]
  • rdbg -v: rdbg 1.11.0

Describe the bug

Recording can't handle BasicObject. It crashes whenever execution enters any method in a BasicObject or its descendants.

To Reproduce

Here's a simple script that demonstrates the issue.

class Test < BasicObject
  def test
    42
  end
end

Test.new.test

Load it into rbdg, enable recording (record on) and run it (continue).

Expected behavior

Should record execution without issues.

Additional context

The exception backtrace:

(eval at /Users/pointlessone/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.11.0/lib/debug/thread_client.rb:1313):1:in 'Test#test': undefined local variable or method '__callee__' for an instance of Test (NameError)
	from /Users/pointlessone/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.11.0/lib/debug/thread_client.rb:1313:in 'Binding#eval'
	from /Users/pointlessone/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.11.0/lib/debug/thread_client.rb:1313:in 'block (2 levels) in DEBUGGER__::ThreadClient::Recorder#initialize'
	from /Users/pointlessone/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.11.0/lib/debug/thread_client.rb:1307:in 'Array#each'
	from /Users/pointlessone/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.11.0/lib/debug/thread_client.rb:1307:in 'block in DEBUGGER__::ThreadClient::Recorder#initialize'
	from test.rb:3:in 'Test#test'
	from test.rb:7:in '<main>'

It looks like [ThreadClient][https://github.com/ruby/debug/blob/14c8a546242a5e88ed8f47607629ffbef7d3315d/lib/debug/thread_client.rb#L1313] is trying to execute __callee__ within the frame. The method is defined in Kernel which is not included in BasicObject.

It seems simply calling the method directly on the Kernel might fix it.

-              frame._callee = b.eval('__callee__')
+              frame._callee = b.eval('::Kernel.__callee__')

pointlessone avatar Aug 08 '25 07:08 pointlessone