[ovs-dev] [PATCH] utilities: New helper ovs-backtrace-parse.
Reid Price
reid at nicira.com
Mon Oct 15 23:25:01 UTC 2012
Nice! Few notes inline
On Mon, Oct 15, 2012 at 3:22 PM, Ethan Jackson <ethan at 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 <ethan at 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 at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
More information about the dev
mailing list