@@ -253,20 +253,24 @@ 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.
268+ pub backtrace : Option < Vec < FrameInfo < ' tcx > > > ,
265269}
266270
267- impl VisitTags for AllocExtra {
271+ impl VisitTags for AllocExtra < ' _ > {
268272 fn visit_tags ( & self , visit : & mut dyn FnMut ( BorTag ) ) {
269- let AllocExtra { borrow_tracker, data_race, weak_memory } = self ;
273+ let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace : _ } = self ;
270274
271275 borrow_tracker. visit_tags ( visit) ;
272276 data_race. visit_tags ( visit) ;
@@ -773,7 +777,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
773777 type ExtraFnVal = Dlsym ;
774778
775779 type FrameExtra = FrameExtra < ' tcx > ;
776- type AllocExtra = AllocExtra ;
780+ type AllocExtra = AllocExtra < ' tcx > ;
777781
778782 type Provenance = Provenance ;
779783 type ProvenanceExtra = ProvenanceExtra ;
@@ -967,9 +971,20 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
967971 )
968972 } ) ;
969973 let buffer_alloc = ecx. machine . weak_memory . then ( weak_memory:: AllocState :: new_allocation) ;
974+
975+ // If an allocation is leaked, we want to report a backtrace to indicate where it was
976+ // allocated. We don't need to record a backtrace for allocations which are allowed to
977+ // leak.
978+ let backtrace = if kind. may_leak ( ) { None } else { Some ( ecx. generate_stacktrace ( ) ) } ;
979+
970980 let alloc: Allocation < Provenance , Self :: AllocExtra > = alloc. adjust_from_tcx (
971981 & ecx. tcx ,
972- AllocExtra { borrow_tracker, data_race : race_alloc, weak_memory : buffer_alloc } ,
982+ AllocExtra {
983+ borrow_tracker,
984+ data_race : race_alloc,
985+ weak_memory : buffer_alloc,
986+ backtrace,
987+ } ,
973988 |ptr| ecx. global_base_pointer ( ptr) ,
974989 ) ?;
975990 Ok ( Cow :: Owned ( alloc) )
@@ -1049,7 +1064,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10491064 fn before_memory_read (
10501065 _tcx : TyCtxt < ' tcx > ,
10511066 machine : & Self ,
1052- alloc_extra : & AllocExtra ,
1067+ alloc_extra : & AllocExtra < ' tcx > ,
10531068 ( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10541069 range : AllocRange ,
10551070 ) -> InterpResult < ' tcx > {
@@ -1069,7 +1084,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10691084 fn before_memory_write (
10701085 _tcx : TyCtxt < ' tcx > ,
10711086 machine : & mut Self ,
1072- alloc_extra : & mut AllocExtra ,
1087+ alloc_extra : & mut AllocExtra < ' tcx > ,
10731088 ( alloc_id, prov_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10741089 range : AllocRange ,
10751090 ) -> InterpResult < ' tcx > {
@@ -1089,7 +1104,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10891104 fn before_memory_deallocation (
10901105 _tcx : TyCtxt < ' tcx > ,
10911106 machine : & mut Self ,
1092- alloc_extra : & mut AllocExtra ,
1107+ alloc_extra : & mut AllocExtra < ' tcx > ,
10931108 ( alloc_id, prove_extra) : ( AllocId , Self :: ProvenanceExtra ) ,
10941109 range : AllocRange ,
10951110 ) -> InterpResult < ' tcx > {
0 commit comments