[ovs-dev] [PATCH] utilities: New helper ovs-backtrace-parse.

Ethan Jackson ethan at nicira.com
Wed Oct 17 02:55:17 UTC 2012


Thanks reid, I've pulled in these changes.

On Mon, Oct 15, 2012 at 4:25 PM, Reid Price <reid at nicira.com> wrote:
> 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