~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/scripts/python/flamegraph.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/perf/scripts/python/flamegraph.py (Version linux-6.12-rc7) and /tools/perf/scripts/python/flamegraph.py (Version linux-5.4.285)


  1 # flamegraph.py - create flame graphs from per    
  2 # SPDX-License-Identifier: GPL-2.0                
  3 #                                                 
  4 # Usage:                                          
  5 #                                                 
  6 #     perf record -a -g -F 99 sleep 60            
  7 #     perf script report flamegraph               
  8 #                                                 
  9 # Combined:                                       
 10 #                                                 
 11 #     perf script flamegraph -a -F 99 sleep 60    
 12 #                                                 
 13 # Written by Andreas Gerstmayr <agerstmayr@redh    
 14 # Flame Graphs invented by Brendan Gregg <bgreg    
 15 # Works in tandem with d3-flame-graph by Marti<    
 16 #                                                 
 17 # pylint: disable=missing-module-docstring        
 18 # pylint: disable=missing-class-docstring         
 19 # pylint: disable=missing-function-docstring      
 20                                                   
 21 from __future__ import print_function             
 22 import argparse                                   
 23 import hashlib                                    
 24 import io                                         
 25 import json                                       
 26 import os                                         
 27 import subprocess                                 
 28 import sys                                        
 29 import urllib.request                             
 30                                                   
 31 minimal_html = """<head>                          
 32   <https://cdn.jsdelivr.net/npm/d3-flame-graph@    
 33 </head>                                           
 34 <body>                                            
 35   <div id="chart"></div>                          
 36   <script type="text/javascript" src="https://    
 37   <https://cdn.jsdelivr.net/npm/d3-flame-graph@    
 38   <script type="text/javascript">                 
 39   const stacks = [/** @flamegraph_json **/];      
 40   // Note, options is unused.                     
 41   const options = [/** @options_json **/];        
 42                                                   
 43   var chart = flamegraph();                       
 44   d3.select("#chart")                             
 45         .datum(stacks[0])                         
 46         .call(chart);                             
 47   </script>                                       
 48 </body>                                           
 49 """                                               
 50                                                   
 51 # pylint: disable=too-few-public-methods          
 52 class Node:                                       
 53     def __init__(self, name, libtype):            
 54         self.name = name                          
 55         # "root" | "kernel" | ""                  
 56         # "" indicates user space                 
 57         self.libtype = libtype                    
 58         self.value = 0                            
 59         self.children = []                        
 60                                                   
 61     def to_json(self):                            
 62         return {                                  
 63             "n": self.name,                       
 64             "l": self.libtype,                    
 65             "v": self.value,                      
 66             "c": self.children                    
 67         }                                         
 68                                                   
 69                                                   
 70 class FlameGraphCLI:                              
 71     def __init__(self, args):                     
 72         self.args = args                          
 73         self.stack = Node("all", "root")          
 74                                                   
 75     @staticmethod                                 
 76     def get_libtype_from_dso(dso):                
 77         """                                       
 78         when kernel-debuginfo is installed,       
 79         dso points to /usr/lib/debug/lib/modul    
 80         """                                       
 81         if dso and (dso == "[kernel.kallsyms]"    
 82             return "kernel"                       
 83                                                   
 84         return ""                                 
 85                                                   
 86     @staticmethod                                 
 87     def find_or_create_node(node, name, libtyp    
 88         for child in node.children:               
 89             if child.name == name:                
 90                 return child                      
 91                                                   
 92         child = Node(name, libtype)               
 93         node.children.append(child)               
 94         return child                              
 95                                                   
 96     def process_event(self, event):               
 97         pid = event.get("sample", {}).get("pid    
 98         # event["dso"] sometimes contains /usr    
 99         # for user-space processes; let's use     
100         if pid == 0:                              
101             comm = event["comm"]                  
102             libtype = "kernel"                    
103         else:                                     
104             comm = "{} ({})".format(event["com    
105             libtype = ""                          
106         node = self.find_or_create_node(self.s    
107                                                   
108         if "callchain" in event:                  
109             for entry in reversed(event["callc    
110                 name = entry.get("sym", {}).ge    
111                 libtype = self.get_libtype_fro    
112                 node = self.find_or_create_nod    
113         else:                                     
114             name = event.get("symbol", "[unkno    
115             libtype = self.get_libtype_from_ds    
116             node = self.find_or_create_node(no    
117         node.value += 1                           
118                                                   
119     def get_report_header(self):                  
120         if self.args.input == "-":                
121             # when this script is invoked with    
122             # no perf.data is created and we c    
123             return ""                             
124                                                   
125         try:                                      
126             output = subprocess.check_output([    
127             return output.decode("utf-8")         
128         except Exception as err:  # pylint: di    
129             print("Error reading report header    
130             return ""                             
131                                                   
132     def trace_end(self):                          
133         stacks_json = json.dumps(self.stack, d    
134                                                   
135         if self.args.format == "html":            
136             report_header = self.get_report_he    
137             options = {                           
138                 "colorscheme": self.args.color    
139                 "context": report_header          
140             }                                     
141             options_json = json.dumps(options)    
142                                                   
143             template_md5sum = None                
144             if self.args.format == "html":        
145                 if os.path.isfile(self.args.te    
146                     template = f"file://{self.    
147                 else:                             
148                     if not self.args.allow_dow    
149                         print(f"""Warning: Fla    
150 does not exist. To avoid this please install a    
151 js-d3-flame-graph or libjs-d3-flame-graph, spe    
152 graph template (--template PATH) or use anothe    
153 FORMAT).""",                                      
154                               file=sys.stderr)    
155                         if self.args.input ==     
156                             print("""Not attem    
157 input is disabled due to using live mode. If y    
158 template retry without live mode. For example,    
159 -F 99 sleep 60' and 'perf script report flameg    
160 download the template from:                       
161 https://cdn.jsdelivr.net/npm/d3-flame-graph@4.    
162 and place it at:                                  
163 /usr/share/d3-flame-graph/d3-flamegraph-base.h    
164                                   file=sys.std    
165                             quit()                
166                         s = None                  
167                         while s != "y" and s !    
168                             s = input("Do you     
169                         if s == "n":              
170                             quit()                
171                     template = "https://cdn.js    
172                     template_md5sum = "143e0d0    
173                                                   
174             try:                                  
175                 with urllib.request.urlopen(te    
176                     output_str = "".join([        
177                         l.decode("utf-8") for     
178                     ])                            
179             except Exception as err:              
180                 print(f"Error reading template    
181                       "a minimal flame graph w    
182                 output_str = minimal_html         
183                 template_md5sum = None            
184                                                   
185             if template_md5sum:                   
186                 download_md5sum = hashlib.md5(    
187                 if download_md5sum != template    
188                     s = None                      
189                     while s != "y" and s != "n    
190                         s = input(f"""Unexpect    
191 {download_md5sum} != {template_md5sum}, for:      
192 {output_str}                                      
193 continue?[yn] """).lower()                        
194                     if s == "n":                  
195                         quit()                    
196                                                   
197             output_str = output_str.replace("/    
198             output_str = output_str.replace("/    
199                                                   
200             output_fn = self.args.output or "f    
201         else:                                     
202             output_str = stacks_json              
203             output_fn = self.args.output or "s    
204                                                   
205         if output_fn == "-":                      
206             with io.open(sys.stdout.fileno(),     
207                 out.write(output_str)             
208         else:                                     
209             print("dumping data to {}".format(    
210             try:                                  
211                 with io.open(output_fn, "w", e    
212                     out.write(output_str)         
213             except IOError as err:                
214                 print("Error writing output fi    
215                 sys.exit(1)                       
216                                                   
217                                                   
218 if __name__ == "__main__":                        
219     parser = argparse.ArgumentParser(descripti    
220     parser.add_argument("-f", "--format",         
221                         default="html", choice    
222                         help="output file form    
223     parser.add_argument("-o", "--output",         
224                         help="output file name    
225     parser.add_argument("--template",             
226                         default="/usr/share/d3    
227                         help="path to flame gr    
228     parser.add_argument("--colorscheme",          
229                         default="blue-green",     
230                         help="flame graph colo    
231                         choices=["blue-green",    
232     parser.add_argument("-i", "--input",          
233                         help=argparse.SUPPRESS    
234     parser.add_argument("--allow-download",       
235                         default=False,            
236                         action="store_true",      
237                         help="allow unprompted    
238                                                   
239     cli_args = parser.parse_args()                
240     cli = FlameGraphCLI(cli_args)                 
241                                                   
242     process_event = cli.process_event             
243     trace_end = cli.trace_end                     
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php