Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use flag instead of caller for debug's binding.irb check #947

Merged
merged 1 commit into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions lib/irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -931,8 +931,11 @@ class Irb
# The lexer used by this irb session
attr_accessor :scanner

attr_reader :from_binding

# Creates a new irb session
def initialize(workspace = nil, input_method = nil)
def initialize(workspace = nil, input_method = nil, from_binding: false)
@from_binding = from_binding
@context = Context.new(self, workspace, input_method)
@context.workspace.load_helper_methods_to_main
@signal_status = :IN_IRB
Expand Down Expand Up @@ -1596,7 +1599,7 @@ def irb(show_code: true)
else
# If we're not in a debugger session, create a new IRB instance with the current
# workspace
binding_irb = IRB::Irb.new(workspace)
binding_irb = IRB::Irb.new(workspace, from_binding: true)
binding_irb.context.irb_path = irb_path
binding_irb.run(IRB.conf)
binding_irb.debug_break
Expand Down
17 changes: 1 addition & 16 deletions lib/irb/command/debug.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ class Debug < Base
category "Debugging"
description "Start the debugger of debug.gem."

BINDING_IRB_FRAME_REGEXPS = [
'<internal:prelude>',
binding.method(:irb).source_location.first,
].map { |file| /\A#{Regexp.escape(file)}:\d+:in (`|'Binding#)irb'\z/ }

def execute(_arg)
execute_debug_command
end
Expand All @@ -36,7 +31,7 @@ def execute_debug_command(pre_cmds: nil, do_cmds: nil)
# 3. Insert a debug breakpoint at `Irb#debug_break` with the intended command.
# 4. Exit the current Irb#run call via `throw :IRB_EXIT`.
# 5. `Irb#debug_break` will be called and trigger the breakpoint, which will run the intended command.
unless binding_irb?
unless irb_context.from_binding?
puts "Debugging commands are only available when IRB is started with binding.irb"
return
end
Expand All @@ -60,16 +55,6 @@ def execute_debug_command(pre_cmds: nil, do_cmds: nil)
throw :IRB_EXIT
end
end

private

def binding_irb?
caller.any? do |frame|
BINDING_IRB_FRAME_REGEXPS.any? do |regexp|
frame.match?(regexp)
end
end
end
end

class DebugCommand < Debug
Expand Down
4 changes: 4 additions & 0 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,10 @@ def evaluate(statement, line_no) # :nodoc:
nil
end

def from_binding?
@irb.from_binding
end

def evaluate_expression(code, line_no) # :nodoc:
result = nil
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
Expand Down
16 changes: 16 additions & 0 deletions test/irb/test_debugger_integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ def test_debug_command_only_runs_once
assert_match(/IRB is already running with a debug session/, output)
end

def test_debug_command_can_only_be_called_from_binding_irb
write_ruby <<~'ruby'
require "irb"
# trick test framework
puts "binding.irb"
IRB.start
ruby

output = run_ruby_file do
type "debug"
type "exit"
end

assert_include(output, "Debugging commands are only available when IRB is started with binding.irb")
end

def test_next
write_ruby <<~'ruby'
binding.irb
Expand Down
Loading