Nice! Few notes inline On Mon, Oct 15, 2012 at 3:22 PM, Ethan Jackson <et...@nicira.com> wrote: > The new ovs-backtrace-parse 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 <et...@nicira.com> > --- > utilities/.gitignore | 1 + > utilities/automake.mk | 2 + > utilities/ovs-backtrace-parse.in | 100 > +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 103 insertions(+) > create mode 100755 utilities/ovs-backtrace-parse.in > > diff --git a/utilities/.gitignore b/utilities/.gitignore > index 4f96a4f..9813842 100644 > --- a/utilities/.gitignore > +++ b/utilities/.gitignore > @@ -3,6 +3,7 @@ > /nlmon > /ovs-appctl > /ovs-appctl.8 > +/ovs-backtrace-parse > /ovs-benchmark > /ovs-benchmark.1 > /ovs-cfg-mod > diff --git a/utilities/automake.mk b/utilities/automake.mk > index 890f867..4dc9545 100644 > --- a/utilities/automake.mk > +++ b/utilities/automake.mk > @@ -7,6 +7,7 @@ bin_PROGRAMS += \ > bin_SCRIPTS += utilities/ovs-pki utilities/ovs-parse-leaks > if HAVE_PYTHON > bin_SCRIPTS += \ > + utilities/ovs-backtrace-parse \ > utilities/ovs-l3ping \ > utilities/ovs-pcap \ > utilities/ovs-tcpundump \ > @@ -20,6 +21,7 @@ scripts_SCRIPTS += \ > scripts_DATA += utilities/ovs-lib > > EXTRA_DIST += \ > + utilities/ovs-backtrace-parse.in \ > utilities/ovs-check-dead-ifs.in \ > utilities/ovs-ctl.in \ > utilities/ovs-l3ping.in \ > diff --git a/utilities/ovs-backtrace-parse.in > b/utilities/ovs-backtrace-parse.in > new file mode 100755 > index 0000000..3656f6f > --- /dev/null > +++ b/utilities/ovs-backtrace-parse.in > @@ -0,0 +1,100 @@ > +#! @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 argparse > +import os > +import re > +import subprocess > +import sys > + > +import ovs.dirs > + > +has_addr2line = True > +addr2line_cache = {} > + > + > +def addr2line(ovs_vswitchd, addr): > + global has_addr2line > + global addr2line_cache > + > + if not has_addr2line: > + return "" > + > + if addr in addr2line_cache: > + return addr2line_cache[addr] > + > + cmd = ["addr2line", "-f", "-s", "-e", ovs_vswitchd, 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: > + has_addr2line = False > + return "" > + > + lines = [l.strip() for l in lines] > + return " ".join(lines) > + > + > +def main(): > + 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. > + > + ovs-appctl backtrace | %(prog)s""" > + > + formatter_class = argparse.RawDescriptionHelpFormatter > + parser = argparse.ArgumentParser(description=description, > + formatter_class=formatter_class) > + parser.add_argument('--version', action='version', version='@VERSION@') > + parser.add_argument('-e', '--exe', nargs=1, type=str, > + help="path to ovs-vswitchd") > + args = parser.parse_args() > + > + if args.exe is not None: > + ovs_vswitchd = args.exe[0] > + else: > + ovs_vswitchd = "@sbindir@/ovs-vswitchd" > + > + trace_list = sys.stdin.read().strip().split("\n\n") > + > + #Remove the first line from each trace. > + trace_list = [trace[(trace.index("\n") + 1):] for trace in trace_list] > + > + 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.split("\n") > + longest = max([len(l) for l in lines]) > + > + print "Backtrace Count: %d" % count > + for line in trace.split("\n"):
Could be: for trace, count in sorted_traces: lines = trace.splitlines() longest = max(len(l) for l in lines) ... for line in lines: > + match = re.search(r'\[(0x.*)]', line) if match is None, this will throw an exception - can you be pretty confident this will match somewhere? > + print "%s %s" % (line.ljust(longest), addr2line(ovs_vswitchd, > + match.group(1))) > + print > + > + > +if __name__ == "__main__": > + main() > -- > 1.7.12 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev