@@ -68,6 +68,10 @@ def export(self, filename):
6868 return True
6969
7070
71+ # Bounded by the unwinder's maximum captured stack depth (MAX_FRAMES).
72+ _FLAMEGRAPH_RECURSION_MARGIN = 2000
73+
74+
7175class FlamegraphCollector (StackTraceCollector ):
7276 def __init__ (self , * args , ** kwargs ):
7377 super ().__init__ (* args , ** kwargs )
@@ -166,34 +170,41 @@ def set_mode(self, mode):
166170 self .stats ["mode" ] = mode
167171
168172 def export (self , filename ):
169- flamegraph_data = self ._convert_to_flamegraph_format ()
170-
171- # Debug output with string table statistics
172- num_functions = len (flamegraph_data .get ("children" , []))
173- total_time = flamegraph_data .get ("value" , 0 )
174- string_count = len (self ._string_table )
175- s1 = "" if num_functions == 1 else "s"
176- s2 = "" if total_time == 1 else "s"
177- s3 = "" if string_count == 1 else "s"
178- print (
179- f"Flamegraph data: { num_functions } root function{ s1 } , "
180- f"{ total_time } total sample{ s2 } , "
181- f"{ string_count } unique string{ s3 } "
182- )
183-
184- if num_functions == 0 :
173+ # Converting the call tree recurses to the sampled stack depth.
174+ old_limit = sys .getrecursionlimit ()
175+ sys .setrecursionlimit (old_limit + _FLAMEGRAPH_RECURSION_MARGIN )
176+ try :
177+ flamegraph_data = self ._convert_to_flamegraph_format ()
178+
179+ # Debug output with string table statistics
180+ num_functions = len (flamegraph_data .get ("children" , []))
181+ total_time = flamegraph_data .get ("value" , 0 )
182+ string_count = len (self ._string_table )
183+ s1 = "" if num_functions == 1 else "s"
184+ s2 = "" if total_time == 1 else "s"
185+ s3 = "" if string_count == 1 else "s"
185186 print (
186- "Warning: No functions found in profiling data. Check if sampling captured any data."
187+ f"Flamegraph data: { num_functions } root function{ s1 } , "
188+ f"{ total_time } total sample{ s2 } , "
189+ f"{ string_count } unique string{ s3 } "
187190 )
188- return False
189191
190- html_content = self ._create_flamegraph_html (flamegraph_data )
192+ if num_functions == 0 :
193+ print (
194+ "Warning: No functions found in profiling data. "
195+ "Check if sampling captured any data."
196+ )
197+ return False
191198
192- with open (filename , "w" , encoding = "utf-8" ) as f :
193- f .write (html_content )
199+ html_content = self ._create_flamegraph_html (flamegraph_data )
194200
195- print (f"Flamegraph saved to: { filename } " )
196- return True
201+ with open (filename , "w" , encoding = "utf-8" ) as f :
202+ f .write (html_content )
203+
204+ print (f"Flamegraph saved to: { filename } " )
205+ return True
206+ finally :
207+ sys .setrecursionlimit (old_limit )
197208
198209 @staticmethod
199210 @functools .lru_cache (maxsize = None )
0 commit comments