@@ -253,20 +253,25 @@ impl ProvenanceExtra {
253253
254254/// Extra per-allocation data
255255#[ derive( Debug , Clone ) ]
256- pub struct AllocExtra {
256+ pub struct AllocExtra < ' tcx > {
257257 /// Global state of the borrow tracker, if enabled.
258258 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.
261261 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.
264264 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 > > > ,
265270}
266271
267- impl VisitTags for AllocExtra {
272+ impl VisitTags for AllocExtra < ' _ > {
268273 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 ;
270275
271276 borrow_tracker. visit_tags ( visit) ;
272277 data_race. visit_tags ( visit) ;
@@ -467,12 +472,17 @@ pub struct MiriMachine<'mir, 'tcx> {
467472 pub ( crate ) gc_interval : u32 ,
468473 /// The number of blocks that passed since the last BorTag GC pass.
469474 pub ( crate ) since_gc : u32 ,
475+
470476 /// The number of CPUs to be reported by miri.
471477 pub ( crate ) num_cpus : u32 ,
478+
472479 /// Determines Miri's page size and associated values
473480 pub ( crate ) page_size : u64 ,
474481 pub ( crate ) stack_addr : u64 ,
475482 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 ,
476486}
477487
478488impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
@@ -581,6 +591,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
581591 page_size,
582592 stack_addr,
583593 stack_size,
594+ collect_leak_backtraces : config. collect_leak_backtraces ,
584595 }
585596 }
586597
@@ -728,6 +739,7 @@ impl VisitTags for MiriMachine<'_, '_> {
728739 page_size : _,
729740 stack_addr : _,
730741 stack_size : _,
742+ collect_leak_backtraces : _,
731743 } = self ;
732744
733745 threads. visit_tags ( visit) ;
@@ -773,7 +785,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
773785 type ExtraFnVal = Dlsym ;
774786
775787 type FrameExtra = FrameExtra < ' tcx > ;
776- type AllocExtra = AllocExtra ;
788+ type AllocExtra = AllocExtra < ' tcx > ;
777789
778790 type Provenance = Provenance ;
779791 type ProvenanceExtra = ProvenanceExtra ;
@@ -967,9 +979,24 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
967979 )
968980 } ) ;
969981 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+
970992 let alloc: Allocation < Provenance , Self :: AllocExtra > = alloc. adjust_from_tcx (
971993 & 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+ } ,
9731000 |ptr| ecx. global_base_pointer ( ptr) ,
9741001 ) ?;
9751002 Ok ( Cow :: Owned ( alloc) )
@@ -1049,7 +1076,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10491076 fn before_memory_read (
10501077 _tcx : TyCtxt < ' tcx > ,
10511078 machine : & Self ,
1052- alloc_extra : & AllocExtra ,
1079+ alloc_extra : & AllocExtra < ' tcx > ,
10531080 ( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10541081 range : AllocRange ,
10551082 ) -> InterpResult < ' tcx > {
@@ -1069,7 +1096,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10691096 fn before_memory_write (
10701097 _tcx : TyCtxt < ' tcx > ,
10711098 machine : & mut Self ,
1072- alloc_extra : & mut AllocExtra ,
1099+ alloc_extra : & mut AllocExtra < ' tcx > ,
10731100 ( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10741101 range : AllocRange ,
10751102 ) -> InterpResult < ' tcx > {
@@ -1089,7 +1116,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10891116 fn before_memory_deallocation (
10901117 _tcx : TyCtxt < ' tcx > ,
10911118 machine : & mut Self ,
1092- alloc_extra : & mut AllocExtra ,
1119+ alloc_extra : & mut AllocExtra < ' tcx > ,
10931120 ( alloc_id, prove_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10941121 range : AllocRange ,
10951122 ) -> InterpResult < ' tcx > {
0 commit comments