-
Notifications
You must be signed in to change notification settings - Fork 3
/
print_profile_data.py
87 lines (68 loc) · 3.29 KB
/
print_profile_data.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import subprocess
from collections import defaultdict
from tqdm import tqdm
from tabulate import tabulate
def get_symbol_offset(executable_path, symbol_name):
try:
nm_output = subprocess.check_output(['nm', executable_path], universal_newlines=True)
# Assuming the output format is like "address T symbol_name"
for line in nm_output.splitlines():
parts = line.split()
if len(parts) >= 3 and parts[2] == symbol_name:
offset_hex = parts[0]
# Convert hex offset to an integer
offset = int(offset_hex, 16)
return offset
return None
except subprocess.CalledProcessError:
return None
def get_symbol_name(executable, address):
try:
result = subprocess.check_output(['addr2line', '-e', executable, '-f', '-C', '-i', address],
universal_newlines=True, stderr=subprocess.PIPE)
return result.strip().splitlines()
except subprocess.CalledProcessError as e:
return ['Error: Unable to retrieve symbol name for address', address]
def process_profiling_data(file_path):
# Read the executable name and addresses from the profiling data file
with open(file_path, 'r') as file:
lines = file.readlines()
[executable, entryMainAddr] = lines[0].strip().split()
offset = int(entryMainAddr, 16) - get_symbol_offset(executable, 'entryMain')
address_lines = [address.strip().split() for address in lines[1:] if address.strip()]
addresses = list(set([a for ads in address_lines for a in ads]))
total_lines = len(lines) - 1
# Analyze and print the results
results = []
for address in tqdm(addresses):
symbol_info = get_symbol_name(executable, hex(int(address, 16) - offset))
symbol_name = symbol_info[0] if len(symbol_info) > 0 else 'Unknown Symbol'
self_time = (len([0 for al in address_lines if al[0] == address]) / total_lines) * 100
other_time = (len([0 for al in address_lines if al[0] != address and address in al]) / total_lines) * 100
all_times = (len([0 for al in address_lines if address in al]) / total_lines) * 100
results.append({
'Address': address,
'Symbol Name': symbol_name,
'Self Time (%)': f'{self_time:.4f}',
'Other Time (%)': f'{other_time:.4f}',
'All Times (%)': f'{all_times:.4f}'
})
# Sort results by self time in descending order
results.sort(key=lambda x: (float(x['Self Time (%)']), float(x['Other Time (%)'])), reverse=True)
# Print the results
# # if not using tabulate:
# for result in results:
# print(result)
max_symbol_name_length = 30
# Create a list of lists for tabulate
table_data = [
[result['Address'], result['Symbol Name'], result['Self Time (%)'], result['Other Time (%)'], result['All Times (%)']]
for result in results
]
# Specify the headers
headers = ['Address', 'Symbol Name', 'Self Time (%)', 'Other Time (%)', 'All Times (%)']
# Print the table
print(tabulate(table_data, headers=headers, tablefmt='orgtbl'))
if __name__ == "__main__":
profiling_data_file = "yy_profiledata.txt" # Replace with your actual file path
process_profiling_data(profiling_data_file)