@@ -65,11 +65,11 @@ struct InterpreterIP
6565 mod:: Union{Module,Nothing}
6666end
6767
68- # convert dual arrays (raw bt buffer, array of GC managed values) to a single
69- # array of locations
70- function _reformat_bt (bt, bt2 )
71- ret = Vector {Union{InterpreterIP, Ptr{Cvoid}}} ()
72- i, j = 1 , 1
68+ # 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 }} ()
72+ i = 1
7373 while i <= length (bt)
7474 ip = bt[i]:: Ptr{Cvoid}
7575 if UInt (ip) != (- 1 % UInt) # See also jl_bt_is_native
@@ -85,15 +85,18 @@ function _reformat_bt(bt, bt2)
8585 tag = (entry_metadata >> 6 ) & 0xf
8686 header = entry_metadata >> 10
8787 if tag == 1 # JL_BT_INTERP_FRAME_TAG
88- code = bt2[j]
89- mod = njlvalues == 2 ? bt2[j+ 1 ] : nothing
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
93+ end
9094 push! (ret, InterpreterIP (code, header, mod))
9195 else
9296 # Tags we don't know about are an error
9397 throw (ArgumentError (" Unexpected extended backtrace entry tag $tag at bt[$i ]" ))
9498 end
9599 # See jl_bt_entry_size
96- j += njlvalues
97100 i += Int (2 + njlvalues + nuintvals)
98101 end
99102 ret
@@ -110,7 +113,10 @@ function backtrace()
110113 # backtrace() itself must not be interpreted nor inlined.
111114 skip = 1
112115 bt1, bt2 = ccall (:jl_backtrace_from_here , Ref{SimpleVector}, (Cint, Cint), false , skip)
113- return _reformat_bt (bt1:: Vector{Ptr{Cvoid}} , bt2:: Vector{Any} )
116+ t = @_gc_preserve_begin bt2
117+ bt = _reformat_bt (bt1:: Vector{Ptr{Cvoid}} )
118+ @_gc_preserve_end t
119+ return bt
114120end
115121
116122"""
119125Get the backtrace of the current exception, for use within `catch` blocks.
120126"""
121127function catch_backtrace ()
122- bt, bt2 = ccall (:jl_get_backtrace , Ref{SimpleVector}, ())
123- return _reformat_bt (bt:: Vector{Ptr{Cvoid}} , bt2:: Vector{Any} )
128+ bt1, bt2 = ccall (:jl_get_backtrace , Ref{SimpleVector}, ())
129+ t = @_gc_preserve_begin bt2
130+ bt = _reformat_bt (bt1:: Vector{Ptr{Cvoid}} )
131+ @_gc_preserve_end t
132+ return bt
124133end
125134
126135"""
@@ -146,7 +155,14 @@ function catch_stack(task=current_task(); include_bt=true)
146155 stride = include_bt ? 3 : 1
147156 for i = reverse (1 : stride: length (raw))
148157 e = raw[i]
149- push! (formatted, include_bt ? (e,Base. _reformat_bt (raw[i+ 1 ],raw[i+ 2 ])) : e)
158+ if include_bt
159+ bt1, bt2 = raw[i+ 1 ], raw[i+ 2 ]
160+ t = @_gc_preserve_begin bt2
161+ push! (formatted, (e, Base. _reformat_bt (bt1)))
162+ @_gc_preserve_end t
163+ else
164+ push! (formatted, e)
165+ end
150166 end
151167 formatted
152168end
0 commit comments