@@ -48,8 +48,41 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
48
48
FxHashMap < ( Ty < ' tcx > , Option < ty:: PolyExistentialTraitRef < ' tcx > > ) , Pointer < M :: PointerTag > > ,
49
49
}
50
50
51
+ // The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
52
+ // boundary and dropped in the other thread, it would exit the span in the other thread.
53
+ struct SpanGuard ( tracing:: Span , std:: marker:: PhantomData < * const u8 > ) ;
54
+
55
+ impl SpanGuard {
56
+ /// By default a `SpanGuard` does nothing.
57
+ fn new ( ) -> Self {
58
+ Self ( tracing:: Span :: none ( ) , std:: marker:: PhantomData )
59
+ }
60
+
61
+ /// If a span is entered, we exit the previous span (if any, normally none) and enter the
62
+ /// new span. This is mainly so we don't have to use `Option` for the `tracing_span` field of
63
+ /// `Frame` by creating a dummy span to being with and then entering it once the frame has
64
+ /// been pushed.
65
+ fn enter ( & mut self , span : tracing:: Span ) {
66
+ // This executes the destructor on the previous instance of `SpanGuard`, ensuring that
67
+ // we never enter or exit more spans than vice versa. Unless you `mem::leak`, then we
68
+ // can't protect the tracing stack, but that'll just lead to weird logging, no actual
69
+ // problems.
70
+ * self = Self ( span, std:: marker:: PhantomData ) ;
71
+ self . 0 . with_subscriber ( |( id, dispatch) | {
72
+ dispatch. enter ( id) ;
73
+ } ) ;
74
+ }
75
+ }
76
+
77
+ impl Drop for SpanGuard {
78
+ fn drop ( & mut self ) {
79
+ self . 0 . with_subscriber ( |( id, dispatch) | {
80
+ dispatch. exit ( id) ;
81
+ } ) ;
82
+ }
83
+ }
84
+
51
85
/// A stack frame.
52
- #[ derive( Clone ) ]
53
86
pub struct Frame < ' mir , ' tcx , Tag = ( ) , Extra = ( ) > {
54
87
////////////////////////////////////////////////////////////////////////////////
55
88
// Function and callsite information
@@ -80,6 +113,11 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> {
80
113
/// can either directly contain `Scalar` or refer to some part of an `Allocation`.
81
114
pub locals : IndexVec < mir:: Local , LocalState < ' tcx , Tag > > ,
82
115
116
+ /// The span of the `tracing` crate is stored here.
117
+ /// When the guard is dropped, the span is exited. This gives us
118
+ /// a full stack trace on all tracing statements.
119
+ tracing_span : SpanGuard ,
120
+
83
121
////////////////////////////////////////////////////////////////////////////////
84
122
// Current position within the function
85
123
////////////////////////////////////////////////////////////////////////////////
@@ -184,6 +222,7 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
184
222
locals : self . locals ,
185
223
loc : self . loc ,
186
224
extra,
225
+ tracing_span : self . tracing_span ,
187
226
}
188
227
}
189
228
}
@@ -637,11 +676,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
637
676
return_place : Option < PlaceTy < ' tcx , M :: PointerTag > > ,
638
677
return_to_block : StackPopCleanup ,
639
678
) -> InterpResult < ' tcx > {
640
- if !self . stack ( ) . is_empty ( ) {
641
- info ! ( "PAUSING({}) {}" , self . frame_idx( ) , self . frame( ) . instance) ;
642
- }
643
- :: log_settings:: settings ( ) . indentation += 1 ;
644
-
645
679
// first push a stack frame so we have access to the local substs
646
680
let pre_frame = Frame {
647
681
body,
@@ -652,6 +686,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
652
686
// all methods actually know about the frame
653
687
locals : IndexVec :: new ( ) ,
654
688
instance,
689
+ tracing_span : SpanGuard :: new ( ) ,
655
690
extra : ( ) ,
656
691
} ;
657
692
let frame = M :: init_frame_extra ( self , pre_frame) ?;
@@ -696,7 +731,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
696
731
self . frame_mut ( ) . locals = locals;
697
732
M :: after_stack_push ( self ) ?;
698
733
self . frame_mut ( ) . loc = Ok ( mir:: Location :: START ) ;
699
- info ! ( "ENTERING({}) {}" , self . frame_idx( ) , self . frame( ) . instance) ;
734
+
735
+ let span = info_span ! ( "frame" , "{}" , instance) ;
736
+ self . frame_mut ( ) . tracing_span . enter ( span) ;
700
737
701
738
Ok ( ( ) )
702
739
}
@@ -746,12 +783,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
746
783
/// The cleanup block ends with a special `Resume` terminator, which will
747
784
/// cause us to continue unwinding.
748
785
pub ( super ) fn pop_stack_frame ( & mut self , unwinding : bool ) -> InterpResult < ' tcx > {
749
- info ! (
750
- "LEAVING({}) {} (unwinding = {})" ,
751
- self . frame_idx( ) ,
752
- self . frame( ) . instance,
753
- unwinding
754
- ) ;
786
+ info ! ( unwinding) ;
755
787
756
788
// Sanity check `unwinding`.
757
789
assert_eq ! (
@@ -766,7 +798,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
766
798
throw_ub_format ! ( "unwinding past the topmost frame of the stack" ) ;
767
799
}
768
800
769
- :: log_settings:: settings ( ) . indentation -= 1 ;
770
801
let frame =
771
802
self . stack_mut ( ) . pop ( ) . expect ( "tried to pop a stack frame, but there were none" ) ;
772
803
@@ -824,12 +855,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
824
855
}
825
856
826
857
if !self . stack ( ) . is_empty ( ) {
827
- info ! (
828
- "CONTINUING({}) {} (unwinding = {})" ,
829
- self . frame_idx( ) ,
830
- self . frame( ) . instance,
831
- unwinding
832
- ) ;
858
+ info ! ( unwinding) ;
833
859
}
834
860
835
861
Ok ( ( ) )
@@ -995,7 +1021,16 @@ where
995
1021
{
996
1022
fn hash_stable ( & self , hcx : & mut StableHashingContext < ' ctx > , hasher : & mut StableHasher ) {
997
1023
// Exhaustive match on fields to make sure we forget no field.
998
- let Frame { body, instance, return_to_block, return_place, locals, loc, extra } = self ;
1024
+ let Frame {
1025
+ body,
1026
+ instance,
1027
+ return_to_block,
1028
+ return_place,
1029
+ locals,
1030
+ loc,
1031
+ extra,
1032
+ tracing_span : _,
1033
+ } = self ;
999
1034
body. hash_stable ( hcx, hasher) ;
1000
1035
instance. hash_stable ( hcx, hasher) ;
1001
1036
return_to_block. hash_stable ( hcx, hasher) ;
0 commit comments