Skip to content

Disable canceled step/next/finish #784

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

Merged
merged 1 commit into from
Nov 1, 2022
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
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