From 013061cfa364fe4c2f3f1f17fe90ab4b226f37df Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Mon, 15 Oct 2012 12:42:48 -0700 Subject: [PATCH] utilities: New helper ovs-parse-backtrace. The new ovs-parse-backtrace utility makes the output of ovs-appctl backtrace more human readable by removing duplicate traces and converting addresses to function names. Signed-off-by: Ethan Jackson --- debian/openvswitch-common.install | 1 + debian/openvswitch-common.manpages | 1 + rhel/openvswitch-fedora.spec.in | 2 + rhel/openvswitch.spec.in | 2 + utilities/.gitignore | 1 + utilities/automake.mk | 5 ++ utilities/ovs-parse-backtrace.8 | 28 ++++++++ utilities/ovs-parse-backtrace.in | 107 +++++++++++++++++++++++++++++ xenserver/openvswitch-xen.spec.in | 2 + 9 files changed, 149 insertions(+) create mode 100644 utilities/ovs-parse-backtrace.8 create mode 100755 utilities/ovs-parse-backtrace.in diff --git a/debian/openvswitch-common.install b/debian/openvswitch-common.install index 3b1fd93e..e2c0454a 100644 --- a/debian/openvswitch-common.install +++ b/debian/openvswitch-common.install @@ -1,6 +1,7 @@ usr/bin/ovs-appctl usr/bin/ovs-benchmark usr/bin/ovs-ofctl +usr/bin/ovs-parse-backtrace usr/bin/ovs-parse-leaks usr/bin/ovs-pki usr/bin/ovsdb-client diff --git a/debian/openvswitch-common.manpages b/debian/openvswitch-common.manpages index 1e99479c..05e93a80 100644 --- a/debian/openvswitch-common.manpages +++ b/debian/openvswitch-common.manpages @@ -5,4 +5,5 @@ _debian/utilities/ovs-benchmark.1 _debian/utilities/ovs-ofctl.8 _debian/utilities/ovs-pki.8 utilities/bugtool/ovs-bugtool.8 +utilities/ovs-parse-backtrace.8 utilities/ovs-parse-leaks.8 diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in index 04cfeec7..7918fd52 100644 --- a/rhel/openvswitch-fedora.spec.in +++ b/rhel/openvswitch-fedora.spec.in @@ -170,6 +170,7 @@ systemctl start openvswitch.service %doc /usr/share/man/man8/ovs-brcompatd.8.gz %doc /usr/share/man/man8/ovs-dpctl.8.gz %doc /usr/share/man/man8/ovs-ofctl.8.gz +%doc /usr/share/man/man8/ovs-parse-backtrace.8.gz %doc /usr/share/man/man8/ovs-parse-leaks.8.gz %doc /usr/share/man/man8/ovs-vsctl.8.gz %doc /usr/share/man/man8/ovs-vswitchd.8.gz @@ -179,6 +180,7 @@ systemctl start openvswitch.service /usr/share/openvswitch/scripts/ovs-ctl %exclude /etc/openvswitch %exclude /usr/bin/ovs-benchmark +%exclude /usr/bin/ovs-parse-backtrace %exclude /usr/bin/ovs-parse-leaks %exclude /usr/bin/ovs-pcap %exclude /usr/bin/ovs-tcpundump diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in index de22c86c..ff598b92 100644 --- a/rhel/openvswitch.spec.in +++ b/rhel/openvswitch.spec.in @@ -115,6 +115,7 @@ exit 0 /usr/bin/ovs-benchmark /usr/bin/ovs-dpctl /usr/bin/ovs-ofctl +/usr/bin/ovs-parse-backtrace /usr/bin/ovs-parse-leaks /usr/bin/ovs-pcap /usr/bin/ovs-pki @@ -140,6 +141,7 @@ exit 0 /usr/share/man/man8/ovs-ctl.8.gz /usr/share/man/man8/ovs-dpctl.8.gz /usr/share/man/man8/ovs-ofctl.8.gz +/usr/share/man/man8/ovs-parse-backtrace.8.gz /usr/share/man/man8/ovs-parse-leaks.8.gz /usr/share/man/man8/ovs-pki.8.gz /usr/share/man/man8/ovs-vlan-test.8.gz diff --git a/utilities/.gitignore b/utilities/.gitignore index 4f96a4f6..ad99dda6 100644 --- a/utilities/.gitignore +++ b/utilities/.gitignore @@ -18,6 +18,7 @@ /ovs-lib /ovs-ofctl /ovs-ofctl.8 +/ovs-parse-backtrace /ovs-parse-leaks /ovs-pcap /ovs-pcap.1 diff --git a/utilities/automake.mk b/utilities/automake.mk index 890f8671..ab8774a9 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -8,6 +8,7 @@ bin_SCRIPTS += utilities/ovs-pki utilities/ovs-parse-leaks if HAVE_PYTHON bin_SCRIPTS += \ utilities/ovs-l3ping \ + utilities/ovs-parse-backtrace \ utilities/ovs-pcap \ utilities/ovs-tcpundump \ utilities/ovs-test \ @@ -24,6 +25,7 @@ EXTRA_DIST += \ utilities/ovs-ctl.in \ utilities/ovs-l3ping.in \ utilities/ovs-lib.in \ + utilities/ovs-parse-backtrace.in \ utilities/ovs-parse-leaks.in \ utilities/ovs-pcap.in \ utilities/ovs-pki.in \ @@ -39,6 +41,7 @@ MAN_ROOTS += \ utilities/ovs-dpctl.8.in \ utilities/ovs-l3ping.8.in \ utilities/ovs-ofctl.8.in \ + utilities/ovs-parse-backtrace.8 \ utilities/ovs-parse-leaks.8 \ utilities/ovs-pcap.1.in \ utilities/ovs-pki.8.in \ @@ -59,6 +62,7 @@ DISTCLEANFILES += \ utilities/ovs-l3ping.8 \ utilities/ovs-lib \ utilities/ovs-ofctl.8 \ + utilities/ovs-parse-backtrace \ utilities/ovs-parse-leaks \ utilities/ovs-pcap \ utilities/ovs-pcap.1 \ @@ -80,6 +84,7 @@ man_MANS += \ utilities/ovs-dpctl.8 \ utilities/ovs-l3ping.8 \ utilities/ovs-ofctl.8 \ + utilities/ovs-parse-backtrace.8 \ utilities/ovs-parse-leaks.8 \ utilities/ovs-pcap.1 \ utilities/ovs-pki.8 \ diff --git a/utilities/ovs-parse-backtrace.8 b/utilities/ovs-parse-backtrace.8 new file mode 100644 index 00000000..2fa7c174 --- /dev/null +++ b/utilities/ovs-parse-backtrace.8 @@ -0,0 +1,28 @@ +.TH ovs\-parse\-backtrace 8 "October 2012" "Open vSwitch" "Open vSwitch Manual" +. +.SH NAME +ovs\-parse\-backtrace \- parses ovs-appctl backtrace output +. +.SH SYNOPSIS +\fBovs\-appctl backtrace\fR | \fBovs\-parse\-backtrace\fR [\fIbinary\fR] +.P +\fBovs\-parse\-backtrace\fR [\fIbinary\fR] < \fIbacktrace\fR +. +.SH DESCRIPTION +In some configurations, many Open vSwitch daemons can produce a series of +backtraces using the \fBovs\-appctl backtrace\fR command. Users can analyze +these backtraces to figure out what the given Open vSwitch daemon may be +spending most of its time doing. \fBovs\-parse\-backtrace\fR makes this output +easier to interpret. +.PP +The \fBovs\-appctl backtrace\fR output must be supplied on standard input. The +binary that produced the output should be supplied as the sole non-option +argument. For best results, the binary should have debug symbols. +. +.SH OPTIONS +.TP +\fB\-\-help\fR +Prints a usage message and exits. +.P +\fB\-\-version\fR +Prints the version and exits. diff --git a/utilities/ovs-parse-backtrace.in b/utilities/ovs-parse-backtrace.in new file mode 100755 index 00000000..4f793bee --- /dev/null +++ b/utilities/ovs-parse-backtrace.in @@ -0,0 +1,107 @@ +#! @PYTHON@ +# +# Copyright (c) 2012 Nicira, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import optparse +import os +import re +import subprocess +import sys + + +addr2line_cache = {} # None if addr2line is missing or broken. + + +def addr2line(binary, addr): + global addr2line_cache + + if addr2line_cache is None: + return "" + + if addr in addr2line_cache: + return addr2line_cache[addr] + + cmd = ["addr2line", "-f", "-s", "-e", binary, addr] + try: + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + lines = proc.stdout.readlines() + failed = proc.returncode + except OSError: + failed = True + + if failed: + addr2line_cache = None + return "" + + lines = [l.strip() for l in lines] + return " ".join(lines) + + +def main(): + parser = optparse.OptionParser(version='@VERSION@', + usage="usage: %prog [binary]", + description="""\ +Parses the output of ovs-appctl backtrace producing a more human readable +result. Expected usage is for ovs-appctl backtrace to be piped in.""") + options, args = parser.parse_args() + + if len(args) > 1: + parser.print_help() + sys.exit(1) + + if len(args) == 1: + binary = args[0] + else: + binary = "@sbindir@/ovs-vswitchd" + debug = "/usr/lib/debug%s.debug" % binary + if os.path.exists(debug): + binary = debug + + print "Binary: %s\n" % binary + + stdin = sys.stdin.read() + trace_list = stdin.strip().split("\n\n") + + try: + #Remove the first line from each trace. + trace_list = [trace[(trace.index("\n") + 1):] for trace in trace_list] + except ValueError: + sys.stdout.write(stdin) + sys.exit(1) + + trace_map = {} + for trace in trace_list: + trace_map[trace] = trace_map.get(trace, 0) + 1 + + sorted_traces = sorted(trace_map.items(), key=(lambda x: x[1]), + reverse=True) + for trace, count in sorted_traces: + lines = trace.splitlines() + longest = max(len(l) for l in lines) + + print "Backtrace Count: %d" % count + for line in lines: + match = re.search(r'\[(0x.*)]', line) + if match: + print "%s %s" % (line.ljust(longest), + addr2line(binary, match.group(1))) + else: + print line + print + + +if __name__ == "__main__": + main() diff --git a/xenserver/openvswitch-xen.spec.in b/xenserver/openvswitch-xen.spec.in index c34c7db8..18e421b1 100644 --- a/xenserver/openvswitch-xen.spec.in +++ b/xenserver/openvswitch-xen.spec.in @@ -428,6 +428,7 @@ exit 0 /usr/bin/ovs-appctl /usr/bin/ovs-dpctl /usr/bin/ovs-ofctl +/usr/bin/ovs-parse-backtrace /usr/bin/ovs-parse-leaks /usr/bin/ovs-pcap /usr/bin/ovs-tcpundump @@ -444,6 +445,7 @@ exit 0 /usr/share/man/man8/ovs-ctl.8.gz /usr/share/man/man8/ovs-dpctl.8.gz /usr/share/man/man8/ovs-ofctl.8.gz +/usr/share/man/man8/ovs-parse-backtrace.8.gz /usr/share/man/man8/ovs-parse-leaks.8.gz /usr/share/man/man1/ovs-pcap.1.gz /usr/share/man/man1/ovs-tcpundump.1.gz -- 2.30.2