@@ -253,20 +253,25 @@ impl ProvenanceExtra {
253
253
254
254
/// Extra per-allocation data
255
255
#[ derive( Debug , Clone ) ]
256
- pub struct AllocExtra {
256
+ pub struct AllocExtra < ' tcx > {
257
257
/// Global state of the borrow tracker, if enabled.
258
258
pub borrow_tracker : Option < borrow_tracker:: AllocState > ,
259
- /// Data race detection via the use of a vector-clock,
260
- /// this is only added if it is enabled.
259
+ /// Data race detection via the use of a vector-clock.
260
+ /// This is only added if it is enabled.
261
261
pub data_race : Option < data_race:: AllocState > ,
262
- /// Weak memory emulation via the use of store buffers,
263
- /// this is only added if it is enabled.
262
+ /// Weak memory emulation via the use of store buffers.
263
+ /// This is only added if it is enabled.
264
264
pub weak_memory : Option < weak_memory:: AllocState > ,
265
+ /// A backtrace to where this allocation was allocated.
266
+ /// As this is recorded for leak reports, it only exists
267
+ /// if this allocation is leakable. The backtrace is not
268
+ /// pruned yet; that should be done before printing it.
269
+ pub backtrace : Option < Vec < FrameInfo < ' tcx > > > ,
265
270
}
266
271
267
- impl VisitTags for AllocExtra {
272
+ impl VisitTags for AllocExtra < ' _ > {
268
273
fn visit_tags ( & self , visit : & mut dyn FnMut ( BorTag ) ) {
269
- let AllocExtra { borrow_tracker, data_race, weak_memory } = self ;
274
+ let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace : _ } = self ;
270
275
271
276
borrow_tracker. visit_tags ( visit) ;
272
277
data_race. visit_tags ( visit) ;
@@ -467,12 +472,17 @@ pub struct MiriMachine<'mir, 'tcx> {
467
472
pub ( crate ) gc_interval : u32 ,
468
473
/// The number of blocks that passed since the last BorTag GC pass.
469
474
pub ( crate ) since_gc : u32 ,
475
+
470
476
/// The number of CPUs to be reported by miri.
471
477
pub ( crate ) num_cpus : u32 ,
478
+
472
479
/// Determines Miri's page size and associated values
473
480
pub ( crate ) page_size : u64 ,
474
481
pub ( crate ) stack_addr : u64 ,
475
482
pub ( crate ) stack_size : u64 ,
483
+
484
+ /// Whether to collect a backtrace when each allocation is created, just in case it leaks.
485
+ pub ( crate ) collect_leak_backtraces : bool ,
476
486
}
477
487
478
488
impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
@@ -581,6 +591,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
581
591
page_size,
582
592
stack_addr,
583
593
stack_size,
594
+ collect_leak_backtraces : config. collect_leak_backtraces ,
584
595
}
585
596
}
586
597
@@ -728,6 +739,7 @@ impl VisitTags for MiriMachine<'_, '_> {
728
739
page_size : _,
729
740
stack_addr : _,
730
741
stack_size : _,
742
+ collect_leak_backtraces : _,
731
743
} = self ;
732
744
733
745
threads. visit_tags ( visit) ;
@@ -773,7 +785,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
773
785
type ExtraFnVal = Dlsym ;
774
786
775
787
type FrameExtra = FrameExtra < ' tcx > ;
776
- type AllocExtra = AllocExtra ;
788
+ type AllocExtra = AllocExtra < ' tcx > ;
777
789
778
790
type Provenance = Provenance ;
779
791
type ProvenanceExtra = ProvenanceExtra ;
@@ -967,9 +979,24 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
967
979
)
968
980
} ) ;
969
981
let buffer_alloc = ecx. machine . weak_memory . then ( weak_memory:: AllocState :: new_allocation) ;
982
+
983
+ // If an allocation is leaked, we want to report a backtrace to indicate where it was
984
+ // allocated. We don't need to record a backtrace for allocations which are allowed to
985
+ // leak.
986
+ let backtrace = if kind. may_leak ( ) || !ecx. machine . collect_leak_backtraces {
987
+ None
988
+ } else {
989
+ Some ( ecx. generate_stacktrace ( ) )
990
+ } ;
991
+
970
992
let alloc: Allocation < Provenance , Self :: AllocExtra > = alloc. adjust_from_tcx (
971
993
& ecx. tcx ,
972
- AllocExtra { borrow_tracker, data_race : race_alloc, weak_memory : buffer_alloc } ,
994
+ AllocExtra {
995
+ borrow_tracker,
996
+ data_race : race_alloc,
997
+ weak_memory : buffer_alloc,
998
+ backtrace,
999
+ } ,
973
1000
|ptr| ecx. global_base_pointer ( ptr) ,
974
1001
) ?;
975
1002
Ok ( Cow :: Owned ( alloc) )
@@ -1049,7 +1076,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1049
1076
fn before_memory_read (
1050
1077
_tcx : TyCtxt < ' tcx > ,
1051
1078
machine : & Self ,
1052
- alloc_extra : & AllocExtra ,
1079
+ alloc_extra : & AllocExtra < ' tcx > ,
1053
1080
( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
1054
1081
range : AllocRange ,
1055
1082
) -> InterpResult < ' tcx > {
@@ -1069,7 +1096,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1069
1096
fn before_memory_write (
1070
1097
_tcx : TyCtxt < ' tcx > ,
1071
1098
machine : & mut Self ,
1072
- alloc_extra : & mut AllocExtra ,
1099
+ alloc_extra : & mut AllocExtra < ' tcx > ,
1073
1100
( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
1074
1101
range : AllocRange ,
1075
1102
) -> InterpResult < ' tcx > {
@@ -1089,7 +1116,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1089
1116
fn before_memory_deallocation (
1090
1117
_tcx : TyCtxt < ' tcx > ,
1091
1118
machine : & mut Self ,
1092
- alloc_extra : & mut AllocExtra ,
1119
+ alloc_extra : & mut AllocExtra < ' tcx > ,
1093
1120
( alloc_id, prove_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
1094
1121
range : AllocRange ,
1095
1122
) -> InterpResult < ' tcx > {
0 commit comments