Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 331e1cd

Browse files
Costa ShulyupinCosta Shulyupin
authored andcommitted
notes
1 parent c0d0388 commit 331e1cd

File tree

1 file changed

+49
-37
lines changed

1 file changed

+49
-37
lines changed

srcxray.py

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
'current_user_ns spin_lock_irq spin_unlock_irq prepare_creds '
6868
'tasklist_lock commit_creds read_lock read_unlock SIGKILL SIGSTOP abort_creds fd_install '
6969
'real_mount FMODE_WRITE tv_nsec putname '
70-
).split()
70+
).split() # TODO: move to file
7171

7272

7373
level_limit = 10
@@ -81,6 +81,7 @@
8181

8282

8383
def print_limited(a, out=None):
84+
# exits when reaches limit of printed lines
8485
out = out if out else sys.stdout
8586
out.write(str(a) + '\n')
8687
global n
@@ -92,6 +93,7 @@ def print_limited(a, out=None):
9293

9394

9495
def log(*args, **kwargs):
96+
# log with context function
9597
if not verbose:
9698
return
9799
s = str(*args).rstrip()
@@ -102,11 +104,15 @@ def log(*args, **kwargs):
102104

103105

104106
def popen(p):
107+
# shortcut for reading output of subcommand
105108
log(p)
106109
return check_output(p, shell=True).decode('utf-8').splitlines()
107110

108111

109112
def extract_referrer(line):
113+
# Extract referrer function from oupput of
114+
# git grep --show-function.
115+
# With quirks for linux kernel
110116
line = re.sub(r'__ro_after_init', '', line)
111117
line = re.sub(r'FNAME\((\w+)\)', r'\1', line)
112118
line = re.sub(r'.*TRACE_EVENT.*', '', line)
@@ -122,6 +128,7 @@ def extract_referrer(line):
122128

123129

124130
def extract_referrer_test():
131+
# unittest of extract_referrer
125132
passed = 0
126133
for a in {
127134
"f=1=good2()",
@@ -147,6 +154,10 @@ def extract_referrer_test():
147154

148155

149156
def func_referrers_git_grep(name):
157+
# Subfunction for searching referrers with
158+
# git grep --show-function.
159+
# Works slowly.
160+
# Obsoleted by doxygen_xml.
150161
res = list()
151162
r = None
152163
for line in popen(r'git grep --threads 1 --no-index --word-regexp '
@@ -179,6 +190,9 @@ def func_referrers_git_grep(name):
179190

180191

181192
def func_referrers_cscope(name):
193+
# Subfunction for searching referrers with cscope.
194+
# Works fast.
195+
# Obsoleted by doxygen_xml.
182196
global cscope_warned
183197
if not os.path.isfile('cscope.out'):
184198
if not cscope_warned:
@@ -201,14 +215,11 @@ def func_referrers_cscope(name):
201215
return res
202216

203217

204-
def func_referrers_all(name):
205-
return list(dict.fromkeys(func_referrers_git_grep(name) + func_referrers_cscope(name)))
206-
207-
208218
def referrers_tree(name, referrer=None, printed=None, level=0):
209219
'''
210-
Arg: <identifier>
220+
Arg: <identifier> - prints text referrers tree.
211221
Ex: nfs_root_data
222+
Obsoleted by doxygen_xml.
212223
'''
213224
if not referrer:
214225
if os.path.isfile('cscope.out'):
@@ -239,16 +250,17 @@ def referrers_tree(name, referrer=None, printed=None, level=0):
239250

240251
def referrers(name):
241252
'''
242-
Arg: <identifier>
253+
Arg: <identifier> - simply greps referrers of a symbol
243254
Ex: nfs_root_data
255+
Prefer to use doxygen_xml.
244256
'''
245-
# for a in func_referrers_git_grep(name):
246-
# print("%s:%s: %s"%(a[0],a[1],a[2]))
247257
print(' '.join([a[2] for a in func_referrers_git_grep(name)]))
248258

249259

250260
def referrers_dep(name, referrer=None, printed=None, level=0):
251-
# Arg: <identifier>
261+
# Arg: <identifier> - prints referrers tree in compact format of
262+
# dependency of make
263+
# Obsoleted by doxygen_xml.
252264
if not referrer:
253265
if os.path.isfile('cscope.out'):
254266
referrer = func_referrers_cscope
@@ -278,8 +290,9 @@ def referrers_dep(name, referrer=None, printed=None, level=0):
278290

279291
def call_tree(node, printed=None, level=0):
280292
'''
281-
Arg: <identifier>
293+
Arg: <identifier> - prints call tree of a function
282294
Ex: start_kernel
295+
Obsoleted by doxygen_xml.
283296
'''
284297
if not os.path.isfile('cscope.out'):
285298
print("Please run: cscope -Rcbk", file=sys.stderr)
@@ -308,6 +321,8 @@ def call_tree(node, printed=None, level=0):
308321

309322

310323
def call_dep(node, printed=None, level=0):
324+
# prints call tree in compact format of dependency of make
325+
# Obsoleted by doxygen_xml.
311326
if not os.path.isfile('cscope.out'):
312327
print("Please run: cscope -Rcbk", file=sys.stderr)
313328
return False
@@ -334,6 +349,7 @@ def call_dep(node, printed=None, level=0):
334349

335350

336351
def my_graph(name=None):
352+
# common subfunction
337353
g = nx.DiGraph(name=name)
338354
# g.graph.update({'node': {'shape': 'none', 'fontsize': 50}})
339355
# g.graph.update({'rankdir': 'LR', 'nodesep': 0, })
@@ -354,7 +370,9 @@ def reduce_graph(g, m=None):
354370
return g
355371

356372

357-
def includes(a):
373+
def includes(sym):
374+
# subfunction, used in syscalls
375+
# extracts include files of a symbol
358376
res = []
359377
# log(a)
360378
for a in popen('man -s 2 %s 2> /dev/null |'
@@ -376,19 +394,24 @@ def includes(a):
376394
if res and len(res) > 1:
377395
r = set()
378396
for f in res:
379-
# log('grep " %s \+\(" --include "%s" -r /usr/include/'%(a, f))
397+
# log('grep " %s \+\(" --include "%s" -r /usr/include/'%(sym, f))
380398
# log(os.system(
381-
# 'grep -w "%s" --include "%s" -r /usr/include/'%(a, f)))
399+
# 'grep -w "%s" --include "%s" -r /usr/include/'%(sym, f)))
382400
if 0 != os.system(
383401
'grep " %s *(" --include "%s" -r /usr/include/ -q'
384-
% (a, os.path.basename(f))):
402+
% (sym, os.path.basename(f))):
385403
r.add(f)
386404
res = res.difference(r)
387405
log(res)
388406
return ','.join(list(res)) if res else 'unexported'
389407

390408

391409
def syscalls():
410+
# Experimental function for exporting syscalls info
411+
# from various sources.
412+
# Used in creation of
413+
# https://en.wikibooks.org/wiki/The_Linux_Kernel/Syscalls
414+
# Ex: srcxray.py "write_dot(syscalls(), 'syscalls.dot')"
392415
sc = my_graph('syscalls')
393416
inc = 'includes.list'
394417
if not os.path.isfile(inc):
@@ -454,20 +477,9 @@ def syscalls():
454477
return sc
455478

456479

457-
# DiGraph
458-
# write_dot to_agraph AGraph
459-
# agwrite
460-
# srcxray.py 'write_dot(syscalls(), "syscalls.dot")'
461-
# write_graphml
462-
# srcxray.py "most_used(read_dot('a.dot'))"
463-
# srcxray.py "digraph_print(read_dot('a.dot'))"
464-
# srcxray.py "write_dot(reduce_graph(read_dot('no-loops.dot')),'reduced.dot')"
465-
# a=sys_clone;srcxray.py "write_dot(rank_couples(reduce_graph(remove_loops(read_dot('$a.dot')))),'$a.dot')"
466-
# srcxray.py "pprint(most_used(read_dot('a.dot')))"
467-
# srcxray.py "write_dot(add_rank('reduced.dot'), 'ranked.dot')"
468-
# srcxray.py "write_dot(remove_loops(read_dot('reduced.dot')), 'no-loops.dot')"
469-
470480
def cleanup(a):
481+
# cleanups graph file
482+
# wrapper for remove_nodes_from
471483
log('')
472484
g = to_dg(a)
473485
print(dg.number_of_edges())
@@ -480,15 +492,7 @@ def sort_dict(d):
480492
return [a for a, b in sorted(d.items(), key=lambda k: k[1], reverse=True)]
481493

482494

483-
def most_used(dg, ins=10, outs=10):
484-
# return {a: b for a, b in sorted(dg.in_degree, key=lambda k: k[1]) if b > 1 and}
485-
# return [(x, dg.in_degree(x), dg.out_degree(x))
486-
return [x
487-
for x in dg.nodes()
488-
if dg.in_degree(x) >= ins and dg.out_degree(x) >= outs]
489-
490-
491-
def starts(dg): # roots
495+
def starts(dg): # roots of trees in a graph
492496
return {n: dg.out_degree(n) for (n, d) in dg.in_degree if not d}
493497

494498

@@ -559,6 +563,7 @@ def sub(node):
559563
def digraph_print(dg, starts=None, dst_fn=None, sort=False):
560564
'''
561565
Arg: <graph> - print graphs as text tree
566+
Ex2: \"digraph_print(read_dot('a.dot'))\"
562567
'''
563568
dst = open(dst_fn, 'w') if dst_fn else None
564569
printed = set()
@@ -777,6 +782,7 @@ def write_dot(g, dot):
777782
'''
778783
Arg: <graph> <file> - writes a graph into a file with custom attributes
779784
'''
785+
# Other similar external functions to_agraph agwrite
780786
dot = str(dot)
781787
dot = open(dot, 'w')
782788
dot.write('strict digraph "None" {\n')
@@ -867,6 +873,7 @@ def to_dg(a):
867873

868874

869875
def remove_loops(dg):
876+
# srcxray.py "write_dot(remove_loops(read_dot('reduced.dot')), 'no-loops.dot')"
870877
rm = []
871878
visited = set()
872879
path = [object()]
@@ -903,6 +910,7 @@ def remove_couples(dg):
903910

904911

905912
def rank_couples(dg):
913+
# a=sys_clone;srcxray.py "write_dot(rank_couples(reduce_graph(remove_loops(read_dot('$a.dot')))),'$a.dot')"
906914
couples = []
907915
ranked = set()
908916
for n in dg:
@@ -1048,6 +1056,7 @@ def dot_expand(a, b):
10481056

10491057

10501058
def add_rank(g):
1059+
# srcxray.py "write_dot(add_rank('reduced.dot'), 'ranked.dot')"
10511060
g = to_dg(g)
10521061
passed1 = set()
10531062
passed2 = set()
@@ -1079,6 +1088,7 @@ def add_rank(g):
10791088

10801089

10811090
def import_symbols():
1091+
# extracts and import symbols from shared libraries
10821092
sym = my_graph('symbols')
10831093
for l in popen('(shopt -s globstar; nm -D -C -A **/*.so.*)'):
10841094
q = l.split(maxsplit=2)
@@ -1165,6 +1175,7 @@ def doxygen(*input):
11651175
def doxygen_xml(a):
11661176
'''
11671177
Arg: <xml directory generated by doxygen> - extracts call graph
1178+
Ex2: \"write_dot(doxygen_xml('xml'), 'doxygen.dot')\"
11681179
'''
11691180
g = my_graph()
11701181
for x in list(glob.glob(os.path.join(a, "*.xml")) + [a]):
@@ -1234,6 +1245,7 @@ def usage():
12341245

12351246
class _unittest_autotest(unittest.TestCase):
12361247
def test_1(self):
1248+
extract_referrer_test()
12371249
write_dot(nx.DiGraph([(1, 2), (2, 3), (2, 4)]), 'test.dot')
12381250
g = read_dot("test.dot")
12391251
self.assertEqual(list(g.successors("2")), ["3", "4"])

0 commit comments

Comments
 (0)