@@ -20,6 +20,55 @@ use crate::native::{
20
20
EVENT_EXTENDED_ITEM_STACK_TRACE64 ,
21
21
} ;
22
22
23
+ const OFFSET_OF_ADDRESS_IN_ITEM : usize = offset_of ! ( EVENT_EXTENDED_ITEM_STACK_TRACE64 , Address ) ;
24
+ const _: ( ) =
25
+ assert ! ( OFFSET_OF_ADDRESS_IN_ITEM == offset_of!( EVENT_EXTENDED_ITEM_STACK_TRACE32 , Address ) ) ;
26
+
27
+ /// A fixed-size representation of EVENT_EXTENDED_ITEM_STACK_TRACE32 (if Address is u32)
28
+ /// and EVENT_EXTENDED_ITEM_STACK_TRACE64 (if Address is u64)
29
+ ///
30
+ /// See <https://learn.microsoft.com/en-us/windows/win32/api/evntcons/ns-evntcons-event_extended_item_stack_trace32>
31
+ /// See <https://learn.microsoft.com/en-us/windows/win32/api/evntcons/ns-evntcons-event_extended_item_stack_trace64>
32
+ #[ derive( Debug ) ]
33
+ pub struct StackTraceItem < Address >
34
+ where
35
+ Address : Copy ,
36
+ {
37
+ match_id : u64 ,
38
+ addresses : Box < [ Address ] > ,
39
+ }
40
+
41
+ impl < Address > StackTraceItem < Address >
42
+ where
43
+ Address : Copy ,
44
+ {
45
+ /// Accessor for the MatchId field
46
+ pub fn match_id ( & self ) -> u64 {
47
+ self . match_id
48
+ }
49
+
50
+ /// Accessor for the ANYSIZE_ARRAY Address field
51
+ pub fn addresses ( & self ) -> & [ Address ] {
52
+ self . addresses . as_ref ( )
53
+ }
54
+
55
+ unsafe fn from_raw (
56
+ match_id : u64 ,
57
+ first_address : * const Address ,
58
+ item_size : usize ,
59
+ ) -> StackTraceItem < Address > {
60
+ let array_size_in_bytes = item_size
61
+ . checked_sub ( OFFSET_OF_ADDRESS_IN_ITEM )
62
+ . unwrap_or ( 0 ) ;
63
+ let array_size = array_size_in_bytes / core:: mem:: size_of :: < Address > ( ) ;
64
+ let addresses = unsafe { std:: slice:: from_raw_parts ( first_address, array_size) } . into ( ) ;
65
+ StackTraceItem {
66
+ match_id,
67
+ addresses,
68
+ }
69
+ }
70
+ }
71
+
23
72
/// A wrapper over [`windows::Win32::System::Diagnostics::Etw::EVENT_HEADER_EXTENDED_DATA_ITEM`]
24
73
#[ repr( transparent) ]
25
74
pub struct EventHeaderExtendedDataItem ( EVENT_HEADER_EXTENDED_DATA_ITEM ) ;
@@ -39,9 +88,9 @@ pub enum ExtendedDataItem {
39
88
TsId ( u32 ) ,
40
89
InstanceInfo ( EVENT_EXTENDED_ITEM_INSTANCE ) ,
41
90
/// Call stack (if the event is captured on a 32-bit computer)
42
- StackTrace32 ( EVENT_EXTENDED_ITEM_STACK_TRACE32 ) ,
91
+ StackTrace32 ( StackTraceItem < u32 > ) ,
43
92
/// Call stack (if the event is captured on a 64-bit computer)
44
- StackTrace64 ( EVENT_EXTENDED_ITEM_STACK_TRACE64 ) ,
93
+ StackTrace64 ( StackTraceItem < u64 > ) ,
45
94
/// TraceLogging event metadata information
46
95
TraceLogging ( String ) ,
47
96
// /// Provider traits data
@@ -96,12 +145,22 @@ impl EventHeaderExtendedDataItem {
96
145
97
146
EVENT_HEADER_EXT_TYPE_STACK_TRACE32 => {
98
147
let data_ptr = data_ptr as * const EVENT_EXTENDED_ITEM_STACK_TRACE32 ;
99
- ExtendedDataItem :: StackTrace32 ( unsafe { * data_ptr } )
148
+ ExtendedDataItem :: StackTrace32 ( unsafe {
149
+ let match_id = ( * data_ptr) . MatchId ;
150
+ let first_address = & ( * data_ptr) . Address [ 0 ] as * const _ ;
151
+ let item_size = self . 0 . DataSize as usize ;
152
+ StackTraceItem :: from_raw ( match_id, first_address, item_size)
153
+ } )
100
154
}
101
155
102
156
EVENT_HEADER_EXT_TYPE_STACK_TRACE64 => {
103
157
let data_ptr = data_ptr as * const EVENT_EXTENDED_ITEM_STACK_TRACE64 ;
104
- ExtendedDataItem :: StackTrace64 ( unsafe { * data_ptr } )
158
+ ExtendedDataItem :: StackTrace64 ( unsafe {
159
+ let match_id = ( * data_ptr) . MatchId ;
160
+ let first_address = & ( * data_ptr) . Address [ 0 ] as * const _ ;
161
+ let item_size = self . 0 . DataSize as usize ;
162
+ StackTraceItem :: from_raw ( match_id, first_address, item_size)
163
+ } )
105
164
}
106
165
107
166
EVENT_HEADER_EXT_TYPE_PROCESS_START_KEY => {
0 commit comments