@@ -65,33 +65,55 @@ struct InterpreterIP
6565 mod:: Union{Module,Nothing}
6666end
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
120142end
@@ -127,7 +149,7 @@ Get the backtrace of the current exception, for use within `catch` blocks.
127149function 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
133155end
@@ -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