Skip to content

Commit e74c724

Browse files
committed
add stack check for linux function
1 parent f475b7f commit e74c724

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

python/stackcheck.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#linux stack check: use objdump -D to dump asm file,and check
2+
from collections import OrderedDict
3+
4+
func_map = OrderedDict()
5+
6+
7+
def build_Path(stack, root, pathlist, recursion_list):
8+
if root['funcname'] in stack:
9+
stack.append(root['funcname'])
10+
save_path(stack, recursion_list)
11+
save_path(stack, pathlist)
12+
stack.pop()
13+
return
14+
15+
if len(stack) > 50:
16+
print("too depth stack:", root['funcname'])
17+
return
18+
19+
stack.append(root['funcname'])
20+
21+
if len(root['called_funcs']) == 0:
22+
save_path(stack, pathlist)
23+
else:
24+
for item in root['called_funcs']:
25+
if not func_map.has_key(item):
26+
print "func not found:" + item + '\n'
27+
else:
28+
build_Path(stack, func_map[item], pathlist, recursion_list)
29+
30+
stack.pop()
31+
32+
33+
def save_path(path, pathlist):
34+
paths = []
35+
for item in path:
36+
paths.append(item)
37+
pathlist.append(paths)
38+
39+
40+
def set_max_stacksize(root):
41+
pathlist = []
42+
max_stack_size = 0
43+
recursion_list = []
44+
stack = []
45+
46+
build_Path(stack, root, pathlist, recursion_list)
47+
48+
for paths in pathlist:
49+
stack_sizes = 0
50+
# root["stack_list"].append(paths)
51+
for path in paths:
52+
stack_sizes += func_map[path]['stack_size']
53+
if stack_sizes > max_stack_size:
54+
max_stack_size = stack_sizes
55+
root["max_path"] = paths
56+
57+
root["stack_max_size"] = max_stack_size
58+
59+
if len(recursion_list) > 0:
60+
root["hava_recursion"] = True
61+
for paths in recursion_list:
62+
root["recursion_list"].append(paths)
63+
64+
65+
def get_recursion_func_list():
66+
func_list = []
67+
for v in func_map.values():
68+
if v["hava_recursion"]:
69+
func_list.append(v["funcname"])
70+
return func_list
71+
72+
73+
def sort_by_stack_size():
74+
bar = OrderedDict(sorted(func_map.items(), key=lambda x: x[1]["stack_max_size"], reverse=True))
75+
76+
print("func name sort by max stack size:name, max_size, stack depth\n")
77+
for key, value in bar.items():
78+
if value["stack_max_size"] > 100:
79+
print (key, value["stack_max_size"], len(value["max_path"]))
80+
81+
bar1 = OrderedDict(sorted(func_map.items(), key=lambda x: x[1]["stack_size"], reverse=True))
82+
83+
print("\n\nfunc name sort by stack size:name, sekf stack size\n")
84+
for key, value in bar1.items():
85+
if value["stack_size"] > 100:
86+
print (key, value["stack_size"])
87+
88+
print("\n\n")
89+
import json
90+
print(json.dumps(bar, indent=4))
91+
print("\n\n")
92+
93+
94+
def parse(filename):
95+
f = open(filename)
96+
line = f.readline()
97+
while line:
98+
if ">:" in line:
99+
# print line
100+
line = process_func(f, line)
101+
102+
else:
103+
line = f.readline()
104+
f.close()
105+
106+
107+
def process_func(f, line):
108+
fun_name = line.split(">")[0].split("<")[1]
109+
# print "func: " + fun_name + "\n"
110+
func_map[fun_name] = {}
111+
112+
func_map[fun_name]["funcname"] = fun_name
113+
func_map[fun_name]["stack_size"] = 0
114+
func_map[fun_name]["called_funcs"] = []
115+
func_map[fun_name]["stack_max_size"] = 0
116+
func_map[fun_name]["max_path"] = []
117+
func_map[fun_name]["hava_recursion"] = False
118+
func_map[fun_name]["recursion_list"] = []
119+
func_map[fun_name]["stack_list"] = []
120+
121+
line = f.readline()
122+
if not line: return
123+
while not (">:" in line):
124+
line = f.readline()
125+
if not line:
126+
break
127+
if "sub" in line and ",%rsp" in line and "$" in line:
128+
stacksize = line.split("$")[1].split(",")[0]
129+
if stacksize == "0xffffffffffffff80":
130+
stacksize = 128
131+
else:
132+
stacksize = int(stacksize, 16)
133+
func_map[fun_name]["stack_size"] = func_map[fun_name]["stack_size"] + stacksize
134+
135+
if ("callq " in line) or ("call " in line) or ("jmp " in line) or ("jmpq " in line):
136+
if not "+" in line:
137+
if "<" in line and ">" in line:
138+
call_fun_name = line.split(">")[0].split("<")[1]
139+
func_map[fun_name]["called_funcs"].append(call_fun_name)
140+
return line
141+
142+
143+
if __name__ == '__main__':
144+
145+
file_list = [r".\\vmlinux.asm\\vmlinux.asm", ]
146+
147+
for file in file_list:
148+
parse(file)
149+
150+
'''for v in func_map.values():
151+
if v["stack_size"] > 500:
152+
set_max_stacksize(v)'''
153+
154+
print("\nrecirsion list:\n")
155+
print(get_recursion_func_list())
156+
157+
print("\nsorted function list:\n")
158+
sort_by_stack_size()
159+
160+
print("\n\n")

0 commit comments

Comments
 (0)