Skip to content

Commit 0d47ee7

Browse files
BioTurboNickDrvi
authored andcommitted
Revert inlined method signature stacktrace lookup code (JuliaLang#52754)
The fallback code that was written for JuliaLang#41099 is causing unintended issues with some inlined stack frames (one previous JuliaLang#51405, new JuliaLang#52709), since the main piece, linetable storage and lookup, was removed in JuliaLang#50546. Probably better to strip it all back to how it was previously, until it can all be revisited more fully. Should be backported to 1.10.
1 parent a397252 commit 0d47ee7

File tree

1 file changed

+2
-97
lines changed

1 file changed

+2
-97
lines changed

base/stacktraces.jl

Lines changed: 2 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -97,87 +97,6 @@ function hash(frame::StackFrame, h::UInt)
9797
return h
9898
end
9999

100-
get_inlinetable(::Any) = nothing
101-
function get_inlinetable(mi::MethodInstance)
102-
isdefined(mi, :def) && mi.def isa Method && isdefined(mi, :cache) && isdefined(mi.cache, :inferred) &&
103-
mi.cache.inferred !== nothing || return nothing
104-
linetable = ccall(:jl_uncompress_ir, Any, (Any, Any, Any), mi.def, mi.cache, mi.cache.inferred).linetable
105-
return filter!(x -> x.inlined_at > 0, linetable)
106-
end
107-
108-
get_method_instance_roots(::Any) = nothing
109-
function get_method_instance_roots(mi::Union{Method, MethodInstance})
110-
m = mi isa MethodInstance ? mi.def : mi
111-
m isa Method && isdefined(m, :roots) || return nothing
112-
return filter(x -> x isa MethodInstance, m.roots)
113-
end
114-
115-
function lookup_inline_frame_info(func::Symbol, file::Symbol, linenum::Int, inlinetable::Vector{Core.LineInfoNode})
116-
#REPL frames and some base files lack this prefix while others have it; should fix?
117-
filestripped = Symbol(lstrip(string(file), ('.', '\\', '/')))
118-
linfo = nothing
119-
#=
120-
Some matching entries contain the MethodInstance directly.
121-
Other matching entries contain only a Method or Symbol (function name); such entries
122-
are located after the entry with the MethodInstance, so backtracking is required.
123-
If backtracking fails, the Method or Module is stored for return, but we continue
124-
the search in case a MethodInstance is found later.
125-
TODO: If a backtrack has failed, do we need to backtrack again later if another Method
126-
or Symbol match is found? Or can a limit on the subsequent backtracks be placed?
127-
=#
128-
for (i, line) in enumerate(inlinetable)
129-
Base.IRShow.method_name(line) === func && line.file (file, filestripped) && line.line == linenum || continue
130-
if line.method isa MethodInstance
131-
linfo = line.method
132-
break
133-
elseif line.method isa Method || line.method isa Symbol
134-
linfo = line.method isa Method ? line.method : line.module
135-
# backtrack to find the matching MethodInstance, if possible
136-
for j in (i - 1):-1:1
137-
nextline = inlinetable[j]
138-
nextline.inlined_at == line.inlined_at && Base.IRShow.method_name(line) === Base.IRShow.method_name(nextline) && line.file === nextline.file || break
139-
if nextline.method isa MethodInstance
140-
linfo = nextline.method
141-
break
142-
end
143-
end
144-
end
145-
end
146-
return linfo
147-
end
148-
149-
function lookup_inline_frame_info(func::Symbol, file::Symbol, miroots::Vector{Any})
150-
# REPL frames and some base files lack this prefix while others have it; should fix?
151-
filestripped = Symbol(lstrip(string(file), ('.', '\\', '/')))
152-
matches = filter(miroots) do x
153-
x.def isa Method || return false
154-
m = x.def::Method
155-
return m.name == func && m.file (file, filestripped)
156-
end
157-
if length(matches) > 1
158-
# ambiguous, check if method is same and return that instead
159-
all_matched = true
160-
for m in matches
161-
all_matched = m.def.line == matches[1].def.line &&
162-
m.def.module == matches[1].def.module
163-
all_matched || break
164-
end
165-
if all_matched
166-
return matches[1].def
167-
end
168-
# all else fails, return module if they match, or give up
169-
all_matched = true
170-
for m in matches
171-
all_matched = m.def.module == matches[1].def.module
172-
all_matched || break
173-
end
174-
return all_matched ? matches[1].def.module : nothing
175-
elseif length(matches) == 1
176-
return matches[1]
177-
end
178-
return nothing
179-
end
180-
181100
"""
182101
lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}
183102
@@ -189,25 +108,11 @@ Base.@constprop :none function lookup(pointer::Ptr{Cvoid})
189108
infos = ccall(:jl_lookup_code_address, Any, (Ptr{Cvoid}, Cint), pointer, false)::Core.SimpleVector
190109
pointer = convert(UInt64, pointer)
191110
isempty(infos) && return [StackFrame(empty_sym, empty_sym, -1, nothing, true, false, pointer)] # this is equal to UNKNOWN
192-
parent_linfo = infos[end][4]
193-
inlinetable = get_inlinetable(parent_linfo)
194-
miroots = inlinetable === nothing ? get_method_instance_roots(parent_linfo) : nothing # fallback if linetable missing
195111
res = Vector{StackFrame}(undef, length(infos))
196-
for i in reverse(1:length(infos))
112+
for i in 1:length(infos)
197113
info = infos[i]::Core.SimpleVector
198114
@assert(length(info) == 6)
199-
func = info[1]::Symbol
200-
file = info[2]::Symbol
201-
linenum = info[3]::Int
202-
linfo = info[4]
203-
if i < length(infos)
204-
if inlinetable !== nothing
205-
linfo = lookup_inline_frame_info(func, file, linenum, inlinetable)
206-
elseif miroots !== nothing
207-
linfo = lookup_inline_frame_info(func, file, miroots)
208-
end
209-
end
210-
res[i] = StackFrame(func, file, linenum, linfo, info[5]::Bool, info[6]::Bool, pointer)
115+
res[i] = StackFrame(info[1]::Symbol, info[2]::Symbol, info[3]::Int, info[4], info[5]::Bool, info[6]::Bool, pointer)
211116
end
212117
return res
213118
end

0 commit comments

Comments
 (0)