@@ -259,20 +259,25 @@ impl ProvenanceExtra {
259259
260260/// Extra per-allocation data
261261#[ derive( Debug , Clone ) ]
262- pub struct AllocExtra {
262+ pub struct AllocExtra < ' tcx > {
263263 /// Global state of the borrow tracker, if enabled.
264264 pub borrow_tracker : Option < borrow_tracker:: AllocState > ,
265- /// Data race detection via the use of a vector-clock,
266- /// this is only added if it is enabled.
265+ /// Data race detection via the use of a vector-clock.
266+ /// This is only added if it is enabled.
267267 pub data_race : Option < data_race:: AllocState > ,
268- /// Weak memory emulation via the use of store buffers,
269- /// this is only added if it is enabled.
268+ /// Weak memory emulation via the use of store buffers.
269+ /// This is only added if it is enabled.
270270 pub weak_memory : Option < weak_memory:: AllocState > ,
271+ /// A backtrace to where this allocation was allocated.
272+ /// As this is recorded for leak reports, it only exists
273+ /// if this allocation is leakable. The backtrace is not
274+ /// pruned yet; that should be done before printing it.
275+ pub backtrace : Option < Vec < FrameInfo < ' tcx > > > ,
271276}
272277
273- impl VisitTags for AllocExtra {
278+ impl VisitTags for AllocExtra < ' _ > {
274279 fn visit_tags ( & self , visit : & mut dyn FnMut ( BorTag ) ) {
275- let AllocExtra { borrow_tracker, data_race, weak_memory } = self ;
280+ let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace : _ } = self ;
276281
277282 borrow_tracker. visit_tags ( visit) ;
278283 data_race. visit_tags ( visit) ;
@@ -473,12 +478,17 @@ pub struct MiriMachine<'mir, 'tcx> {
473478 pub ( crate ) gc_interval : u32 ,
474479 /// The number of blocks that passed since the last BorTag GC pass.
475480 pub ( crate ) since_gc : u32 ,
481+
476482 /// The number of CPUs to be reported by miri.
477483 pub ( crate ) num_cpus : u32 ,
484+
478485 /// Determines Miri's page size and associated values
479486 pub ( crate ) page_size : u64 ,
480487 pub ( crate ) stack_addr : u64 ,
481488 pub ( crate ) stack_size : u64 ,
489+
490+ /// Whether to collect a backtrace when each allocation is created, just in case it leaks.
491+ pub ( crate ) collect_leak_backtraces : bool ,
482492}
483493
484494impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
@@ -587,6 +597,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
587597 page_size,
588598 stack_addr,
589599 stack_size,
600+ collect_leak_backtraces : config. collect_leak_backtraces ,
590601 }
591602 }
592603
@@ -734,6 +745,7 @@ impl VisitTags for MiriMachine<'_, '_> {
734745 page_size : _,
735746 stack_addr : _,
736747 stack_size : _,
748+ collect_leak_backtraces : _,
737749 } = self ;
738750
739751 threads. visit_tags ( visit) ;
@@ -779,7 +791,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
779791 type ExtraFnVal = Dlsym ;
780792
781793 type FrameExtra = FrameExtra < ' tcx > ;
782- type AllocExtra = AllocExtra ;
794+ type AllocExtra = AllocExtra < ' tcx > ;
783795
784796 type Provenance = Provenance ;
785797 type ProvenanceExtra = ProvenanceExtra ;
@@ -973,9 +985,24 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
973985 )
974986 } ) ;
975987 let buffer_alloc = ecx. machine . weak_memory . then ( weak_memory:: AllocState :: new_allocation) ;
988+
989+ // If an allocation is leaked, we want to report a backtrace to indicate where it was
990+ // allocated. We don't need to record a backtrace for allocations which are allowed to
991+ // leak.
992+ let backtrace = if kind. may_leak ( ) || !ecx. machine . collect_leak_backtraces {
993+ None
994+ } else {
995+ Some ( ecx. generate_stacktrace ( ) )
996+ } ;
997+
976998 let alloc: Allocation < Provenance , Self :: AllocExtra > = alloc. adjust_from_tcx (
977999 & ecx. tcx ,
978- AllocExtra { borrow_tracker, data_race : race_alloc, weak_memory : buffer_alloc } ,
1000+ AllocExtra {
1001+ borrow_tracker,
1002+ data_race : race_alloc,
1003+ weak_memory : buffer_alloc,
1004+ backtrace,
1005+ } ,
9791006 |ptr| ecx. global_base_pointer ( ptr) ,
9801007 ) ?;
9811008 Ok ( Cow :: Owned ( alloc) )
@@ -1055,7 +1082,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10551082 fn before_memory_read (
10561083 _tcx : TyCtxt < ' tcx > ,
10571084 machine : & Self ,
1058- alloc_extra : & AllocExtra ,
1085+ alloc_extra : & AllocExtra < ' tcx > ,
10591086 ( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10601087 range : AllocRange ,
10611088 ) -> InterpResult < ' tcx > {
@@ -1075,7 +1102,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10751102 fn before_memory_write (
10761103 _tcx : TyCtxt < ' tcx > ,
10771104 machine : & mut Self ,
1078- alloc_extra : & mut AllocExtra ,
1105+ alloc_extra : & mut AllocExtra < ' tcx > ,
10791106 ( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10801107 range : AllocRange ,
10811108 ) -> InterpResult < ' tcx > {
@@ -1095,7 +1122,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10951122 fn before_memory_deallocation (
10961123 _tcx : TyCtxt < ' tcx > ,
10971124 machine : & mut Self ,
1098- alloc_extra : & mut AllocExtra ,
1125+ alloc_extra : & mut AllocExtra < ' tcx > ,
10991126 ( alloc_id, prove_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
11001127 range : AllocRange ,
11011128 ) -> InterpResult < ' tcx > {
0 commit comments