Skip to content

Commit

Permalink
Make DebugInfo edges per-call rather than per-callee
Browse files Browse the repository at this point in the history
This is useful for when you need to, e.g., trim the "common prefix" of
two stacktraces that were both taken from inside an inlined function
call.

I'm hoping to use this property to provide a way to get only the
"popped" frames inside a `catch` handler, but that requires us to
understand when an inlined frame was popped, as in:
```julia
@inline function foo()
    try
        error("foo")
    catch err
        Base.showerror(stderr, err, Base.catch_backtrace())
    end
end
bar() = foo()
```

The popped frames would be:
```julia
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:44
 [2] foo
   @ ./REPL[1]:3 [inlined]
```

To know to trim off `bar()` (since it hasn't been popped yet), I want
to record the ip at catch entry and then have our stacktrace expansion
logic remove any frames common with the catch entry.

In order to trim that common prefix correctly, we need to distinguish
this case from:
```
try foo() catch foo() end
```
which has the same line number and callee, but is a different call.
  • Loading branch information
topolarity committed Oct 23, 2024
1 parent 8bdacc3 commit 627446a
Showing 1 changed file with 5 additions and 11 deletions.
16 changes: 5 additions & 11 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,11 @@ end
# TODO append `inlinee_debuginfo` to inner linetable when `inlined_at[2] ≠ 0`
function ir_inline_linetable!(debuginfo::DebugInfoStream, inlinee_debuginfo::DebugInfo, inlined_at::NTuple{3,Int32})
# Append the linetable of the inlined function to our edges table
linetable_offset = 1
while true
if linetable_offset > length(debuginfo.edges)
push!(debuginfo.edges, inlinee_debuginfo)
break
elseif debuginfo.edges[linetable_offset] === inlinee_debuginfo
break
end
linetable_offset += 1
end
return (inlined_at[1], Int32(linetable_offset), Int32(0))
#
# We are not allowed to de-duplicate here, since we want to preserve the property that
# each DebugInfo edge corresponds to an inlined call (not just an inlined callee).
push!(debuginfo.edges, inlinee_debuginfo)
return (inlined_at[1], length(debuginfo.edges), Int32(0))
end

function ir_prepare_inlining!(insert_node!::Inserter, inline_target::Union{IRCode, IncrementalCompact},
Expand Down

0 comments on commit 627446a

Please sign in to comment.