This commit is contained in:
Costa Shulyupin 2018-07-19 07:52:33 +03:00
parent e1c7f3643b
commit 7a987a2bdf
1 changed files with 43 additions and 18 deletions

View File

@ -10,10 +10,15 @@
# 2018 Constantine Shulyupin, const@MakeLinux.com # 2018 Constantine Shulyupin, const@MakeLinux.com
# #
import inspect, random, os, sys, collections, subprocess, re import inspect
import random
import os
import sys
import collections
import subprocess
import re
black_list = ['aligned', '__attribute__', 'unlikely', 'typeof', black_list = ['aligned', '__attribute__', 'unlikely', 'typeof', 'u32',
'u32',
'PVOP_CALLEE0', 'PVOP_VCALLEE0', 'PVOP_VCALLEE1', 'trace_hardirqs_off'] 'PVOP_CALLEE0', 'PVOP_VCALLEE0', 'PVOP_VCALLEE1', 'trace_hardirqs_off']
level_limit = 7 level_limit = 7
@ -31,12 +36,15 @@ def print_limited(a):
def log(*args, **kwargs): def log(*args, **kwargs):
print(inspect.stack()[1][3], str(*args).rstrip(), file=sys.stderr, **kwargs) print(inspect.stack()[1][3],
str(*args).rstrip(), file=sys.stderr, **kwargs)
pass pass
def popen(p): def popen(p):
return subprocess.Popen(p, shell=True, stdout=subprocess.PIPE, encoding="utf-8").stdout return subprocess.Popen(p, shell=True, stdout=subprocess.PIPE, encoding="utf-8").stdout
def extract_referer(line): def extract_referer(line):
line = re.sub(r'__ro_after_init', '', line) line = re.sub(r'__ro_after_init', '', line)
line = re.sub(r'FNAME\((\w+)\)', r'\1', line) line = re.sub(r'FNAME\((\w+)\)', r'\1', line)
@ -47,6 +55,7 @@ def extract_referer(line):
if m: if m:
return m.group(1) return m.group(1)
def extract_referer_test(): def extract_referer_test():
for a in { for a in {
"fs=good2()", "fs=good2()",
@ -59,6 +68,7 @@ def extract_referer_test():
"f: a=in bad()"}: "f: a=in bad()"}:
print(a, '->', extract_referer(a)) print(a, '->', extract_referer(a))
def func_referers_git_grep(name): def func_referers_git_grep(name):
res = [] res = []
r = None r = None
@ -73,8 +83,10 @@ def func_referers_git_grep(name):
r = extract_referer(line) r = extract_referer(line)
return res return res
cscope_warned = False cscope_warned = False
def func_referers_cscope(name): def func_referers_cscope(name):
global cscope_warned global cscope_warned
if not os.path.isfile('cscope.out'): if not os.path.isfile('cscope.out'):
@ -82,24 +94,29 @@ def func_referers_cscope(name):
print("Recommended: cscope -bkR", file=sys.stderr) print("Recommended: cscope -bkR", file=sys.stderr)
cscope_warned = True cscope_warned = True
return [] return []
res = [l.split()[1] for l in popen(r'cscope -d -L3 "%s"'%(name)) if not l in black_list] res = [l.split()[1] for l in popen(r'cscope -d -L3 "%s"' %
(name)) if not l in black_list]
if not res: if not res:
res = func_referers_git_grep(name) res = func_referers_git_grep(name)
return res return res
def func_referers_all(name): def func_referers_all(name):
return set(func_referers_git_grep(name) + func_referers_cscope(name)) return set(func_referers_git_grep(name) + func_referers_cscope(name))
def referers_tree(name, referer=None, printed = None, level = 0):
def referers_tree(name, referer=None, printed=None, level=0):
if not referer: if not referer:
if os.path.isfile('cscope.out'): if os.path.isfile('cscope.out'):
referer = func_referers_cscope referer = func_referers_cscope
else: else:
print("Using git grep only, recommended to run: cscope -bkR", file=sys.stderr) print("Using git grep only, recommended to run: cscope -bkR",
file=sys.stderr)
referer = func_referers_git_grep referer = func_referers_git_grep
if isinstance(referer, str): if isinstance(referer, str):
referer = eval(referer) referer = eval(referer)
if not printed: printed = set() if not printed:
printed = set()
if name in printed: if name in printed:
print_limited(level*'\t' + name + ' ^') print_limited(level*'\t' + name + ' ^')
return return
@ -117,13 +134,15 @@ def referers_tree(name, referer=None, printed = None, level = 0):
listed.add(a) listed.add(a)
return '' return ''
def call_tree(node, printed = None, level = 0):
def call_tree(node, printed=None, level=0):
if not os.path.isfile('cscope.out'): if not os.path.isfile('cscope.out'):
print("Please run: cscope -bkR", file=sys.stderr) print("Please run: cscope -bkR", file=sys.stderr)
return False return False
if printed == None: printed = set() if printed == None:
printed = set()
if node in printed: if node in printed:
limit= - 1 limit = - 1
print_limited(level*'\t' + node + ' ^') print_limited(level*'\t' + node + ' ^')
return return
else: else:
@ -133,18 +152,21 @@ def call_tree(node, printed = None, level = 0):
print_limited((level + 1)*'\t' + '...') print_limited((level + 1)*'\t' + '...')
return '' return ''
local_printed = set() local_printed = set()
for line in popen('cscope -d -L2 "%s"'%(node)): for line in popen('cscope -d -L2 "%s"' % (node)):
I = line.split()[1] I = line.split()[1]
if I in local_printed or I in black_list: continue; if I in local_printed or I in black_list:
continue
local_printed.add(I) local_printed.add(I)
try: try:
call_tree(line.split()[1], printed, level + 1); call_tree(line.split()[1], printed, level + 1)
except: except:
pass pass
return '' return ''
me = os.path.basename(sys.argv[0]) me = os.path.basename(sys.argv[0])
def usage(): def usage():
print(me, "referers_tree", "<identifier>") print(me, "referers_tree", "<identifier>")
print(me, "call_tree", "<identifier>") print(me, "call_tree", "<identifier>")
@ -154,6 +176,7 @@ def usage():
print(me, "call_tree start_kernel") print(me, "call_tree start_kernel")
print(me, "Emergency termination: ^Z, kill %1") print(me, "Emergency termination: ^Z, kill %1")
def main(): def main():
try: try:
ret = False ret = False
@ -163,12 +186,14 @@ def main():
if '(' in sys.argv[1]: if '(' in sys.argv[1]:
ret = eval(sys.argv[1]) ret = eval(sys.argv[1])
else: else:
ret = eval(sys.argv[1] + '(' + ', '.join("'%s'"%(a) for a in sys.argv[2:]) + ')') ret = eval(sys.argv[1] + '(' + ', '.join("'%s'" % (a)
for a in sys.argv[2:]) + ')')
if type(ret) == type(False) and ret == False: if type(ret) == type(False) and ret == False:
sys.exit(os.EX_CONFIG) sys.exit(os.EX_CONFIG)
print(ret) print(ret)
except KeyboardInterrupt: except KeyboardInterrupt:
warning("\nInterrupted") warning("\nInterrupted")
if __name__ == "__main__": if __name__ == "__main__":
main() main()