Thanks reid, I've pulled in these changes.
On Mon, Oct 15, 2012 at 4:25 PM, Reid Price <r...@nicira.com> wrote: > 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