Skip to content

Commit

Permalink
Disable canceled step/next/finish
Browse files Browse the repository at this point in the history
When `next` command canceled with other breaks, for example, stop
at a breakpoint while executing `next` command, the `next` command
should be canceled and it should not stop on the next line.

However, the current implementation left the TracePoint object for
step commands, so it should be disabled.
  • Loading branch information
ko1 committed Nov 1, 2022
1 parent eeb5bb6 commit 9eb5e3e
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 5 deletions.
14 changes: 11 additions & 3 deletions lib/debug/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ module DEBUGGER__
class PostmortemError < RuntimeError; end

class Session
attr_reader :intercepted_sigint_cmd, :process_group
attr_reader :intercepted_sigint_cmd, :process_group, :subsession_id

include Color

Expand All @@ -116,6 +116,7 @@ def initialize
@intercepted_sigint_cmd = 'DEFAULT'
@process_group = ProcessGroup.new
@subsession_stack = []
@subsession_id = 0

@frame_map = {} # for DAP: {id => [threadId, frame_depth]} and CDP: {id => frame_depth}
@var_map = {1 => [:globals], } # {id => ...} for DAP
Expand All @@ -138,8 +139,14 @@ def active?
!@q_evt.closed?
end

def break_at? file, line
@bps.has_key? [file, line]
def stop_stepping? file, line, subsession_id
if @bps.has_key? [file, line]
true
elsif @subsession_id != subsession_id
true
else
false
end
end

def activate ui = nil, on_fork: false
Expand Down Expand Up @@ -1571,6 +1578,7 @@ def get_thread_client th = Thread.current
end

private def enter_subsession
@subsession_id += 1
if !@subsession_stack.empty?
DEBUGGER__.info "Enter subsession (nested #{@subsession_stack.size})"
else
Expand Down
11 changes: 9 additions & 2 deletions lib/debug/thread_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,14 @@ def step_tp iter, events = [:line, :b_return, :return]
@step_tp.disable if @step_tp

thread = Thread.current
subsession_id = SESSION.subsession_id

if SUPPORT_TARGET_THREAD
@step_tp = TracePoint.new(*events){|tp|
next if SESSION.break_at? tp.path, tp.lineno
if SESSION.stop_stepping? tp.path, tp.lineno, subsession_id
tp.disable
next
end
next if !yield(tp.event)
next if tp.path.start_with?(__dir__)
next if tp.path.start_with?('<internal:trace_point>')
Expand All @@ -347,7 +351,10 @@ def step_tp iter, events = [:line, :b_return, :return]
else
@step_tp = TracePoint.new(*events){|tp|
next if thread != Thread.current
next if SESSION.break_at? tp.path, tp.lineno
if SESSION.stop_stepping? tp.path, tp.lineno, subsession_id
tp.disable
next
end
next if !yield(tp.event)
next if tp.path.start_with?(__dir__)
next if tp.path.start_with?('<internal:trace_point>')
Expand Down
46 changes: 46 additions & 0 deletions test/console/control_flow_commands_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -358,4 +358,50 @@ def test_next_steps_over_rescue_when_raising_from_method
end
end
end

class CancelStepTest < ConsoleTestCase
def program
<<~RUBY
1| def foo m
2| __send__ m
3| end
4| def bar
5| a = :bar1
6| b = :bar2
7| c = :bar3
8| end
9|
10| def baz
11| :baz
12| end
13| foo :bar
14| foo :baz
15| foo :baz
RUBY
end

def test_next_should_be_canceled
debug_code program do
type 'b 13'
type 'b Object#bar'
type 'c'
assert_line_num 13
type 'n'
assert_line_num 5
type 'c'
end
end

def test_finish_should_be_canceled
debug_code program do
type 'b 5'
type 'b 6'
type 'c'
assert_line_num 5
type 'finish'
assert_line_num 6
type 'c'
end
end
end
end

0 comments on commit 9eb5e3e

Please sign in to comment.