X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=tests%2Futils%2Fparse-callstack.py;h=f16ab8e404adddb41dec5a1754d353a3b794a585;hb=6a871bbe6177568f748d1a9f580fa981bc75171c;hp=029100b6184de3e4c61d83841e65180ef724888b;hpb=b1a6a0bac7cb445d9c6bbb5adc89030a02f73462;p=lttng-tools.git diff --git a/tests/utils/parse-callstack.py b/tests/utils/parse-callstack.py index 029100b61..f16ab8e40 100755 --- a/tests/utils/parse-callstack.py +++ b/tests/utils/parse-callstack.py @@ -10,19 +10,20 @@ import bisect import subprocess import re + def addr2line(executable, addr): """ - Uses binutils' addr2line to get function containing a given address + Uses binutils' addr2line to get function containing a given address """ - cmd =['addr2line'] + cmd = ["addr2line"] - cmd += ['-e', executable] + cmd += ["-e", executable] # Print function names - cmd += ['--functions'] + cmd += ["--functions"] # Expand inlined functions - cmd += ['--addresses', addr] + cmd += ["--addresses", addr] status = subprocess.run(cmd, stdout=subprocess.PIPE, check=True) @@ -32,7 +33,9 @@ def addr2line(executable, addr): # - function name # - source location if len(addr2line_output) % 3 != 0: - raise Exception('Unexpected addr2line output:\n\t{}'.format('\n\t'.join(addr2line_output))) + raise Exception( + "Unexpected addr2line output:\n\t{}".format("\n\t".join(addr2line_output)) + ) function_names = [] for address_line_number in range(0, len(addr2line_output), 3): @@ -44,95 +47,101 @@ def addr2line(executable, addr): return function_names + def extract_user_func_names(executable, raw_callstack): """ - Given a callstack from the Babeltrace CLI output, returns a set - containing the name of the functions. This assumes that the binary have - not changed since the execution. + Given a callstack from the Babeltrace CLI output, returns a set + containing the name of the functions. This assumes that the binary have + not changed since the execution. """ recorded_callstack = set() # Remove commas and split on spaces - for index, addr in enumerate(raw_callstack.replace(',', '').split(' ')): + for index, addr in enumerate(raw_callstack.replace(",", "").split(" ")): # Consider only the elements starting with '0x' which are the # addresses recorded in the callstack - if '0x' in addr[:2]: + if "0x" in addr[:2]: funcs = addr2line(executable, addr) recorded_callstack.update(funcs) return recorded_callstack + def extract_kernel_func_names(raw_callstack): """ - Given a callstack from the Babeltrace CLI output, returns a set - containing the name of the functions. - Uses the /proc/kallsyms procfile to find the symbol associated with an - address. This function should only be used if the user is root or has - access to /proc/kallsyms. + Given a callstack from the Babeltrace CLI output, returns a set + containing the name of the functions. + Uses the /proc/kallsyms procfile to find the symbol associated with an + address. This function should only be used if the user is root or has + access to /proc/kallsyms. """ recorded_callstack = set() - syms=[] - addresses=[] + syms = [] + addresses = [] # We read kallsyms file and save the output - with open('/proc/kallsyms') as kallsyms_f: + with open("/proc/kallsyms") as kallsyms_f: for line in kallsyms_f: line_tokens = line.split() addr = line_tokens[0] symbol = line_tokens[2] addresses.append(int(addr, 16)) - syms.append({'addr':int(addr, 16), 'symbol':symbol}) + syms.append({"addr": int(addr, 16), "symbol": symbol}) # Save the address and symbol in a sorted list of tupple - syms = sorted(syms, key=lambda k:k['addr']) + syms = sorted(syms, key=lambda k: k["addr"]) # We save the list of addresses in a seperate sorted list to easily bisect # the closer address of a symbol. addresses = sorted(addresses) # Remove commas and split on spaces - for addr in raw_callstack.replace(',', '').split(' '): - if '0x' in addr[:2]: + for addr in raw_callstack.replace(",", "").split(" "): + if "0x" in addr[:2]: # Search the location of the address in the addresses list and # deference this location in the syms list to add the associated # symbol. loc = bisect.bisect(addresses, int(addr, 16)) - recorded_callstack.add(syms[loc-1]['symbol']) + recorded_callstack.add(syms[loc - 1]["symbol"]) return recorded_callstack + # Regex capturing the callstack_user and callstack_kernel context -user_cs_rexp='.*callstack_user\ \=\ \[(.*)\]\ .*\}, \{.*\}' -kernel_cs_rexp='.*callstack_kernel\ \=\ \[(.*)\]\ .*\}, \{.*\}' +user_cs_rexp = ".*callstack_user\ \=\ \[(.*)\]\ .*\}, \{.*\}" +kernel_cs_rexp = ".*callstack_kernel\ \=\ \[(.*)\]\ .*\}, \{.*\}" + def main(): """ - Reads a line from stdin and expect it to be a wellformed Babeltrace CLI - output containing containing a callstack context of the domain passed - as argument. + Reads a line from stdin and expect it to be a wellformed Babeltrace CLI + output containing containing a callstack context of the domain passed + as argument. """ expected_callstack = set() recorded_callstack = set() - cs_type=None + cs_type = None if len(sys.argv) <= 2: print(sys.argv) - raise ValueError('USAGE: ./{} (--kernel|--user EXE) FUNC-NAMES'.format(sys.argv[0])) + raise ValueError( + "USAGE: ./{} (--kernel|--user EXE) FUNC-NAMES".format(sys.argv[0]) + ) # If the `--user` option is passed, save the next argument as the path # to the executable - argc=1 - executable=None - if sys.argv[argc] in '--kernel': + argc = 1 + executable = None + if sys.argv[argc] in "--kernel": rexp = kernel_cs_rexp - cs_type='kernel' - elif sys.argv[argc] in '--user': + cs_type = "kernel" + elif sys.argv[argc] in "--user": rexp = user_cs_rexp - cs_type='user' - argc+=1 + cs_type = "user" + argc += 1 executable = sys.argv[argc] else: - raise Exception('Unknown domain') + raise Exception("Unknown domain") - argc+=1 + argc += 1 # Extract the function names that are expected to be found call stack of # the current events @@ -150,22 +159,23 @@ def main(): # If there is no match, exit with error if m is None: - raise re.error('Callstack not found in event line') + raise re.error("Callstack not found in event line") else: raw_callstack = str(m.group(1)) - if cs_type in 'user': - recorded_callstack=extract_user_func_names(executable, raw_callstack) - elif cs_type in 'kernel': - recorded_callstack=extract_kernel_func_names(raw_callstack) + if cs_type in "user": + recorded_callstack = extract_user_func_names(executable, raw_callstack) + elif cs_type in "kernel": + recorded_callstack = extract_kernel_func_names(raw_callstack) else: - raise Exception('Unknown domain') + raise Exception("Unknown domain") # Verify that all expected function are present in the callstack for e in expected_callstack: if e not in recorded_callstack: - raise Exception('Expected function name not found in recorded callstack') + raise Exception("Expected function name not found in recorded callstack") sys.exit(0) -if __name__ == '__main__': + +if __name__ == "__main__": main()