@@ -35,47 +35,98 @@ impl Frame {
35
35
}
36
36
}
37
37
38
- #[ repr( C , align( 16 ) ) ] // required by `CONTEXT`, is a FIXME in winapi right now
39
- struct MyContext ( CONTEXT ) ;
40
-
41
- #[ inline( always) ]
42
- pub unsafe fn trace ( cb : & mut FnMut ( & super :: Frame ) -> bool ) {
43
- // Allocate necessary structures for doing the stack walk
44
- let process = processthreadsapi:: GetCurrentProcess ( ) ;
45
- let thread = processthreadsapi:: GetCurrentThread ( ) ;
46
-
47
- let mut context = mem:: zeroed :: < MyContext > ( ) ;
48
- winnt:: RtlCaptureContext ( & mut context. 0 ) ;
49
- let mut frame = super :: Frame {
50
- inner : Frame { inner : mem:: zeroed ( ) } ,
51
- } ;
52
- let image = init_frame ( & mut frame. inner . inner , & context. 0 ) ;
53
-
54
- // Initialize this process's symbols
55
- let _c = :: dbghelp_init ( ) ;
56
-
57
- // And now that we're done with all the setup, do the stack walking!
58
- while dbghelp:: StackWalk64 ( image as DWORD ,
59
- process,
60
- thread,
61
- & mut frame. inner . inner ,
62
- & mut context. 0 as * mut CONTEXT as * mut _ ,
63
- None ,
64
- Some ( dbghelp:: SymFunctionTableAccess64 ) ,
65
- Some ( dbghelp:: SymGetModuleBase64 ) ,
66
- None ) == TRUE {
67
- if frame. inner . inner . AddrPC . Offset == frame. inner . inner . AddrReturn . Offset ||
68
- frame. inner . inner . AddrPC . Offset == 0 ||
69
- frame. inner . inner . AddrReturn . Offset == 0 {
38
+ // This beast is to maintain Rust 1.18 Compatibility
39
+ cfg_if ! {
40
+ if #[ cfg( feature = "repr_align" ) ] {
41
+ #[ repr( C , align( 16 ) ) ] // required by `CONTEXT`, is a FIXME in winapi right now
42
+ struct MyContext ( CONTEXT ) ;
43
+
44
+ #[ inline( always) ]
45
+ pub unsafe fn trace( cb: & mut FnMut ( & super :: Frame ) -> bool ) {
46
+ // Allocate necessary structures for doing the stack walk
47
+ let process = processthreadsapi:: GetCurrentProcess ( ) ;
48
+ let thread = processthreadsapi:: GetCurrentThread ( ) ;
49
+
50
+ let mut context = mem:: zeroed:: <MyContext >( ) ;
51
+ winnt:: RtlCaptureContext ( & mut context. 0 ) ;
52
+ let mut frame = super :: Frame {
53
+ inner: Frame { inner: mem:: zeroed( ) } ,
54
+ } ;
55
+ let image = init_frame( & mut frame. inner. inner, & context. 0 ) ;
56
+
57
+ // Initialize this process's symbols
58
+ let _c = :: dbghelp_init( ) ;
59
+
60
+ // And now that we're done with all the setup, do the stack walking!
61
+ while dbghelp:: StackWalk64 ( image as DWORD ,
62
+ process,
63
+ thread,
64
+ & mut frame. inner. inner,
65
+ & mut context. 0 as * mut CONTEXT as * mut _,
66
+ None ,
67
+ Some ( dbghelp:: SymFunctionTableAccess64 ) ,
68
+ Some ( dbghelp:: SymGetModuleBase64 ) ,
69
+ None ) == TRUE {
70
+ if frame. inner. inner. AddrPC . Offset == frame. inner. inner. AddrReturn . Offset ||
71
+ frame. inner. inner. AddrPC . Offset == 0 ||
72
+ frame. inner. inner. AddrReturn . Offset == 0 {
73
+ break
74
+ }
75
+
76
+ if !cb( & frame) {
77
+ break
78
+ }
79
+ }
80
+ }
81
+ } else if #[ cfg( feature = "std" ) ] {
82
+ #[ inline( always) ]
83
+ pub unsafe fn trace( cb: & mut FnMut ( & super :: Frame ) -> bool ) {
84
+ // Allocate necessary structures for doing the stack walk
85
+ let process = processthreadsapi:: GetCurrentProcess ( ) ;
86
+ let thread = processthreadsapi:: GetCurrentThread ( ) ;
87
+
88
+ // The CONTEXT structure needs to be aligned on a 16-byte boundary for
89
+ // 64-bit Windows, but we don't have a way to express that in Rust prior
90
+ // to 1.24. Allocations are generally aligned to 16-bytes, though, so we
91
+ // box this up.
92
+ use std:: boxed:: Box ;
93
+ let mut context = Box :: new( mem:: zeroed:: <CONTEXT >( ) ) ;
94
+ winnt:: RtlCaptureContext ( & mut * context) ;
95
+ let mut frame = super :: Frame {
96
+ inner: Frame { inner: mem:: zeroed( ) } ,
97
+ } ;
98
+ let image = init_frame( & mut frame. inner. inner, & context) ;
99
+
100
+ // Initialize this process's symbols
101
+ let _c = :: dbghelp_init( ) ;
102
+
103
+ // And now that we're done with all the setup, do the stack walking!
104
+ while dbghelp:: StackWalk64 ( image as DWORD ,
105
+ process,
106
+ thread,
107
+ & mut frame. inner. inner,
108
+ & mut * context as * mut _ as * mut _,
109
+ None ,
110
+ Some ( dbghelp:: SymFunctionTableAccess64 ) ,
111
+ Some ( dbghelp:: SymGetModuleBase64 ) ,
112
+ None ) == TRUE {
113
+ if frame. inner. inner. AddrPC . Offset == frame. inner. inner. AddrReturn . Offset ||
114
+ frame. inner. inner. AddrPC . Offset == 0 ||
115
+ frame. inner. inner. AddrReturn . Offset == 0 {
70
116
break
71
117
}
72
118
73
- if !cb ( & frame) {
74
- break
119
+ if !cb( & frame) {
120
+ break
121
+ }
122
+ }
75
123
}
124
+ } else {
125
+ compile_error!( "`no_std` is not supported for versions of Rust prior to 1.24." ) ;
76
126
}
77
127
}
78
128
129
+
79
130
#[ cfg( target_arch = "x86_64" ) ]
80
131
fn init_frame ( frame : & mut STACKFRAME64 , ctx : & CONTEXT ) -> WORD {
81
132
frame. AddrPC . Offset = ctx. Rip as u64 ;
0 commit comments