@@ -262,14 +262,7 @@ def extract_stack(
262
262
frames = deque (maxlen = max_stack_depth ) # type: Deque[FrameType]
263
263
264
264
while frame is not None :
265
- try :
266
- f_back = frame .f_back
267
- except AttributeError :
268
- capture_internal_exception (sys .exc_info ())
269
- # For some reason, the frame we got isn't a `FrameType` and doesn't
270
- # have a `f_back`. When this happens, we continue with any frames
271
- # that we've managed to extract up to this point.
272
- break
265
+ f_back = frame .f_back
273
266
frames .append (frame )
274
267
frame = f_back
275
268
@@ -638,30 +631,35 @@ def write(self, cwd, ts, sample, frame_cache):
638
631
elapsed_since_start_ns = str (offset )
639
632
640
633
for tid , (stack_id , raw_stack , frames ) in sample :
641
- # Check if the stack is indexed first, this lets us skip
642
- # indexing frames if it's not necessary
643
- if stack_id not in self .indexed_stacks :
644
- for i , raw_frame in enumerate (raw_stack ):
645
- if raw_frame not in self .indexed_frames :
646
- self .indexed_frames [raw_frame ] = len (self .indexed_frames )
647
- processed_frame = frame_cache .get (raw_frame )
648
- if processed_frame is None :
649
- processed_frame = extract_frame (frames [i ], cwd )
650
- frame_cache [raw_frame ] = processed_frame
651
- self .frames .append (processed_frame )
652
-
653
- self .indexed_stacks [stack_id ] = len (self .indexed_stacks )
654
- self .stacks .append (
655
- [self .indexed_frames [raw_frame ] for raw_frame in raw_stack ]
634
+ try :
635
+ # Check if the stack is indexed first, this lets us skip
636
+ # indexing frames if it's not necessary
637
+ if stack_id not in self .indexed_stacks :
638
+ for i , raw_frame in enumerate (raw_stack ):
639
+ if raw_frame not in self .indexed_frames :
640
+ self .indexed_frames [raw_frame ] = len (self .indexed_frames )
641
+ processed_frame = frame_cache .get (raw_frame )
642
+ if processed_frame is None :
643
+ processed_frame = extract_frame (frames [i ], cwd )
644
+ frame_cache [raw_frame ] = processed_frame
645
+ self .frames .append (processed_frame )
646
+
647
+ self .indexed_stacks [stack_id ] = len (self .indexed_stacks )
648
+ self .stacks .append (
649
+ [self .indexed_frames [raw_frame ] for raw_frame in raw_stack ]
650
+ )
651
+
652
+ self .samples .append (
653
+ {
654
+ "elapsed_since_start_ns" : elapsed_since_start_ns ,
655
+ "thread_id" : tid ,
656
+ "stack_id" : self .indexed_stacks [stack_id ],
657
+ }
656
658
)
657
-
658
- self .samples .append (
659
- {
660
- "elapsed_since_start_ns" : elapsed_since_start_ns ,
661
- "thread_id" : tid ,
662
- "stack_id" : self .indexed_stacks [stack_id ],
663
- }
664
- )
659
+ except AttributeError :
660
+ # For some reason, the frame we get doesn't have certain attributes.
661
+ # When this happens, we abandon the current sample as it's bad.
662
+ capture_internal_exception (sys .exc_info ())
665
663
666
664
def process (self ):
667
665
# type: () -> ProcessedProfile
@@ -825,10 +823,21 @@ def _sample_stack(*args, **kwargs):
825
823
826
824
now = nanosecond_time ()
827
825
828
- raw_sample = {
829
- tid : extract_stack (frame , last_sample [0 ].get (tid ))
830
- for tid , frame in sys ._current_frames ().items ()
831
- }
826
+ try :
827
+ raw_sample = {
828
+ tid : extract_stack (frame , last_sample [0 ].get (tid ))
829
+ for tid , frame in sys ._current_frames ().items ()
830
+ }
831
+ except AttributeError :
832
+ # For some reason, the frame we get doesn't have certain attributes.
833
+ # When this happens, we abandon the current sample as it's bad.
834
+ capture_internal_exception (sys .exc_info ())
835
+
836
+ # make sure to clear the cache if something went wrong when extracting
837
+ # the stack so we dont keep a reference to the last stack of frames around
838
+ last_sample [0 ] = {}
839
+
840
+ return
832
841
833
842
# make sure to update the last sample so the cache has
834
843
# the most recent stack for better cache hits
0 commit comments