2
2
use crate :: resolve;
3
3
use crate :: PrintFmt ;
4
4
use crate :: { resolve_frame, trace, BacktraceFmt , Symbol , SymbolName } ;
5
- use std :: ffi:: c_void;
5
+ use core :: ffi:: c_void;
6
6
use std:: fmt;
7
7
use std:: path:: { Path , PathBuf } ;
8
8
use std:: prelude:: v1:: * ;
@@ -29,6 +29,101 @@ pub struct Backtrace {
29
29
frames : Vec < BacktraceFrame > ,
30
30
}
31
31
32
+ #[ derive( Clone , Copy ) ]
33
+ struct TracePtr ( * mut c_void ) ;
34
+ /// SAFETY: These pointers are always valid within a process and are not used for mutation.
35
+ unsafe impl Send for TracePtr { }
36
+ /// SAFETY: These pointers are always valid within a process and are not used for mutation.
37
+ unsafe impl Sync for TracePtr { }
38
+
39
+ impl TracePtr {
40
+ fn into_void ( self ) -> * mut c_void {
41
+ self . 0
42
+ }
43
+ #[ cfg( feature = "serde" ) ]
44
+ fn from_addr ( addr : usize ) -> Self {
45
+ TracePtr ( addr as * mut c_void )
46
+ }
47
+ }
48
+
49
+ #[ cfg( feature = "serde" ) ]
50
+ impl < ' de > Deserialize < ' de > for TracePtr {
51
+ #[ inline]
52
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
53
+ where
54
+ D : serde:: Deserializer < ' de > ,
55
+ {
56
+ struct PrimitiveVisitor ;
57
+
58
+ impl < ' de > serde:: de:: Visitor < ' de > for PrimitiveVisitor {
59
+ type Value = TracePtr ;
60
+
61
+ fn expecting ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
62
+ formatter. write_str ( "usize" )
63
+ }
64
+
65
+ #[ inline]
66
+ fn visit_u8 < E > ( self , v : u8 ) -> Result < Self :: Value , E >
67
+ where
68
+ E : serde:: de:: Error ,
69
+ {
70
+ Ok ( TracePtr ( v as usize as * mut c_void ) )
71
+ }
72
+
73
+ #[ inline]
74
+ fn visit_u16 < E > ( self , v : u16 ) -> Result < Self :: Value , E >
75
+ where
76
+ E : serde:: de:: Error ,
77
+ {
78
+ Ok ( TracePtr ( v as usize as * mut c_void ) )
79
+ }
80
+
81
+ #[ inline]
82
+ fn visit_u32 < E > ( self , v : u32 ) -> Result < Self :: Value , E >
83
+ where
84
+ E : serde:: de:: Error ,
85
+ {
86
+ if usize:: BITS >= 32 {
87
+ Ok ( TracePtr ( v as usize as * mut c_void ) )
88
+ } else {
89
+ Err ( E :: invalid_type (
90
+ serde:: de:: Unexpected :: Unsigned ( v as _ ) ,
91
+ & self ,
92
+ ) )
93
+ }
94
+ }
95
+
96
+ #[ inline]
97
+ fn visit_u64 < E > ( self , v : u64 ) -> Result < Self :: Value , E >
98
+ where
99
+ E : serde:: de:: Error ,
100
+ {
101
+ if usize:: BITS >= 64 {
102
+ Ok ( TracePtr ( v as usize as * mut c_void ) )
103
+ } else {
104
+ Err ( E :: invalid_type (
105
+ serde:: de:: Unexpected :: Unsigned ( v as _ ) ,
106
+ & self ,
107
+ ) )
108
+ }
109
+ }
110
+ }
111
+
112
+ deserializer. deserialize_u64 ( PrimitiveVisitor )
113
+ }
114
+ }
115
+
116
+ #[ cfg( feature = "serde" ) ]
117
+ impl Serialize for TracePtr {
118
+ #[ inline]
119
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
120
+ where
121
+ S : serde:: ser:: Serializer ,
122
+ {
123
+ serializer. serialize_u64 ( self . 0 as usize as u64 )
124
+ }
125
+ }
126
+
32
127
fn _assert_send_sync ( ) {
33
128
fn _assert < T : Send + Sync > ( ) { }
34
129
_assert :: < Backtrace > ( ) ;
@@ -54,9 +149,9 @@ enum Frame {
54
149
Raw ( crate :: Frame ) ,
55
150
#[ cfg( feature = "serde" ) ]
56
151
Deserialized {
57
- ip : usize ,
58
- symbol_address : usize ,
59
- module_base_address : Option < usize > ,
152
+ ip : TracePtr ,
153
+ symbol_address : TracePtr ,
154
+ module_base_address : Option < TracePtr > ,
60
155
} ,
61
156
}
62
157
@@ -65,15 +160,15 @@ impl Frame {
65
160
match * self {
66
161
Frame :: Raw ( ref f) => f. ip ( ) ,
67
162
#[ cfg( feature = "serde" ) ]
68
- Frame :: Deserialized { ip, .. } => ip as * mut c_void ,
163
+ Frame :: Deserialized { ip, .. } => ip. into_void ( ) ,
69
164
}
70
165
}
71
166
72
167
fn symbol_address ( & self ) -> * mut c_void {
73
168
match * self {
74
169
Frame :: Raw ( ref f) => f. symbol_address ( ) ,
75
170
#[ cfg( feature = "serde" ) ]
76
- Frame :: Deserialized { symbol_address, .. } => symbol_address as * mut c_void ,
171
+ Frame :: Deserialized { symbol_address, .. } => symbol_address. into_void ( ) ,
77
172
}
78
173
}
79
174
@@ -84,7 +179,7 @@ impl Frame {
84
179
Frame :: Deserialized {
85
180
module_base_address,
86
181
..
87
- } => module_base_address. map ( |addr| addr as * mut c_void ) ,
182
+ } => module_base_address. map ( |addr| addr. into_void ( ) ) ,
88
183
}
89
184
}
90
185
@@ -94,7 +189,7 @@ impl Frame {
94
189
let sym = |symbol : & Symbol | {
95
190
symbols. push ( BacktraceSymbol {
96
191
name : symbol. name ( ) . map ( |m| m. as_bytes ( ) . to_vec ( ) ) ,
97
- addr : symbol. addr ( ) . map ( |a| a as usize ) ,
192
+ addr : symbol. addr ( ) . map ( TracePtr ) ,
98
193
filename : symbol. filename ( ) . map ( |m| m. to_owned ( ) ) ,
99
194
lineno : symbol. lineno ( ) ,
100
195
colno : symbol. colno ( ) ,
@@ -104,7 +199,7 @@ impl Frame {
104
199
Frame :: Raw ( ref f) => resolve_frame ( f, sym) ,
105
200
#[ cfg( feature = "serde" ) ]
106
201
Frame :: Deserialized { ip, .. } => {
107
- resolve ( ip as * mut c_void , sym) ;
202
+ resolve ( ip. into_void ( ) , sym) ;
108
203
}
109
204
}
110
205
symbols
@@ -124,7 +219,7 @@ impl Frame {
124
219
#[ cfg_attr( feature = "serde" , derive( Deserialize , Serialize ) ) ]
125
220
pub struct BacktraceSymbol {
126
221
name : Option < Vec < u8 > > ,
127
- addr : Option < usize > ,
222
+ addr : Option < TracePtr > ,
128
223
filename : Option < PathBuf > ,
129
224
lineno : Option < u32 > ,
130
225
colno : Option < u32 > ,
@@ -347,7 +442,7 @@ impl BacktraceSymbol {
347
442
/// This function requires the `std` feature of the `backtrace` crate to be
348
443
/// enabled, and the `std` feature is enabled by default.
349
444
pub fn addr ( & self ) -> Option < * mut c_void > {
350
- self . addr . map ( |s| s as * mut c_void )
445
+ self . addr . map ( |s| s. into_void ( ) )
351
446
}
352
447
353
448
/// Same as `Symbol::filename`
@@ -468,7 +563,7 @@ mod serde_impls {
468
563
SerializedFrame {
469
564
ip : frame. ip ( ) as usize ,
470
565
symbol_address : frame. symbol_address ( ) as usize ,
471
- module_base_address : frame. module_base_address ( ) . map ( |addr| addr as usize ) ,
566
+ module_base_address : frame. module_base_address ( ) . map ( |sym_a| sym_a as usize ) ,
472
567
symbols : symbols. clone ( ) ,
473
568
}
474
569
. serialize ( s)
@@ -483,9 +578,9 @@ mod serde_impls {
483
578
let frame: SerializedFrame = SerializedFrame :: deserialize ( d) ?;
484
579
Ok ( BacktraceFrame {
485
580
frame : Frame :: Deserialized {
486
- ip : frame. ip ,
487
- symbol_address : frame. symbol_address ,
488
- module_base_address : frame. module_base_address ,
581
+ ip : TracePtr :: from_addr ( frame. ip ) ,
582
+ symbol_address : TracePtr :: from_addr ( frame. symbol_address ) ,
583
+ module_base_address : frame. module_base_address . map ( TracePtr :: from_addr ) ,
489
584
} ,
490
585
symbols : frame. symbols ,
491
586
} )
0 commit comments