Skip to content

Commit dea10b5

Browse files
st0012ko1
authored andcommitted
Allow TracePoint reentry during DAP's evaluation
This avoids the TracePoint conflict with Zeitwerk, which was reported in #408
1 parent 4e70b17 commit dea10b5

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

lib/debug/server_dap.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,9 @@ def value_inspect obj, short: true
788788

789789
def dap_eval b, expr, _context, prompt: '(repl_eval)'
790790
begin
791-
b.eval(expr.to_s, prompt)
791+
tp_allow_reentry do
792+
b.eval(expr.to_s, prompt)
793+
end
792794
rescue Exception => e
793795
e
794796
end

test/protocol/break_test.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,56 @@ def test_break_stops_at_the_extra_file
8383
end
8484
end
8585
end
86+
87+
class NestedBreakTest < ProtocolTestCase
88+
PROGRAM = <<~RUBY
89+
1| def foo(x)
90+
2| x
91+
3| end
92+
4|
93+
5| foo("foo")
94+
RUBY
95+
96+
def test_breakpoint_can_be_triggered_inside_suspenssion
97+
run_protocol_scenario PROGRAM, cdp: false do
98+
req_add_breakpoint 2
99+
req_continue
100+
assert_line_num 2
101+
102+
assert_locals_result(
103+
[
104+
{ name: "%self", value: "main", type: "Object" },
105+
{ name: "x", value: "foo", type: "String" },
106+
]
107+
)
108+
109+
# Only if TracePoint.allow_reentry is available, we can trigger TracePoint events
110+
# inside another TracePoint event, which is essential for nested breakpoints.
111+
if TracePoint.respond_to? :allow_reentry
112+
evaluate("foo('bar')")
113+
114+
assert_line_num 2
115+
assert_locals_result(
116+
[
117+
{ name: "%self", value: "main", type: "Object" },
118+
{ name: "x", value: "bar", type: "String" },
119+
]
120+
)
121+
end
122+
123+
req_terminate_debuggee
124+
end
125+
end
126+
127+
private
128+
129+
def evaluate(expression)
130+
res = send_dap_request 'stackTrace',
131+
threadId: 1,
132+
startFrame: 0,
133+
levels: 20
134+
f_id = res.dig(:body, :stackFrames, 0, :id)
135+
send_request 'evaluate', expression: expression, frameId: f_id, context: "repl"
136+
end
137+
end
86138
end

0 commit comments

Comments
 (0)