@@ -122,6 +122,12 @@ struct ProfileFormat
122
122
end
123
123
end
124
124
125
+ # offsets of the metadata in the data stream
126
+ const META_OFFSET_SLEEPSTATE = 2
127
+ const META_OFFSET_CPUCYCLECLOCK = 3
128
+ const META_OFFSET_TASKID = 4
129
+ const META_OFFSET_THREADID = 5
130
+
125
131
"""
126
132
print([io::IO = stdout,] [data::Vector]; kwargs...)
127
133
@@ -267,8 +273,8 @@ function get_task_ids(data::Vector{<:Unsigned}, threadid = nothing)
267
273
taskids = UInt[]
268
274
for i in length (data): - 1 : 1
269
275
if is_block_end (data, i)
270
- if isnothing (threadid) || data[i - 5 ] == threadid
271
- taskid = data[i - 4 ]
276
+ if isnothing (threadid) || data[i - META_OFFSET_THREADID ] == threadid
277
+ taskid = data[i - META_OFFSET_TASKID ]
272
278
! in (taskid, taskids) && push! (taskids, taskid)
273
279
end
274
280
end
@@ -280,8 +286,8 @@ function get_thread_ids(data::Vector{<:Unsigned}, taskid = nothing)
280
286
threadids = Int[]
281
287
for i in length (data): - 1 : 1
282
288
if is_block_end (data, i)
283
- if isnothing (taskid) || data[i - 4 ] == taskid
284
- threadid = data[i - 5 ]
289
+ if isnothing (taskid) || data[i - META_OFFSET_TASKID ] == taskid
290
+ threadid = data[i - META_OFFSET_THREADID ]
285
291
! in (threadid, threadids) && push! (threadids, threadid)
286
292
end
287
293
end
@@ -296,13 +302,20 @@ function is_block_end(data, i)
296
302
# and we could have (though very unlikely):
297
303
# 1:<stack><metadata><null><null><NULL><metadata><null><null>:end
298
304
# and we want to ignore the triple NULL (which is an ip).
299
- data[i] == 0 || return false # first block end null
300
- data[i - 1 ] == 0 || return false # second block end null
301
- data[i - 2 ] in 1 : 2 || return false # sleep state
302
- data[i - 3 ] != 0 || return false # cpu_cycle_clock
303
- data[i - 4 ] != 0 || return false # taskid
304
- data[i - 5 ] != 0 || return false # threadid
305
- return true
305
+ return data[i] == 0 && data[i - 1 ] == 0 && data[i - META_OFFSET_SLEEPSTATE] != 0
306
+ end
307
+
308
+ function has_meta (data)
309
+ for i in 6 : length (data)
310
+ data[i] == 0 || continue # first block end null
311
+ data[i - 1 ] == 0 || continue # second block end null
312
+ data[i - META_OFFSET_SLEEPSTATE] in 1 : 2 || continue
313
+ data[i - META_OFFSET_CPUCYCLECLOCK] != 0 || continue
314
+ data[i - META_OFFSET_TASKID] != 0 || continue
315
+ data[i - META_OFFSET_THREADID] != 0 || continue
316
+ return true
317
+ end
318
+ return false
306
319
end
307
320
308
321
"""
@@ -505,15 +518,15 @@ error_codes = Dict(
505
518
506
519
507
520
"""
508
- fetch(;include_meta = false ) -> data
521
+ fetch(;include_meta = true ) -> data
509
522
510
523
Returns a copy of the buffer of profile backtraces. Note that the
511
524
values in `data` have meaning only on this machine in the current session, because it
512
525
depends on the exact memory addresses used in JIT-compiling. This function is primarily for
513
526
internal use; [`retrieve`](@ref) may be a better choice for most users.
514
- By default metadata such as threadid and taskid will be stripped . Set `include_meta` to `true ` to include metadata.
527
+ By default metadata such as threadid and taskid is included . Set `include_meta` to `false ` to strip metadata.
515
528
"""
516
- function fetch (;include_meta = false )
529
+ function fetch (;include_meta = true )
517
530
maxlen = maxlen_data ()
518
531
len = len_data ()
519
532
if is_buffer_full ()
@@ -542,7 +555,7 @@ function strip_meta(data)
542
555
i -= 1
543
556
j -= 1
544
557
end
545
- @assert i == j == 0 " metadata stripping failed i= $i j= $j data[1:i]= $(data[ 1 : i]) "
558
+ @assert i == j == 0 " metadata stripping failed"
546
559
return data_stripped
547
560
end
548
561
@@ -556,7 +569,7 @@ details of the metadata format.
556
569
function add_fake_meta (data; threadid = 1 , taskid = 0xf0f0f0f0 )
557
570
threadid == 0 && error (" Fake threadid cannot be 0" )
558
571
taskid == 0 && error (" Fake taskid cannot be 0" )
559
- any (Base . Fix1 (is_block_end, data), eachindex (data) ) && error (" input already has metadata" )
572
+ ! isempty ( data) && has_meta (data) && error (" input already has metadata" )
560
573
cpu_clock_cycle = UInt64 (99 )
561
574
data_with_meta = similar (data, 0 )
562
575
for i = 1 : length (data)
576
589
# Merging multiple equivalent entries and recursive calls
577
590
function parse_flat (:: Type{T} , data:: Vector{UInt64} , lidict:: Union{LineInfoDict, LineInfoFlatDict} , C:: Bool ,
578
591
threads:: Union{Int,AbstractVector{Int}} , tasks:: Union{UInt,AbstractVector{UInt}} ) where {T}
592
+ ! isempty (data) && ! has_meta (data) && error (" Profile data is missing required metadata" )
579
593
lilist = StackFrame[]
580
594
n = Int[]
581
595
m = Int[]
@@ -591,10 +605,10 @@ function parse_flat(::Type{T}, data::Vector{UInt64}, lidict::Union{LineInfoDict,
591
605
ip = data[i]
592
606
if is_block_end (data, i)
593
607
# read metadata
594
- thread_sleeping = data[i - 2 ] - 1 # subtract 1 as state is incremented to avoid being equal to 0
595
- # cpu_cycle_clock = data[i - 3 ]
596
- taskid = data[i - 4 ]
597
- threadid = data[i - 5 ]
608
+ thread_sleeping = data[i - META_OFFSET_SLEEPSTATE ] - 1 # subtract 1 as state is incremented to avoid being equal to 0
609
+ # cpu_cycle_clock = data[i - META_OFFSET_CPUCYCLECLOCK ]
610
+ taskid = data[i - META_OFFSET_TASKID ]
611
+ threadid = data[i - META_OFFSET_THREADID ]
598
612
if ! in (threadid, threads) || ! in (taskid, tasks)
599
613
skip = true
600
614
continue
828
842
# turn a list of backtraces into a tree (implicitly separated by NULL markers)
829
843
function tree! (root:: StackFrameTree{T} , all:: Vector{UInt64} , lidict:: Union{LineInfoFlatDict, LineInfoDict} , C:: Bool , recur:: Symbol ,
830
844
threads:: Union{Int,AbstractVector{Int},Nothing} = nothing , tasks:: Union{UInt,AbstractVector{UInt},Nothing} = nothing ) where {T}
845
+ ! isempty (all) && ! has_meta (all) && error (" Profile data is missing required metadata" )
831
846
parent = root
832
847
tops = Vector {StackFrameTree{T}} ()
833
848
build = Vector {StackFrameTree{T}} ()
@@ -839,10 +854,10 @@ function tree!(root::StackFrameTree{T}, all::Vector{UInt64}, lidict::Union{LineI
839
854
ip = all[i]
840
855
if is_block_end (all, i)
841
856
# read metadata
842
- thread_sleeping = all[i - 2 ] - 1 # subtract 1 as state is incremented to avoid being equal to 0
843
- # cpu_cycle_clock = all[i - 3 ]
844
- taskid = all[i - 4 ]
845
- threadid = all[i - 5 ]
857
+ thread_sleeping = all[i - META_OFFSET_SLEEPSTATE ] - 1 # subtract 1 as state is incremented to avoid being equal to 0
858
+ # cpu_cycle_clock = all[i - META_OFFSET_CPUCYCLECLOCK ]
859
+ taskid = all[i - META_OFFSET_TASKID ]
860
+ threadid = all[i - META_OFFSET_THREADID ]
846
861
if (threads != = nothing && ! in (threadid, threads)) ||
847
862
(tasks != = nothing && ! in (taskid, tasks))
848
863
skip = true
0 commit comments