Skip to content

Commit

Permalink
Merge pull request #149 from JuliaDebug/teh/stepping
Browse files Browse the repository at this point in the history
Ensure that "s" steps through wrappers
  • Loading branch information
timholy authored Mar 15, 2019
2 parents b76bc3d + 8fd5574 commit c41e768
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 22 deletions.
11 changes: 9 additions & 2 deletions src/commands.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ function maybe_step_through_wrapper!(@nospecialize(recurse), frame::Frame)
length(stmts) < 2 && return frame
last = stmts[end-1]
isexpr(last, :(=)) && (last = last.args[2])
is_kw = isa(scope, Method) && startswith(String(Base.unwrap_unionall(scope.sig).parameters[1].name.name), "#kw")
is_kw = isa(scope, Method) && startswith(String(Base.unwrap_unionall(Base.unwrap_unionall(scope.sig).parameters[1]).name.name), "#kw")
if is_kw || isexpr(last, :call) && any(x->x==Core.SlotNumber(1), last.args)
# If the last expr calls #self# or passes it to an implementation method,
# this is a wrapper function that we might want to step through
Expand Down Expand Up @@ -312,6 +312,7 @@ or one of the 'advanced' commands
"""
function debug_command(@nospecialize(recurse), frame::Frame, cmd::AbstractString, rootistoplevel::Bool=false)
istoplevel = rootistoplevel && frame.caller === nothing
cmd0 = cmd
if cmd == "si"
stmt = pc_expr(frame)
cmd = is_call(stmt) ? "s" : "se"
Expand Down Expand Up @@ -341,7 +342,13 @@ function debug_command(@nospecialize(recurse), frame::Frame, cmd::AbstractString
ret = handle_err(recurse, frame, err)
return isa(ret, BreakpointRef) ? (leaf(frame), ret) : ret
end
isa(ret, BreakpointRef) && return maybe_reset_frame!(recurse, frame, ret, rootistoplevel)
if isa(ret, BreakpointRef)
newframe = leaf(frame)
cmd0 == "si" && return newframe, ret
newframe = maybe_step_through_wrapper!(recurse, newframe)
return newframe, BreakpointRef(newframe.framecode, 0)
end
# if we got here, the call returned a value
maybe_assign!(frame, stmt0, ret)
frame.pc += 1
return frame, frame.pc
Expand Down
69 changes: 49 additions & 20 deletions test/debug.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,26 +104,6 @@ struct B{T} end
@test debug_command(frame, "n") === nothing
end

@testset "Macros" begin
# Work around the fact that we can't detect macro expansions if the macro
# is defined in the same file
include_string(Main, """
function test_macro()
a = sin(5)
b = asin(a)
@insert_some_calls
z
end
""","file.jl")
frame = JuliaInterpreter.enter_call_expr(:($(test_macro)()))
f, pc = debug_command(frame, "n") # a is set
f, pc = debug_command(f, "n") # b is set
f, pc = debug_command(f, "n") # x is set
f, pc = debug_command(f, "n") # y is set
f, pc = debug_command(f, "n") # z is set
@test debug_command(f, "n") === nothing # return
end

@testset "Keyword arguments" begin
f(x; b = 1) = x+b
g() = f(1; b = 2)
Expand All @@ -144,6 +124,55 @@ struct B{T} end
@test get_return(frame) == 6
end

@testset "Optional + keyword wrappers" begin
opkw(a, b=1; c=2, d=3) = 1
callopkw1() = opkw(0)
callopkw2() = opkw(0, -1)
callopkw3() = opkw(0; c=-2)
callopkw4() = opkw(0, -1; c=-2)
callopkw5() = opkw(0; c=-2, d=-3)
callopkw6() = opkw(0, -1; c=-2, d=-3)
scopes = Method[]
for f in (callopkw1, callopkw2, callopkw3, callopkw4, callopkw5, callopkw6)
frame = fr = JuliaInterpreter.enter_call(f)
pc = fr.pc
while pc <= JuliaInterpreter.nstatements(fr.framecode) - 2
fr, pc = debug_command(fr, "se")
end
fr, pc = debug_command(frame, "si")
@test stacklength(frame) == 2
frame = fr = JuliaInterpreter.enter_call(f)
pc = fr.pc
while pc <= JuliaInterpreter.nstatements(fr.framecode) - 2
fr, pc = debug_command(fr, "se")
end
fr, pc = debug_command(frame, "s")
@test stacklength(frame) > 2
push!(scopes, JuliaInterpreter.scopeof(fr))
end
@test length(unique(scopes)) == 1 # all get to the body method
end

@testset "Macros" begin
# Work around the fact that we can't detect macro expansions if the macro
# is defined in the same file
include_string(Main, """
function test_macro()
a = sin(5)
b = asin(a)
@insert_some_calls
z
end
""","file.jl")
frame = JuliaInterpreter.enter_call_expr(:($(test_macro)()))
f, pc = debug_command(frame, "n") # a is set
f, pc = debug_command(f, "n") # b is set
f, pc = debug_command(f, "n") # x is set
f, pc = debug_command(f, "n") # y is set
f, pc = debug_command(f, "n") # z is set
@test debug_command(f, "n") === nothing # return
end

@testset "Quoting" begin
# Test that symbols don't get an extra QuoteNode
f_symbol() = :limit => true
Expand Down

0 comments on commit c41e768

Please sign in to comment.