@@ -258,3 +258,88 @@ let code = """
258
258
@test occursin (" InterpreterIP in top-level CodeInfo for Main.A" , bt_str)
259
259
end
260
260
261
+ """
262
+ _reformat_sp(bt_data...) -> sp::Vector{Ptr{Cvoid}}
263
+
264
+ Convert the output `bt_data` of `jl_backtrace_from_here` with `returnsp` flag set to a
265
+ vector of valid stack pointers `sp`; i.e., `sp` is a subset of `bt_data[3]`.
266
+
267
+ See also `Base._reformat_bt`.
268
+ """
269
+ function _reformat_sp (
270
+ bt_raw:: Array{Ptr{Cvoid},1} ,
271
+ bt2:: Array{Any,1} ,
272
+ sp_raw:: Array{Ptr{Cvoid},1} ,
273
+ )
274
+ bt = Base. _reformat_bt (bt_raw, bt2)
275
+ sp = empty! (similar (sp_raw))
276
+ i = j = 0
277
+ while true
278
+ # Advance `i` such that `bt[i] isa Ptr{Cvoid}` (native pointer).
279
+ local ip
280
+ while true
281
+ if i == lastindex (bt)
282
+ return sp
283
+ end
284
+ i += 1
285
+ x = bt[i]
286
+ if x isa Ptr{Cvoid}
287
+ ip = x
288
+ break
289
+ end
290
+ end
291
+ # Advance `j` such that `bt_raw[j] == bt[i]` to find a valid stack pointer.
292
+ while true
293
+ if j == lastindex (bt_raw)
294
+ return sp
295
+ end
296
+ j += 1
297
+ if bt_raw[j] == ip
298
+ push! (sp, sp_raw[j])
299
+ break
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ """
306
+ withframeaddress(f)
307
+
308
+ Call function `f` with an address `ptr::Ptr{Cvoid}` of an independent frame
309
+ immediately outer to `f`.
310
+ """
311
+ withframeaddress
312
+ @eval @noinline function withframeaddress (f)
313
+ sp = Core. Intrinsics. llvmcall (
314
+ ($ """
315
+ declare i8* @llvm.frameaddress(i32)
316
+ define private i$(Sys. WORD_SIZE) @frameaddr() {
317
+ %1 = call i8* @llvm.frameaddress(i32 0)
318
+ %2 = ptrtoint i8* %1 to i$(Sys. WORD_SIZE)
319
+ ret i$(Sys. WORD_SIZE) %2
320
+ }""" , " frameaddr" ),
321
+ UInt,
322
+ Tuple{},
323
+ )
324
+ @noinline f (Ptr {Cvoid} (sp))
325
+ end
326
+
327
+ function sandwiched_backtrace ()
328
+ local ptr1, ptr2, bt
329
+ withframeaddress () do p1
330
+ ptr1 = p1
331
+ bt = ccall (:jl_backtrace_from_here , Ref{Base. SimpleVector}, (Cint, Cint), true , 0 )
332
+ withframeaddress () do p2
333
+ ptr2 = p2
334
+ end
335
+ end
336
+ return ptr1, ptr2, bt
337
+ end
338
+
339
+ @testset " stack pointers" begin
340
+ ptr1, ptr2, bt_data = sandwiched_backtrace ()
341
+ sp = _reformat_sp (bt_data... )
342
+ @test ptr2 < sp[2 ]
343
+ @test sp[1 ] < ptr1
344
+ @test all (diff (Int128 .(UInt .(sp))) .> 0 )
345
+ end
0 commit comments