Linux Audio

Check our new training course

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