Revision: 1005 Author: teawater Date: Sat Mar 31 06:51:04 2012 Log: add-ons/hotcode.py output hot code info to html file. http://code.google.com/p/kgtp/source/detail?r=1005 Modified: /trunk/UPDATE /trunk/add-ons/hotcode.py ======================================= --- /trunk/UPDATE Wed Mar 28 09:27:51 2012 +++ /trunk/UPDATE Sat Mar 31 06:51:04 2012 @@ -11,6 +11,8 @@ * Fix bug of add-ons/hotcode.py when it use with user space task. +* add-ons/hotcode.py can output hot code info to html file. + *** 20120319 * https://lkml.org/lkml/2012/3/19/210 ======================================= --- /trunk/add-ons/hotcode.py Thu Mar 29 19:14:42 2012 +++ /trunk/add-ons/hotcode.py Sat Mar 31 06:51:04 2012 @@ -8,15 +8,20 @@ import tempfile import os import signal +import sys +import traceback debug_dir = "/usr/lib/debug/" #0 inferior_id 1 dir_name 2 kernel_list 3 user_list -#list 0 function_list 1 file_list 2 line_list+#list 0 function_list 1 file_list 2 line_list 3 function_list_line 4 file_list_line
task_list = {} no_task = False -kernel_hotcode_list = ({},{},{}) - +kernel_hotcode_list = ({}, {}, {}, {}, {}) + + +output_html = True +output_html_file = "./hotcode.html" show_line_number_default = 20 show_line_number = show_line_number_default @@ -28,35 +33,6 @@ #proposed in PEP 265, using the itemgetter return sorted(d.iteritems(), key=itemgetter(1), reverse=True) -#info[0] line_num, info[1] file_name, info[2] function_name -def add_info_to_code_list(info, code_list): - #function_list - if info[2] in code_list[0]: - code_list[0][info[2]] += 1 - else: - code_list[0][info[2]] = 1 - #file_list - if info[1] in code_list[1]: - code_list[1][info[1]] += 1 - else: - code_list[1][info[1]] = 1 - #line_list - line = str(info[1]) + ":" + str(info[0]) - if line in code_list[2]: - code_list[2][line] += 1 - else: - code_list[2][line] = 1 - -def task_list_add_line(is_user, pid, info): - if no_task: - #function_list - add_info_to_code_list (info, kernel_hotcode_list) - else: - if is_user: - add_info_to_code_list (info, task_list[pid][3]) - else: - add_info_to_code_list (info, task_list[pid][2]) - def hotcode_show_code_list(string, code_list): if len(code_list) > 0: print "\t", string @@ -86,8 +62,82 @@ hotcode_show_code_list("Hotest line", task_list[pid][3][2]) print +html_id = 0 + +def hotcode_list_to_output_html_fd_1(llist, tlist, fd): + global html_id + i = 1 + for c in dict_sort(llist): + if tlist != None:+ fd.write('''<tr><td onclick='sh("'''+str(html_id)+'''");'>'''+str(c[0])+'''</td><td style=" width: 10%; text-align: right;">'''+str(c[1])+'''</td></tr>''') + fd.write('''<tr><td style="text-align: center; display: none;" colspan="2" id="''' + str(html_id) + '''"><table style="width: 100%;" border="1" cellpadding="0" cellspacing="0"><tbody>''')
+ for d in dict_sort(tlist[c[0]]):+ fd.write("<tr><td>" + str(d[0]) + '''</td><td style=" width: 10%; text-align: right;">''' + str(d[1]) + "</td></tr>")
+ fd.write('</tbody></table>') + else:+ fd.write('<tr><td>'+str(c[0])+'''</td><td style=" width: 10%; text-align: right;">'''+str(c[1])+'''</td></tr>''')
+ i += 1 + html_id += 1 + if i > show_line_number: + break + +def hotcode_list_to_output_html_fd(hlist, fd): + global html_id+ fd.write('''<tr><td style="text-align: center;" colspan="2">Hot functions list</td></tr>''')
+ hotcode_list_to_output_html_fd_1(hlist[0], hlist[3], fd)+ fd.write('''<tr><td style="text-align: center;" colspan="2">Hot file list</td></tr>''')
+ hotcode_list_to_output_html_fd_1(hlist[1], hlist[4], fd)+ fd.write('''<tr><td style="text-align: center;" colspan="2">Hot line list</td></tr>''')
+ hotcode_list_to_output_html_fd_1(hlist[2], None, fd) + +def hotcode_to_output_html_file(): + global html_id + html_id = 0 + fd = open(output_html_file, "w") + fd.write(''' +<html><head><title>Hotcode</title> +<script> +<!-- +function sh(id) +{ + if(document.getElementById(id).style.display=='none') { + document.getElementById(id).style.display='block'; + } + else { + document.getElementById(id).style.display='none'; + } +} +--> +</script></head> +<body>+<div style="text-align: center;">This file is generated by KGTP (<a href="http://code.google.com/p/kgtp/";>http://code.google.com/p/kgtp/</a>)</div> +<div style="text-align: center;">Click the function name or file name to see the detailed info.</div>''')
+ if no_task: + fd.write('<br><br>')+ fd.write('''<table style="margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="0"><tbody>''')
+ hotcode_list_to_output_html_fd(kernel_hotcode_list, fd) + fd.write('</tbody></table>') + else: + for pid in task_list: + fd.write('<br><br>')+ fd.write('''<table style="margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="0"><tbody>''') + fd.write('''<tr><td style="text-align: center;" colspan="2">pid:''' + str(pid) + " " + task_list[pid][1] + "</td></tr>")
+ if trace_user:+ fd.write('''<tr><td style="text-align: center;" colspan="2">User space hotcode list</td></tr>''')
+ hotcode_list_to_output_html_fd(task_list[pid][3], fd) + if trace_kernel:+ fd.write('''<tr><td style="text-align: center;" colspan="2">Kernel space hotcode list</td></tr>''')
+ hotcode_list_to_output_html_fd(task_list[pid][2], fd) + fd.write('</tbody></table>') + fd.write('</body></html>') + fd.close() + print "Save", html_id, "entries." + def sigint_handler(num, e): - hotcode_show() + if output_html: + hotcode_to_output_html_file() + else: + hotcode_show() try: s = raw_input('Conitnue? [(y)es], (n)o:') except: @@ -203,7 +253,7 @@ gdb.execute("add-symbol-file "+filename+" ("+addr+"+"+text_offset+")") gdb.execute("file "+user_dir) gdb.execute("inferior 1") - task_list[pid] = (fid, user_dir, ({},{},{}), ({},{},{}))+ task_list[pid] = (fid, user_dir, ({}, {}, {}, {}, {}), ({}, {}, {}, {}, {}))
def get_addr_range_list(fun): buf = gdb.execute("info line "+fun, False, True) @@ -278,6 +328,33 @@ trace_kernel = True no_task = True +try:+ s = raw_input('Which way you want to output hotcode info when ctrl-c? [(h)tml], (t)ty:')
+except: + s = 'h' +if s[0:1] == 't' or s[0:1] == 'T': + output_html = False +else: + output_html = True + +if output_html: + while 1: + try:+ s = raw_input('Which file you want to save the html output? [' + output_html_file + ']:')
+ if os.path.exists(s): + if os.path.isfile(s):+ s = raw_input('File ' + s +' exist, do you want to over write it? (y)es, [(n)o]:')
+ if s[0:1] != 'y' and s[0:1] != 'Y': + continue + else:+ print 'File ' + s +' exist, but it cannot be written. Please choice another file.'
+ continue + except: + continue + if len(s) > 0: + output_html_file = s + break + try:show_line_number = input('Show line number (0 meas all)? ['+str(show_line_number)+']:')
except: @@ -517,6 +594,42 @@#--------------------------------------------------------------------------------------------------
#cycle +def add_line_to_list(line, line_list): + if line in line_list: + line_list[line] += 1 + else: + line_list[line] = 1 + +#info[0] line_num, info[1] file_name, info[2] function_name +def add_info_to_code_list(info, code_list): + line = str(info[1]) + ":" + str(info[0]) + #function_list + if info[2] in code_list[0]: + code_list[0][info[2]] += 1 + else: + code_list[0][info[2]] = 1 + code_list[3][info[2]] = {} + add_line_to_list(line, code_list[3][info[2]]) + #file_list + if info[1] in code_list[1]: + code_list[1][info[1]] += 1 + else: + code_list[1][info[1]] = 1 + code_list[4][info[1]] = {} + add_line_to_list(line, code_list[4][info[1]]) + #line_list + add_line_to_list(line, code_list[2]) + +def task_list_add_line(is_user, pid, info): + if no_task: + #function_list + add_info_to_code_list (info, kernel_hotcode_list) + else: + if is_user: + add_info_to_code_list (info, task_list[pid][3]) + else: + add_info_to_code_list (info, task_list[pid][2]) + def get_line_from_sym(sym): sym = sym.rstrip(os.linesep) @@ -559,9 +672,13 @@ line = get_line_from_sym(sym) task_list_add_line(False, 0, line) except gdb.error, x: - print("Drop one entry because", x) + print("Drop one entry because:")+ for file, lineno, function, text in traceback.extract_tb(sys.exc_info()[2]):
+ print file, lineno, function, text except gdb.MemoryError, x: - print("Drop one entry because", x) + print("Drop one entry because:")+ for file, lineno, function, text in traceback.extract_tb(sys.exc_info()[2]):
+ print file, lineno, function, text try: gdb.execute("tfind 1", False, True) except: @@ -574,7 +691,7 @@ pid = long(gdb.parse_and_eval("$current_task_pid")) if not pid in task_list:raise gdb.error ("Cannot find inferior for pid "+ str(pid) +", drop one entry.")
- if trace_user and long(gdb.parse_and_eval("regs->cs & 3")) == 3:+ if trace_user and (not trace_kernel or long(gdb.parse_and_eval("regs->cs & 3")) == 3):
is_user = True ip = long(gdb.parse_and_eval("regs->ip - 1")) gdb.execute("inferior "+str(task_list[pid][0]), False, True) @@ -586,13 +703,17 @@ gdb.execute("inferior 1", False, True) task_list_add_line(is_user, pid, line) except gdb.error, x: - print("Drop one entry because", x) + print("Drop one entry because:")+ for file, lineno, function, text in traceback.extract_tb(sys.exc_info()[2]):
+ print file, lineno, function, text try: gdb.execute("inferior 1", False, True) except: pass except gdb.MemoryError, x: - print("Drop one entry because", x) + print("Drop one entry because:")+ for file, lineno, function, text in traceback.extract_tb(sys.exc_info()[2]):
+ print file, lineno, function, text try: gdb.execute("inferior 1", False, True) except: