Skip to content

Commit 8fd5574

Browse files
committed
Ensure that "s" steps through wrappers
1 parent 608aea9 commit 8fd5574

File tree

2 files changed

+58
-22
lines changed

2 files changed

+58
-22
lines changed

src/commands.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ function maybe_step_through_wrapper!(@nospecialize(recurse), frame::Frame)
227227
length(stmts) < 2 && return frame
228228
last = stmts[end-1]
229229
isexpr(last, :(=)) && (last = last.args[2])
230-
is_kw = isa(scope, Method) && startswith(String(Base.unwrap_unionall(scope.sig).parameters[1].name.name), "#kw")
230+
is_kw = isa(scope, Method) && startswith(String(Base.unwrap_unionall(Base.unwrap_unionall(scope.sig).parameters[1]).name.name), "#kw")
231231
if is_kw || isexpr(last, :call) && any(x->x==Core.SlotNumber(1), last.args)
232232
# If the last expr calls #self# or passes it to an implementation method,
233233
# this is a wrapper function that we might want to step through
@@ -312,6 +312,7 @@ or one of the 'advanced' commands
312312
"""
313313
function debug_command(@nospecialize(recurse), frame::Frame, cmd::AbstractString, rootistoplevel::Bool=false)
314314
istoplevel = rootistoplevel && frame.caller === nothing
315+
cmd0 = cmd
315316
if cmd == "si"
316317
stmt = pc_expr(frame)
317318
cmd = is_call(stmt) ? "s" : "se"
@@ -341,7 +342,13 @@ function debug_command(@nospecialize(recurse), frame::Frame, cmd::AbstractString
341342
ret = handle_err(recurse, frame, err)
342343
return isa(ret, BreakpointRef) ? (leaf(frame), ret) : ret
343344
end
344-
isa(ret, BreakpointRef) && return maybe_reset_frame!(recurse, frame, ret, rootistoplevel)
345+
if isa(ret, BreakpointRef)
346+
newframe = leaf(frame)
347+
cmd0 == "si" && return newframe, ret
348+
newframe = maybe_step_through_wrapper!(recurse, newframe)
349+
return newframe, BreakpointRef(newframe.framecode, 0)
350+
end
351+
# if we got here, the call returned a value
345352
maybe_assign!(frame, stmt0, ret)
346353
frame.pc += 1
347354
return frame, frame.pc

test/debug.jl

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -104,26 +104,6 @@ struct B{T} end
104104
@test debug_command(frame, "n") === nothing
105105
end
106106

107-
@testset "Macros" begin
108-
# Work around the fact that we can't detect macro expansions if the macro
109-
# is defined in the same file
110-
include_string(Main, """
111-
function test_macro()
112-
a = sin(5)
113-
b = asin(a)
114-
@insert_some_calls
115-
z
116-
end
117-
""","file.jl")
118-
frame = JuliaInterpreter.enter_call_expr(:($(test_macro)()))
119-
f, pc = debug_command(frame, "n") # a is set
120-
f, pc = debug_command(f, "n") # b is set
121-
f, pc = debug_command(f, "n") # x is set
122-
f, pc = debug_command(f, "n") # y is set
123-
f, pc = debug_command(f, "n") # z is set
124-
@test debug_command(f, "n") === nothing # return
125-
end
126-
127107
@testset "Keyword arguments" begin
128108
f(x; b = 1) = x+b
129109
g() = f(1; b = 2)
@@ -144,6 +124,55 @@ struct B{T} end
144124
@test get_return(frame) == 6
145125
end
146126

127+
@testset "Optional + keyword wrappers" begin
128+
opkw(a, b=1; c=2, d=3) = 1
129+
callopkw1() = opkw(0)
130+
callopkw2() = opkw(0, -1)
131+
callopkw3() = opkw(0; c=-2)
132+
callopkw4() = opkw(0, -1; c=-2)
133+
callopkw5() = opkw(0; c=-2, d=-3)
134+
callopkw6() = opkw(0, -1; c=-2, d=-3)
135+
scopes = Method[]
136+
for f in (callopkw1, callopkw2, callopkw3, callopkw4, callopkw5, callopkw6)
137+
frame = fr = JuliaInterpreter.enter_call(f)
138+
pc = fr.pc
139+
while pc <= JuliaInterpreter.nstatements(fr.framecode) - 2
140+
fr, pc = debug_command(fr, "se")
141+
end
142+
fr, pc = debug_command(frame, "si")
143+
@test stacklength(frame) == 2
144+
frame = fr = JuliaInterpreter.enter_call(f)
145+
pc = fr.pc
146+
while pc <= JuliaInterpreter.nstatements(fr.framecode) - 2
147+
fr, pc = debug_command(fr, "se")
148+
end
149+
fr, pc = debug_command(frame, "s")
150+
@test stacklength(frame) > 2
151+
push!(scopes, JuliaInterpreter.scopeof(fr))
152+
end
153+
@test length(unique(scopes)) == 1 # all get to the body method
154+
end
155+
156+
@testset "Macros" begin
157+
# Work around the fact that we can't detect macro expansions if the macro
158+
# is defined in the same file
159+
include_string(Main, """
160+
function test_macro()
161+
a = sin(5)
162+
b = asin(a)
163+
@insert_some_calls
164+
z
165+
end
166+
""","file.jl")
167+
frame = JuliaInterpreter.enter_call_expr(:($(test_macro)()))
168+
f, pc = debug_command(frame, "n") # a is set
169+
f, pc = debug_command(f, "n") # b is set
170+
f, pc = debug_command(f, "n") # x is set
171+
f, pc = debug_command(f, "n") # y is set
172+
f, pc = debug_command(f, "n") # z is set
173+
@test debug_command(f, "n") === nothing # return
174+
end
175+
147176
@testset "Quoting" begin
148177
# Test that symbols don't get an extra QuoteNode
149178
f_symbol() = :limit => true

0 commit comments

Comments
 (0)