Skip to content

Commit 479a544

Browse files
committed
Filter on wanted backtrace entry types.
1 parent e71b057 commit 479a544

File tree

1 file changed

+36
-14
lines changed

1 file changed

+36
-14
lines changed

base/error.jl

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,33 +65,55 @@ struct InterpreterIP
6565
mod::Union{Module,Nothing}
6666
end
6767

68+
# formatted backtrace buffers can contain all types of objects (none for now though)
69+
const BackTraceEntry = Union{Ptr{Nothing}, InterpreterIP}
70+
# but only some correspond with actual instruction pointers
71+
const InstructionPointer = Union{Ptr{Nothing}, InterpreterIP}
72+
6873
# convert an array of raw backtrace entries to array of usable objects
69-
# (either native pointers or InterpreterIP objects)
70-
function _reformat_bt(bt)
71-
ret = Vector{Union{Ptr{Cvoid},InterpreterIP}}()
74+
# (either native pointers, InterpreterIP objects, or AllocationInfo objects)
75+
function _reformat_bt(bt, Wanted::Type=BackTraceEntry)
76+
# NOTE: Ptr{Cvoid} is always part of the output container type,
77+
# as end-of-block markers are encoded as a NULL pointer
78+
# TODO: use Nothing/nothing for that?
79+
ret = Vector{Union{Ptr{Cvoid}, Wanted}}()
7280
i = 1
7381
while i <= length(bt)
7482
ip = bt[i]::Ptr{Cvoid}
75-
if UInt(ip) != (-1 % UInt) # See also jl_bt_is_native
76-
# native frame
83+
84+
# end-of-block marker
85+
if UInt(ip) == 0
7786
push!(ret, ip)
7887
i += 1
7988
continue
8089
end
90+
91+
# native frame
92+
if UInt(ip) != (-1 % UInt)
93+
# See also jl_bt_is_native
94+
if Ptr{Cvoid} <: Wanted
95+
push!(ret, ip)
96+
i += 1
97+
end
98+
continue
99+
end
100+
81101
# Extended backtrace entry
82102
entry_metadata = reinterpret(UInt, bt[i+1])
83103
njlvalues = entry_metadata & 0x7
84104
nuintvals = (entry_metadata >> 3) & 0x7
85105
tag = (entry_metadata >> 6) & 0xf
86106
header = entry_metadata >> 10
87107
if tag == 1 # JL_BT_INTERP_FRAME_TAG
88-
code = unsafe_pointer_to_objref(convert(Ptr{Any}, bt[i+2]))
89-
mod = if njlvalues == 2
90-
unsafe_pointer_to_objref(convert(Ptr{Any}, bt[i+3]))
91-
else
92-
nothing
108+
if InterpreterIP <: Wanted
109+
code = unsafe_pointer_to_objref(convert(Ptr{Any}, bt[i+2]))
110+
mod = if njlvalues == 2
111+
unsafe_pointer_to_objref(convert(Ptr{Any}, bt[i+3]))
112+
else
113+
nothing
114+
end
115+
push!(ret, InterpreterIP(code, header, mod))
93116
end
94-
push!(ret, InterpreterIP(code, header, mod))
95117
else
96118
# Tags we don't know about are an error
97119
throw(ArgumentError("Unexpected extended backtrace entry tag $tag at bt[$i]"))
@@ -114,7 +136,7 @@ function backtrace()
114136
skip = 1
115137
bt1, bt2 = ccall(:jl_backtrace_from_here, Ref{SimpleVector}, (Cint, Cint), false, skip)
116138
t = @_gc_preserve_begin bt2
117-
bt = _reformat_bt(bt1::Vector{Ptr{Cvoid}})
139+
bt = _reformat_bt(bt1::Vector{Ptr{Cvoid}}, InstructionPointer)
118140
@_gc_preserve_end t
119141
return bt
120142
end
@@ -127,7 +149,7 @@ Get the backtrace of the current exception, for use within `catch` blocks.
127149
function catch_backtrace()
128150
bt1, bt2 = ccall(:jl_get_backtrace, Ref{SimpleVector}, ())
129151
t = @_gc_preserve_begin bt2
130-
bt = _reformat_bt(bt1::Vector{Ptr{Cvoid}})
152+
bt = _reformat_bt(bt1::Vector{Ptr{Cvoid}}, InstructionPointer)
131153
@_gc_preserve_end t
132154
return bt
133155
end
@@ -158,7 +180,7 @@ function catch_stack(task=current_task(); include_bt=true)
158180
if include_bt
159181
bt1, bt2 = raw[i+1], raw[i+2]
160182
t = @_gc_preserve_begin bt2
161-
push!(formatted, (e, Base._reformat_bt(bt1)))
183+
push!(formatted, (e, Base._reformat_bt(bt1, InstructionPointer)))
162184
@_gc_preserve_end t
163185
else
164186
push!(formatted, e)

0 commit comments

Comments
 (0)