3 # Copyright (c) 2012 Nicira, Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at:
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
24 addr2line_cache = {} # None if addr2line is missing or broken.
27 def addr2line(binary, addr):
28 global addr2line_cache
30 if addr2line_cache is None:
33 if addr in addr2line_cache:
34 return addr2line_cache[addr]
36 cmd = ["addr2line", "-f", "-s", "-e", binary, addr]
38 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
39 stderr=subprocess.PIPE)
40 lines = proc.stdout.readlines()
41 failed = proc.returncode
46 addr2line_cache = None
49 lines = [l.strip() for l in lines]
50 return " ".join(lines)
54 parser = optparse.OptionParser(version='@VERSION@',
55 usage="usage: %prog [binary]",
57 Parses the output of ovs-appctl backtrace producing a more human readable
58 result. Expected usage is for ovs-appctl backtrace to be piped in.""")
59 options, args = parser.parse_args()
68 binary = "@sbindir@/ovs-vswitchd"
69 debug = "/usr/lib/debug%s.debug" % binary
70 if os.path.exists(debug):
73 print "Binary: %s\n" % binary
75 stdin = sys.stdin.read()
76 trace_list = stdin.strip().split("\n\n")
79 #Remove the first line from each trace.
80 trace_list = [trace[(trace.index("\n") + 1):] for trace in trace_list]
82 sys.stdout.write(stdin)
86 for trace in trace_list:
87 trace_map[trace] = trace_map.get(trace, 0) + 1
89 sorted_traces = sorted(trace_map.items(), key=(lambda x: x[1]),
91 for trace, count in sorted_traces:
92 lines = trace.splitlines()
93 longest = max(len(l) for l in lines)
95 print "Backtrace Count: %d" % count
97 match = re.search(r'\[(0x.*)]', line)
99 print "%s %s" % (line.ljust(longest),
100 addr2line(binary, match.group(1)))
106 if __name__ == "__main__":