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

TOMOYO Linux Cross Reference
Linux/scripts/tracing/draw_functrace.py

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/tracing/draw_functrace.py (Version linux-6.11.5) and /scripts/tracing/draw_functrace.py (Version linux-5.17.15)


  1 #!/usr/bin/env python                               1 #!/usr/bin/env python
  2 # SPDX-License-Identifier: GPL-2.0-only             2 # SPDX-License-Identifier: GPL-2.0-only
  3                                                     3 
  4 """                                                 4 """
  5 Copyright 2008 (c) Frederic Weisbecker <fweisbe      5 Copyright 2008 (c) Frederic Weisbecker <fweisbec@gmail.com>
  6                                                     6 
  7 This script parses a trace provided by the fun      7 This script parses a trace provided by the function tracer in
  8 kernel/trace/trace_functions.c                      8 kernel/trace/trace_functions.c
  9 The resulted trace is processed into a tree to      9 The resulted trace is processed into a tree to produce a more human
 10 view of the call stack by drawing textual but      10 view of the call stack by drawing textual but hierarchical tree of
 11 calls. Only the functions's names and the call !!  11 calls. Only the functions's names and the the call time are provided.
 12                                                    12 
 13 Usage:                                             13 Usage:
 14         Be sure that you have CONFIG_FUNCTION_     14         Be sure that you have CONFIG_FUNCTION_TRACER
 15         # mount -t tracefs nodev /sys/kernel/t !!  15         # mount -t debugfs nodev /sys/kernel/debug
 16         # echo function > /sys/kernel/tracing/ !!  16         # echo function > /sys/kernel/debug/tracing/current_tracer
 17         $ cat /sys/kernel/tracing/trace_pipe > !!  17         $ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func
 18         Wait some times but not too much, the      18         Wait some times but not too much, the script is a bit slow.
 19         Break the pipe (Ctrl + Z)                  19         Break the pipe (Ctrl + Z)
 20         $ scripts/tracing/draw_functrace.py <      20         $ scripts/tracing/draw_functrace.py < ~/raw_trace_func > draw_functrace
 21         Then you have your drawn trace in draw     21         Then you have your drawn trace in draw_functrace
 22 """                                                22 """
 23                                                    23 
 24                                                    24 
 25 import sys, re                                     25 import sys, re
 26                                                    26 
 27 class CallTree:                                    27 class CallTree:
 28         """ This class provides a tree represe     28         """ This class provides a tree representation of the functions
 29                 call stack. If a function has      29                 call stack. If a function has no parent in the kernel (interrupt,
 30                 syscall, kernel thread...) the     30                 syscall, kernel thread...) then it is attached to a virtual parent
 31                 called ROOT.                       31                 called ROOT.
 32         """                                        32         """
 33         ROOT = None                                33         ROOT = None
 34                                                    34 
 35         def __init__(self, func, time = None,      35         def __init__(self, func, time = None, parent = None):
 36                 self._func = func                  36                 self._func = func
 37                 self._time = time                  37                 self._time = time
 38                 if parent is None:                 38                 if parent is None:
 39                         self._parent = CallTre     39                         self._parent = CallTree.ROOT
 40                 else:                              40                 else:
 41                         self._parent = parent      41                         self._parent = parent
 42                 self._children = []                42                 self._children = []
 43                                                    43 
 44         def calls(self, func, calltime):           44         def calls(self, func, calltime):
 45                 """ If a function calls anothe     45                 """ If a function calls another one, call this method to insert it
 46                         into the tree at the a     46                         into the tree at the appropriate place.
 47                         @return: A reference t     47                         @return: A reference to the newly created child node.
 48                 """                                48                 """
 49                 child = CallTree(func, calltim     49                 child = CallTree(func, calltime, self)
 50                 self._children.append(child)       50                 self._children.append(child)
 51                 return child                       51                 return child
 52                                                    52 
 53         def getParent(self, func):                 53         def getParent(self, func):
 54                 """ Retrieve the last parent o     54                 """ Retrieve the last parent of the current node that
 55                         has the name given by      55                         has the name given by func. If this function is not
 56                         on a parent, then crea     56                         on a parent, then create it as new child of root
 57                         @return: A reference t     57                         @return: A reference to the parent.
 58                 """                                58                 """
 59                 tree = self                        59                 tree = self
 60                 while tree != CallTree.ROOT an     60                 while tree != CallTree.ROOT and tree._func != func:
 61                         tree = tree._parent        61                         tree = tree._parent
 62                 if tree == CallTree.ROOT:          62                 if tree == CallTree.ROOT:
 63                         child = CallTree.ROOT.     63                         child = CallTree.ROOT.calls(func, None)
 64                         return child               64                         return child
 65                 return tree                        65                 return tree
 66                                                    66 
 67         def __repr__(self):                        67         def __repr__(self):
 68                 return self.__toString("", Tru     68                 return self.__toString("", True)
 69                                                    69 
 70         def __toString(self, branch, lastChild     70         def __toString(self, branch, lastChild):
 71                 if self._time is not None:         71                 if self._time is not None:
 72                         s = "%s----%s (%s)\n"      72                         s = "%s----%s (%s)\n" % (branch, self._func, self._time)
 73                 else:                              73                 else:
 74                         s = "%s----%s\n" % (br     74                         s = "%s----%s\n" % (branch, self._func)
 75                                                    75 
 76                 i = 0                              76                 i = 0
 77                 if lastChild:                      77                 if lastChild:
 78                         branch = branch[:-1] +     78                         branch = branch[:-1] + " "
 79                 while i < len(self._children):     79                 while i < len(self._children):
 80                         if i != len(self._chil     80                         if i != len(self._children) - 1:
 81                                 s += "%s" % se     81                                 s += "%s" % self._children[i].__toString(branch +\
 82                                                    82                                                                 "    |", False)
 83                         else:                      83                         else:
 84                                 s += "%s" % se     84                                 s += "%s" % self._children[i].__toString(branch +\
 85                                                    85                                                                 "    |", True)
 86                         i += 1                     86                         i += 1
 87                 return s                           87                 return s
 88                                                    88 
 89 class BrokenLineException(Exception):              89 class BrokenLineException(Exception):
 90         """If the last line is not complete be     90         """If the last line is not complete because of the pipe breakage,
 91            we want to stop the processing and      91            we want to stop the processing and ignore this line.
 92         """                                        92         """
 93         pass                                       93         pass
 94                                                    94 
 95 class CommentLineException(Exception):             95 class CommentLineException(Exception):
 96         """ If the line is a comment (as in th     96         """ If the line is a comment (as in the beginning of the trace file),
 97             just ignore it.                        97             just ignore it.
 98         """                                        98         """
 99         pass                                       99         pass
100                                                   100 
101                                                   101 
102 def parseLine(line):                              102 def parseLine(line):
103         line = line.strip()                       103         line = line.strip()
104         if line.startswith("#"):                  104         if line.startswith("#"):
105                 raise CommentLineException        105                 raise CommentLineException
106         m = re.match("[^]]+?\\] +([a-z.]+) +([    106         m = re.match("[^]]+?\\] +([a-z.]+) +([0-9.]+): (\\w+) <-(\\w+)", line)
107         if m is None:                             107         if m is None:
108                 raise BrokenLineException         108                 raise BrokenLineException
109         return (m.group(2), m.group(3), m.grou    109         return (m.group(2), m.group(3), m.group(4))
110                                                   110 
111                                                   111 
112 def main():                                       112 def main():
113         CallTree.ROOT = CallTree("Root (Nowher    113         CallTree.ROOT = CallTree("Root (Nowhere)", None, None)
114         tree = CallTree.ROOT                      114         tree = CallTree.ROOT
115                                                   115 
116         for line in sys.stdin:                    116         for line in sys.stdin:
117                 try:                              117                 try:
118                         calltime, callee, call    118                         calltime, callee, caller = parseLine(line)
119                 except BrokenLineException:       119                 except BrokenLineException:
120                         break                     120                         break
121                 except CommentLineException:      121                 except CommentLineException:
122                         continue                  122                         continue
123                 tree = tree.getParent(caller)     123                 tree = tree.getParent(caller)
124                 tree = tree.calls(callee, call    124                 tree = tree.calls(callee, calltime)
125                                                   125 
126         print(CallTree.ROOT)                      126         print(CallTree.ROOT)
127                                                   127 
128 if __name__ == "__main__":                        128 if __name__ == "__main__":
129         main()                                    129         main()
                                                      

~ [ 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