KGTP (Linux Kernel debugger and tracer) 20120424 release(doc update)[3/3]script

From: Hui Zhu
Date: Tue Apr 24 2012 - 09:21:04 EST


Signed-off-by: Hui Zhu <teawater@xxxxxxxxx>
---
scripts/gtp/add-ons/hotcode.py | 747 +++++++++++++++++++++++++++++++++++++++++
scripts/gtp/add-ons/pe.py | 729 ++++++++++++++++++++++++++++++++++++++++
scripts/gtp/getgtprsp.pl | 141 +++++++
scripts/gtp/getmod.py | 148 ++++++++
4 files changed, 1765 insertions(+)

--- /dev/null
+++ b/scripts/gtp/add-ons/hotcode.py
@@ -0,0 +1,747 @@
+#!/usr/bin/python
+
+# This script is used to find the hotcode in some tasks
+# GPL
+# Copyright(C) Hui Zhu (teawater@xxxxxxxxx), 2012
+
+import gdb
+import tempfile
+import os
+import signal
+import sys
+import traceback
+import time
+
+class hotcode_list:
+ def __init__(self):
+ self.function_list = {}
+ self.file_list = {}
+ self.line_list = {}
+ self.function_list_line = {}
+ self.file_list_line = {}
+ self.num = 0
+
+class task:
+ def __init__(self, fid, user_dir):
+ self.fid = fid
+ self.user_dir = user_dir
+ self.kernel = hotcode_list()
+ self.user = hotcode_list()
+
+debug_dir = "/usr/lib/debug/"
+task_list = {}
+no_task = False
+kernel_hotcode_list = hotcode_list()
+
+output_html = True
+output_html_file = "./hotcode.html"
+show_line_number_default = 20
+show_line_number = show_line_number_default
+
+#--------------------------------------------------------------------------------------------------
+#For signal handler
+
+from operator import itemgetter
+def dict_sort(d, reverse=False):
+ #proposed in PEP 265, using the itemgetter
+ return sorted(d.iteritems(), key=itemgetter(1), reverse=True)
+
+def hotcode_show_code_list(string, code_list):
+ if len(code_list) > 0:
+ print "\t", string
+ i = 1
+ for c in dict_sort(code_list):
+ print "\t", c[0], "\t\t", c[1]
+ i += 1
+ if i > show_line_number:
+ break
+ print
+
+def hotcode_show():
+ if no_task:
+ hotcode_show_code_list("Hotest function", kernel_hotcode_list.function_list)
+ hotcode_show_code_list("Hotest file", kernel_hotcode_list.file_list)
+ hotcode_show_code_list("Hotest line", kernel_hotcode_list.line_list)
+ else:
+ for pid in task_list:
+ print "task", str(pid), task_list[pid].user_dir
+ print "Kernel hotcode:"
+ hotcode_show_code_list("Hotest function", task_list[pid].kernel.function_list)
+ hotcode_show_code_list("Hotest file", task_list[pid].kernel.file_list)
+ hotcode_show_code_list("Hotest line", task_list[pid].kernel.line_list)
+ print "User hotcode:"
+ hotcode_show_code_list("Hotest function", task_list[pid].user.function_list)
+ hotcode_show_code_list("Hotest file", task_list[pid].user.file_list)
+ hotcode_show_code_list("Hotest line", task_list[pid].user.line_list)
+ 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.function_list, hlist.function_list_line, fd)
+
+ fd.write('''<tr><td style="text-align: center;" colspan="2">Hot file list</td></tr>''')
+ hotcode_list_to_output_html_fd_1(hlist.file_list, hlist.file_list_line, fd)
+
+ fd.write('''<tr><td style="text-align: center;" colspan="2">Hot line list</td></tr>''')
+ hotcode_list_to_output_html_fd_1(hlist.line_list, 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>) in ''' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '''.</div>
+<div style="text-align: center;">Click the function name or file name to see the detailed info.</div>''')
+ if show_line_number > 0:
+ fd.write('''<div style="text-align: center;">Just show top 20 of each list.</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>''')
+ fd.write('''<tr><td><strong>Kernel space hotcode list</strong></td><td style=" width: 10%; text-align: right;">'''+str(kernel_hotcode_list.num)+'''</td></tr>''')
+ 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].user_dir + "</td></tr>")
+ if trace_user:
+ fd.write('''<tr><td style="text-align: center;" colspan="2">User space hotcode list </td></tr>''')
+ fd.write('''<tr><td><strong>User space hotcode list</strong></td><td style=" width: 10%; text-align: right;">'''+str(task_list[pid].user.num)+'''</td></tr>''')
+ hotcode_list_to_output_html_fd(task_list[pid].user, fd)
+ if trace_kernel:
+ if trace_user:
+ fd.write('''<tr><td style="text-align: center;" colspan="2"></td></tr>''')
+ fd.write('''<tr><td><strong>Kernel space hotcode list</strong></td><td style=" width: 10%; text-align: right;">'''+str(task_list[pid].kernel.num)+'''</td></tr>''')
+ hotcode_list_to_output_html_fd(task_list[pid].kernel, fd)
+ fd.write('</tbody></table>')
+ fd.write('</body></html>')
+ fd.close()
+ print "Save", html_id, "entries."
+
+def sigint_handler(num, e):
+ if output_html:
+ hotcode_to_output_html_file()
+ else:
+ hotcode_show()
+ try:
+ s = raw_input('Conitnue? [(y)es], (n)o:')
+ except:
+ s = 'y'
+ finally:
+ if s[0:1] != 'n' and s[0:1] != 'N':
+ return;
+ #gdb.execute("inferior 1")
+ try:
+ gdb.execute("tfind -1", True, False)
+ gdb.execute("target remote /sys/kernel/debug/gtp", True, False)
+ gdb.execute("set disconnected-tracing off", True, False)
+ except:
+ print "Try to stop GTP got error, please use command \"sudo rmmod gtp.ko\" stop it."
+ exit(1);
+#--------------------------------------------------------------------------------------------------
+#init
+
+def add_inferior():
+ fid = gdb.execute("add-inferior", False, True)
+ if fid.find("Added inferior ") != 0:
+ return -1
+ fid = int(fid[len("Added inferior "):])
+ return fid
+
+gdb.execute("set target-async on", True, False)
+gdb.execute("set pagination off", True, False)
+gdb.execute("set confirm off", True, False)
+gdb.execute("set circular-trace-buffer on", True, False)
+gdb.execute("set debug-file-directory "+debug_dir, True, False)
+try:
+ gdb.execute("kill", True, False)
+except:
+ pass
+
+trace_user = True
+trace_kernel = True
+while 1:
+ tmp = "both"
+ try:
+ tmp = raw_input('Which part of code you want trace? [(b)oth], (u)ser, (k)ernel:')
+ except:
+ continue
+ if tmp[0:1] == 'U' or tmp[0:1] == 'u':
+ trace_kernel = False
+ elif tmp[0:1] == 'K' or tmp[0:1] == 'k':
+ trace_user = False
+ break
+
+#Get which task pid why want to trace
+print("Please input the pid of task that you want to trace - one per line.")
+print("If not set any task, will trace all code in the Linux kernel.")
+while 1:
+ pid = -1
+ try:
+ pid = input('task pid (use empty to stop pid input):')
+ except:
+ pass
+ if pid <= 0:
+ break
+ if pid in task_list:
+ print("This pid already in the list.")
+ continue
+ user_dir = ""
+ fid = 0
+ if trace_user:
+ try:
+ orig_user_dir = user_dir = os.path.realpath("/proc/"+str(pid)+"/exe")
+ except:
+ #maybe this is the kernel task
+ print "Cannot get the user code info of this pid, will not parse the user level code symbol"
+ task_list[pid] = task(fid, user_dir)
+ continue
+ if os.path.exists(debug_dir+user_dir):
+ user_dir = debug_dir+user_dir
+ while 1:
+ tmp = ""
+ try:
+ tmp = raw_input('Please input the debug binary of task if you want to change it ['+user_dir+']:')
+ except:
+ continue
+ if tmp != "":
+ user_dir = os.path.realpath(tmp)
+ break
+ if not os.path.exists(user_dir):
+ print "Cannot get the user code info of this pid, will not parse the user level code symbol"
+ task_list[pid] = task(fid, user_dir)
+ continue
+ print "Use "+user_dir+" as debug binary."
+ fid = add_inferior()
+ if fid < 0:
+ print "Try to load task got error."
+ continue
+ gdb.execute("inferior "+str(fid))
+ pfile = open("/proc/"+str(pid)+"/maps", "r")
+ tmplist = pfile.read().split(os.linesep)
+ pfile.close()
+ for c in tmplist:
+ c_list = c.split(" ")
+ filename = c_list[-1].strip()
+ if filename != orig_user_dir and os.path.exists(filename) and len(c_list) > 2 and len(c_list[1]) > 3 and c_list[1][2] == 'x':
+ addr = "0x"+c_list[0][0:c.find('-')]
+ gdb.execute("file "+filename)
+ info_files = gdb.execute("info files", True, True)
+ info_files_list = info_files.split(os.linesep)
+ text_offset = "0x0"
+ for line in info_files_list:
+ line_list = line.split(" is ")
+ if len(line_list) == 2 and line_list[1].strip() == ".text":
+ line_list[0] = line_list[0].strip()
+ text_offset = line_list[0][0:line_list[0].find(' - ')]
+ print ("add-symbol-file "+filename+" ("+addr+"+"+text_offset+")")
+ gdb.execute("add-symbol-file "+filename+" ("+addr+"+"+text_offset+")")
+ gdb.execute("file "+user_dir)
+ gdb.execute("inferior 1")
+ task_list[pid] = task(fid, user_dir)
+
+def get_addr_range_list(fun):
+ buf = gdb.execute("info line "+fun, False, True)
+ line_list = buf.split(os.linesep)
+ ret = []
+ begin = -1
+ end = -1
+ for line in line_list:
+ addr_begin = line.find("starts at address ")
+ if addr_begin >= 0:
+ line = line[addr_begin + len("starts at address "):]
+ addr_end = line.find(" <"+fun)
+ if addr_end >= 0:
+ begin = int(line[:addr_end], 0)
+ line = line[addr_end + len(" <"+fun):]
+ addr_begin = line.find("ends at ")
+ if addr_begin >= 0:
+ line = line[addr_begin + len("ends at "):]
+ addr_end = line.find(" <"+fun)
+ if addr_end > 0:
+ end = int(line[:addr_end], 0)
+ if begin != -1:
+ ret.append([begin, end])
+ begin = -1
+ end = -1
+
+ if len(ret) > 0:
+ buf = gdb.execute("disassemble "+fun, False, True)
+ line_list = buf.split(os.linesep)
+ line_list.reverse()
+ end = 0
+ for line in line_list:
+ addr_begin = line.find("0x")
+ if addr_begin >= 0:
+ line = line[addr_begin:]
+ addr_end = line.find(" <+")
+ if addr_end > 0:
+ end = int(line[:addr_end], 0) + 1
+ break
+ if end != 0:
+ offset = 0
+ for c in ret:
+ if c[1] < end:
+ if offset == 0 or offset > (end - c[1]):
+ offset = end - c[1]
+ for c in ret:
+ c[1] += offset
+
+ return ret
+
+def get_ignore_str(function):
+ ret = ""
+ try:
+ s = raw_input('Do you want to ignore function \"'+function+'\"? [(y)es], (n)o:')
+ except:
+ s = 'y'
+ if s[0:1] != 'n' and s[0:1] != 'N':
+ r_list = get_addr_range_list(function)
+ for r in r_list:
+ if ret != "":
+ ret += " && "
+ else:
+ ret += "&& ("
+ #(regs->ip < r[0] || regs->ip > r[1])
+ ret += "($pc_ip0 < "+str(r[0])+" || $pc_ip0 > "+str(r[1])+")"
+ if ret != "":
+ ret += ")"
+ return ret
+
+if len(task_list) == 0:
+ trace_user = False
+ 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:
+ show_line_number = show_line_number_default
+
+#Set tracepoint
+gdb.execute("target remote /sys/kernel/debug/gtp", True, False)
+
+try:
+ gdb.execute("tstop", True, False)
+ gdb.execute("delete", True, False)
+except:
+ pass
+
+
+def getmod():
+ #following code is get from ../getmod.py
+ #use the code directly because sys.argv = [''] inside GDB
+ def format_file(name):
+ tmp = ""
+ for c in name:
+ if c == "_":
+ c = "-"
+ tmp += c
+ return tmp
+
+ #Check if the target is available
+ if str(gdb.selected_thread()) == "None":
+ raise gdb.error("Please connect to Linux Kernel before use the script.")
+
+ #Output the help
+ print "Use GDB command \"set $mod_search_dir=dir\" to set an directory for search the modules."
+
+ ignore_gtp_ko = gdb.parse_and_eval("$ignore_gtp_ko")
+ if ignore_gtp_ko.type.code == gdb.TYPE_CODE_INT:
+ ignore_gtp_ko = int(ignore_gtp_ko)
+ else:
+ ignore_gtp_ko = 1
+
+ #Get the mod_search_dir
+ mod_search_dir_list = []
+ #Get dir from $mod_search_dir
+ tmp_dir = gdb.parse_and_eval("$mod_search_dir")
+ if tmp_dir.type.code == gdb.TYPE_CODE_ARRAY:
+ tmp_dir = str(tmp_dir)
+ tmp_dir = tmp_dir[1:len(tmp_dir)]
+ tmp_dir = tmp_dir[0:tmp_dir.index("\"")]
+ mod_search_dir_list.append(tmp_dir)
+ #Get dir that same with current vmlinux
+ tmp_dir = str(gdb.execute("info files", False, True))
+ tmp_dir = tmp_dir[tmp_dir.index("Symbols from \"")+len("Symbols from \""):len(tmp_dir)]
+ tmp_dir = tmp_dir[0:tmp_dir.index("\"")]
+ tmp_dir = tmp_dir[0:tmp_dir.rindex("/")]
+ mod_search_dir_list.append(tmp_dir)
+ #Get the dir of current Kernel
+ tmp_dir = "/lib/modules/" + str(os.uname()[2])
+ if os.path.isdir(tmp_dir):
+ mod_search_dir_list.append(tmp_dir)
+ #Let user choice dir
+ mod_search_dir = ""
+ while mod_search_dir == "":
+ for i in range(0, len(mod_search_dir_list)):
+ print str(i)+". "+mod_search_dir_list[i]
+ try:
+ s = input('Select a directory for search the modules [0]:')
+ except SyntaxError:
+ s = 0
+ except:
+ continue
+ if s < 0 or s >= len(mod_search_dir_list):
+ continue
+ mod_search_dir = mod_search_dir_list[s]
+
+ mod_list_offset = long(gdb.parse_and_eval("((size_t) &(((struct module *)0)->list))"))
+ mod_list = long(gdb.parse_and_eval("(&modules)"))
+ mod_list_current = mod_list
+
+ while 1:
+ mod_list_current = long(gdb.parse_and_eval("((struct list_head *) "+str(mod_list_current)+")->next"))
+
+ #check if need break the loop
+ if mod_list == mod_list_current:
+ break
+
+ mod = mod_list_current - mod_list_offset
+
+ #get mod_name
+ mod_name = str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->name"))
+ mod_name = mod_name[mod_name.index("\"")+1:len(mod_name)]
+ mod_name = mod_name[0:mod_name.index("\"")]
+ if mod_name == "fglrx":
+ contiue
+ mod_name += ".ko"
+ mod_name = format_file(mod_name)
+
+ #get mod_dir_name
+ mod_dir_name = ""
+ for root, dirs, files in os.walk(mod_search_dir):
+ for afile in files:
+ tmp_file = format_file(afile)
+ if tmp_file == mod_name:
+ mod_dir_name = os.path.join(root,afile)
+ break
+ if mod_dir_name != "":
+ break
+
+ command = " "
+
+ #Add module_core to command
+ command += str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->module_core"))
+
+ #Add each sect_attrs->attrs to command
+ #get nsections
+ nsections = int(gdb.parse_and_eval("((struct module *)"+str(mod)+")->sect_attrs->nsections"))
+ sect_attrs = long(gdb.parse_and_eval("(u64)((struct module *)"+str(mod)+")->sect_attrs"))
+ for i in range(0, nsections):
+ command += " -s"
+ tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].name"))
+ tmp = tmp[tmp.index("\"")+1:len(tmp)]
+ tmp = tmp[0:tmp.index("\"")]
+ command += " "+tmp
+ tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].address"))
+ command += " "+tmp
+
+ if mod_dir_name == "":
+ print "Cannot find out",mod_name,"from directory."
+ print "Please use following command load the symbols from it:"
+ print "add-symbol-file some_dir/"+mod_name+command
+ else:
+ if ignore_gtp_ko and mod_name == "gtp.ko":
+ pass
+ else:
+ #print "add-symbol-file "+mod_dir_name+command
+ gdb.execute("add-symbol-file "+mod_dir_name+command, False, False)
+
+if trace_kernel:
+ try:
+ s = raw_input('Do you load the symbol from LKM? (y)es, [(n)o]:')
+ except:
+ s = 'n'
+ if s[0:1] == 'y' or s[0:1] == 'Y':
+ getmod()
+
+cpu_number = int(gdb.parse_and_eval("$cpu_number"))
+tempfilename = tempfile.mktemp()
+tempfile = open(tempfilename, "w")
+if no_task:
+ ignore_str = ""
+ #Setup first tracepoint
+ ignore_str += get_ignore_str("arch_local_irq_enable")
+ ignore_str += get_ignore_str("intel_idle")
+ # GDB have bug with long conditon so close them
+ #ignore_str += get_ignore_str("__do_softirq")
+ #ignore_str += get_ignore_str("_raw_spin_unlock_irqrestore")
+
+ for i in range(0, cpu_number):
+ tempfile.write("tvariable $pc_ip"+str(i)+"\n")
+ tempfile.write("tvariable $pc_cs"+str(i)+"\n")
+ tempfile.write("trace handle_irq\n")
+ tempfile.write("commands\n")
+ tempfile.write("teval $pc_ip0=(u64)regs->ip\n")
+ tempfile.write("teval $pc_cs0=(u64)regs->cs\n")
+ tempfile.write("end\n")
+ #Setup second tracepoint
+ tempfile.write("trace handle_irq\n")
+ cond_str = " (($pc_cs0 & 3) == 0)"
+ tempfile.write("condition $bpnum "+cond_str+ignore_str+"\n")
+ tempfile.write("commands\n")
+ tempfile.write("collect $no_self_trace\n")
+ tempfile.write("collect $pc_ip0\n")
+ tempfile.write("end\n")
+ tempfile.write("trace smp_apic_timer_interrupt\n")
+ tempfile.write("commands\n")
+ tempfile.write("teval $pc_ip0=(u64)regs->ip\n")
+ tempfile.write("teval $pc_cs0=(u64)regs->cs\n")
+ tempfile.write("end\n")
+ #Setup second tracepoint
+ tempfile.write("trace smp_apic_timer_interrupt\n")
+ cond_str = " (($pc_cs0 & 3) == 0)"
+ tempfile.write("condition $bpnum "+cond_str+ignore_str+"\n")
+ tempfile.write("commands\n")
+ tempfile.write("collect $no_self_trace\n")
+ tempfile.write("collect $pc_ip0\n")
+ tempfile.write("end\n")
+else:
+ pid_str = ""
+ for pid in task_list:
+ if pid_str != "":
+ pid_str += " || "
+ else:
+ pid_str += "("
+ pid_str += "($current_task_pid == "+str(pid)+") "
+ if pid_str != "":
+ pid_str += ")"
+ cond_str = ""
+ if not trace_user:
+ if pid_str != "":
+ cond_str += " && "
+ cond_str += " ((regs->cs & 3) == 0)"
+ elif not trace_kernel:
+ if pid_str != "":
+ cond_str += "&&"
+ cond_str += " ((regs->cs & 3) == 3)"
+ tempfile.write("trace handle_irq\n")
+ tempfile.write("condition $bpnum "+pid_str+cond_str+"\n")
+ tempfile.write("commands\n")
+ tempfile.write("collect regs->ip\n")
+ if trace_user and trace_kernel:
+ tempfile.write("collect regs->cs\n")
+ tempfile.write("collect $current_task_pid\n")
+ tempfile.write("end\n")
+ tempfile.write("trace smp_apic_timer_interrupt\n")
+ tempfile.write("condition $bpnum "+pid_str+cond_str+"\n")
+ tempfile.write("commands\n")
+ tempfile.write("collect regs->ip\n")
+ if trace_user and trace_kernel:
+ tempfile.write("collect regs->cs\n")
+ tempfile.write("collect $current_task_pid\n")
+ tempfile.write("end\n")
+tempfile.close()
+tempfile = open(tempfilename, "r")
+print "Tracepoint command:"
+print tempfile.read()
+tempfile.close()
+gdb.execute("source "+tempfilename, True, False)
+os.remove(tempfilename)
+gdb.execute("set disconnected-tracing on", True, False)
+gdb.execute("tstart")
+gdb.execute("kill", True, False)
+
+signal.signal(signal.SIGINT, sigint_handler);
+signal.siginterrupt(signal.SIGINT, False);
+
+#Connect to pipe
+gdb.execute("target tfile /sys/kernel/debug/gtpframe_pipe")
+
+#--------------------------------------------------------------------------------------------------
+#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.function_list:
+ code_list.function_list[info[2]] += 1
+ else:
+ code_list.function_list[info[2]] = 1
+ code_list.function_list_line[info[2]] = {}
+ add_line_to_list(line, code_list.function_list_line[info[2]])
+ #file_list
+ if info[1] in code_list.file_list:
+ code_list.file_list[info[1]] += 1
+ else:
+ code_list.file_list[info[1]] = 1
+ code_list.file_list_line[info[1]] = {}
+ add_line_to_list(line, code_list.file_list_line[info[1]])
+ #line_list
+ add_line_to_list(line, code_list.line_list)
+ #num
+ code_list.num += 1
+
+def task_list_add_line(is_user, pid, info):
+ global task_list
+ if no_task:
+ add_info_to_code_list (info, kernel_hotcode_list)
+ else:
+ if is_user:
+ add_info_to_code_list (info, task_list[pid].user)
+ else:
+ add_info_to_code_list (info, task_list[pid].kernel)
+
+def get_line_from_sym(sym):
+ sym = sym.rstrip(os.linesep)
+
+ #Get line_num and file_name
+ begin = sym.find("Line ")
+ end = sym.find("\" starts at address")
+ line_num = None
+ file_name = None
+ if begin >= 0 and end > 0 and begin + len("Line ") < end:
+ line = sym[begin + len("Line "):end]
+ line = line.split(" of \"")
+ if len(line) == 2:
+ line_num = line[0]
+ file_name = line[1]
+ sym = sym[end:]
+
+ #Get function_name
+ begin = sym.find("<")
+ end = sym.find(">")
+ if begin >= 0 and end > 0 and begin + 1 < end:
+ function_name = sym[begin + 1:end]
+ end = function_name.rfind("+")
+ if end > 0:
+ function_name = function_name[:end]
+ sym = gdb.execute("info symbol "+function_name, True, True).rstrip(os.linesep)
+ begin = sym.rfind(" of ")
+ if begin > 0:
+ begin += len(" of ")
+ function_name = sym[begin:] + ":" + function_name
+ else:
+ function_name = None
+ return (line_num, file_name, function_name)
+
+if no_task:
+ while 1:
+ try:
+ gdb.execute("tfind 0", False, True)
+ cpu_id = long(gdb.parse_and_eval("$cpu_id"));
+ sym = gdb.execute("info line *($pc_ip"+str(cpu_id)+" - 1)", True, True)
+ line = get_line_from_sym(sym)
+ task_list_add_line(False, 0, line)
+ except gdb.error, 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:")
+ 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:
+ pass
+else:
+ while 1:
+ try:
+ gdb.execute("tfind 0", False, True)
+ is_user = False
+ 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 (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].fid), False, True)
+ sym = gdb.execute("info line *"+str(ip), True, True)
+ else:
+ sym = gdb.execute("info line *(regs->ip - 1)", True, True)
+ line = get_line_from_sym(sym)
+ if is_user:
+ gdb.execute("inferior 1", False, True)
+ task_list_add_line(is_user, pid, line)
+ except gdb.error, 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:")
+ 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
+ try:
+ gdb.execute("tfind 1", False, True)
+ except:
+ pass
--- /dev/null
+++ b/scripts/gtp/add-ons/pe.py
@@ -0,0 +1,729 @@
+#!/usr/bin/python
+
+# This script is used to show the performance counters in graph mode
+# GPL
+# Copyright(C) Hui Zhu (teawater@xxxxxxxxx), 2011
+
+
+pe_list = []
+#0 type, 1 config, 2 name
+#typt and config can get from https://code.google.com/p/kgtp/wiki/HOWTO#How_to_use_performance_counters
+pe_list.append(["0","0", "CPU_CYCLES"])
+pe_list.append(["0","1", "INSTRUCTIONS"])
+pe_list.append(["0","2", "CACHE_REFERENCES"])
+pe_list.append(["0","3", "CACHE_MISSES"])
+pe_list.append(["0","4", "BRANCH_INSTRUCTIONS"])
+pe_list.append(["0","5", "BRANCH_MISSES"])
+pe_list.append(["0","6", "BUS_CYCLES"])
+pe_list.append(["3","0", "L1D_READ_ACCESS"])
+pe_list.append(["3","1", "L1I_READ_ACCESS"])
+
+#sleep time
+sleep_sec = 1
+
+#0 text 1 gtk
+gui_type = 1
+
+in_gdb = False
+
+
+pe_list_type = 0
+pe_list_config = 1
+pe_list_name = 2
+pe_list_prev = 3
+pe_list_qtv = 4
+
+if in_gdb:
+ import gdb
+else:
+ import os
+
+
+class kgtp:
+ fd = -1
+ retry_count = 3
+ buf_max = 1024
+ tvariable = {}
+ tvariable_next_number = 0
+
+ def __init__(self):
+ #Open fd
+ try:
+ self.fd = os.open("/sys/kernel/debug/gtp", os.O_RDWR)
+ except:
+ print "Please do not forget insmod and sudo."
+ exit(0)
+
+ def __del__(self):
+ if self.fd >= 0:
+ os.close(self.fd)
+
+ def read_fd(self):
+ try:
+ buf = os.read(self.fd, self.buf_max)
+ except:
+ return False
+ return buf
+
+ def write_fd(self, msg):
+ try:
+ buf = os.write(self.fd, msg)
+ except:
+ return False
+ return True
+
+ def read(self):
+ for i in range(0, self.retry_count):
+ if i != 0:
+ self.write_fd("-")
+
+ buf = self.read_fd()
+ if buf == False:
+ continue
+ buf_len = len(buf)
+ if buf_len < 4:
+ continue
+
+ csum = 0
+ for i in range(0, buf_len - 2):
+ if i == 0:
+ if buf[i] != "$":
+ retry = True
+ break
+ elif buf[i] == '#':
+ break
+ else:
+ csum += ord(buf[i])
+ if i == 0 or buf[i] != "#":
+ continue
+ if int("0x"+buf[i+1:i+3], 16) != (csum & 0xff):
+ continue
+ buf = buf[1:i]
+ self.write_fd("+")
+
+ #print "KGTP read: "+buf
+ return buf
+
+ print "KGTP read got error"
+ return False
+
+ def write(self, msg):
+ for i in range(0, self.retry_count):
+ if i != 0:
+ self.write_fd("-")
+
+ csum = 0
+ for c in msg:
+ csum += ord(c)
+ msg = "$"+msg+"#"+"%02x" % (csum & 0xff)
+
+ if self.write_fd(msg) == False:
+ continue
+ if self.read_fd() != "+":
+ continue
+
+ #print "KGTP write: "+msg
+ return True
+
+ print "KGTP write got error"
+ return False
+
+ def simple_cmd(self, cmd):
+ if gtp.write(cmd) == False:
+ return False
+ if gtp.read() != "OK":
+ return False
+ return True
+
+ def tvariable_init(self):
+ tvariable = {}
+ tvariable_next_number = 0
+
+ if gtp.write("qTfV") == False:
+ return False
+ ret = gtp.read()
+ while 1:
+ if ret == False:
+ return False
+ if ret == "l":
+ return True
+ ret = ret.split(":")
+ if len(ret) < 4:
+ print "KGTP GDBRSP package format error"
+ return False
+ if len(ret[3]) % 2 != 0:
+ print "KGTP GDBRSP package format error"
+ return False
+
+ #Get name
+ letter = ""
+ name = ""
+ for c in ret[3]:
+ letter += c
+ if len(letter) == 2:
+ name += chr(int("0x"+letter, 16))
+ letter = ""
+
+ number = int("0x"+ret[0], 16)
+ self.tvariable[name] = number
+ if (number >= self.tvariable_next_number):
+ self.tvariable_next_number = number + 1
+
+ if gtp.write("qTsV") == False:
+ return False
+ ret = gtp.read()
+
+ def tvariable_val(self, number):
+ return self.tvariable_val_raw("qTV:"+"%x" % number)
+
+ def tvariable_val_raw(self, buf):
+ if gtp.write(buf) == False:
+ return
+ ret = gtp.read()
+ if ret == False:
+ return
+ if ret[0] != "V":
+ return
+
+ return long("0x"+ret[1:], 16)
+
+ def tvariable_add(self, name, val):
+ if self.tvariable_next_number == 0:
+ print "Must call tvariable_init before add tvariable"
+ return
+
+ buf = "QTDV:" + "%x" % self.tvariable_next_number + ":" + "%x" % val + ":0:"
+ for c in name:
+ buf += "%02x" % ord(c)
+ if gtp.write(buf) == False:
+ return
+ if gtp.read() != "OK":
+ print "Get something wrong when add tvariable to KGTP"
+ return
+
+ self.tvariable_next_number += 1
+ return (self.tvariable_next_number - 1)
+
+ def qtinit(self):
+ return self.simple_cmd("QTinit")
+
+ def tstart(self):
+ return self.simple_cmd("QTStart")
+
+ def tstop(self):
+ return self.simple_cmd("QTStop")
+
+
+def each_entry(callback):
+ global pe_list, cpu_number
+ for i in range(0, cpu_number):
+ for e in pe_list:
+ callback(i, e)
+
+
+def init_pe(i, e):
+ if (len(e) < pe_list_prev + 1):
+ e.append([])
+ e[pe_list_prev].append(0)
+ if (len(e) < pe_list_qtv + 1):
+ e.append([])
+
+ if in_gdb:
+ gdb.execute("tvariable $pc_pe_type_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i)+"="+e[pe_list_type], True, False)
+ gdb.execute("tvariable $pc_pe_config_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i)+"="+e[pe_list_config], True, False)
+ gdb.execute("tvariable $pc_pe_val_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i)+"=0", True, False)
+ gdb.execute("tvariable $pc_pe_en_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i)+"=1", True, False)
+ else:
+ if gtp.tvariable_add("pc_pe_type_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i), int(e[pe_list_type])) == None:
+ exit(0)
+ if gtp.tvariable_add("pc_pe_config_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i), int(e[pe_list_config])) == None:
+ exit(0)
+ number = gtp.tvariable_add("pc_pe_val_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i), 0)
+ if number == None:
+ exit(0)
+ if gtp.tvariable_add("pc_pe_en_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i), 1) == None:
+ exit(0)
+ e[pe_list_qtv].append("qTV:"+"%x" % number)
+
+def init_kgtp():
+ global cpu_number
+
+ if in_gdb:
+ cpu_number = int(gdb.parse_and_eval("$cpu_number"))
+ #Set the empty tracepoint
+ gdb.execute("delete tracepoints", False, False)
+ gdb.execute("trace *0", True, False)
+ else:
+ cpu_number = gtp.tvariable_val(gtp.tvariable["cpu_number"])
+ if cpu_number == None:
+ exit(0)
+
+ #Set the pe
+ each_entry(init_pe)
+
+import signal
+def sigint_handler(num, e):
+ if in_gdb:
+ gdb.execute("tstop", True, False)
+ else:
+ gtp.tstop()
+ exit(0)
+
+
+if in_gdb:
+ #close pagination
+ gdb.execute("set pagination off", True, False);
+ #Connect to KGTP if need
+ if str(gdb.selected_thread()) == "None":
+ gdb.execute("target remote /sys/kernel/debug/gtp", True, False)
+else:
+ gtp = kgtp()
+ if gtp.qtinit == False:
+ exit(0)
+ if gtp.tvariable_init() == False:
+ exit(0)
+
+#Init the status to KGTP
+cpu_number = 0
+init_kgtp()
+signal.signal(signal.SIGINT, sigint_handler)
+
+
+#start
+if in_gdb:
+ gdb.execute("tstart", True, False)
+else:
+ gtp.tstart()
+
+
+#text gui ---------------------------------------------------------------------
+#pe_list will be set to:type, config, name, prev_value_list
+if gui_type == 0:
+ import time
+ def output_pe(i, e):
+ if in_gdb:
+ current_value = long(gdb.parse_and_eval("$pc_pe_val_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i)))
+ else:
+ current_value = gtp.tvariable_val_raw(e[pe_list_qtv][i])
+ if current_value == None:
+ print "Fail when get val from KGTP"
+ exit(0)
+ print "cpu"+str(i),e[pe_list_name],current_value-e[pe_list_prev][i]
+ e[pe_list_prev][i] = current_value
+
+ while 1:
+ each_entry(output_pe)
+ print
+ time.sleep(sleep_sec)
+
+
+#gtk gui ----------------------------------------------------------------------
+#pe_list will be set to:0 type, 1 config, 2 name, 3 prev_value_list,
+# 4 value_list, 5 x_list, 6 button_list,
+# 7 button_color_list, 8 line_color_list
+if gui_type == 1:
+ #This script need python-gtk2
+ import gtk
+ import glib
+
+ pe_list_value = 5
+ pe_list_x = 6
+ pe_list_button = 7
+ pe_list_bcolor = 8
+ pe_list_lcolor = 9
+
+ pe_color = (0xffb0ff, 0x006000)
+
+ class PyApp(gtk.Window):
+ #Init ----------------------------------------------------------
+ def __init__(self):
+ global pe_list, cpu_number
+
+ super(PyApp, self).__init__()
+
+ self.max_value = 0
+ self.prev_width = 0
+ self.prev_height = 0
+ self.y_ratio = 0
+ self.entry_width = 10
+ self.logfd = False
+
+ #Set the pe
+ each_entry(self.pe_init_callback)
+
+ #Set the color
+ num = len(pe_list) * cpu_number
+ block = (pe_color[0] - pe_color[1]) / float(num)
+ color = pe_color[1]
+ for i in range(0, cpu_number):
+ for e in pe_list:
+ e[pe_list_bcolor].append(gtk.gdk.Color("#"+ "%06x" % int(color)))
+ e[pe_list_lcolor].append((((int(color) >> 16) / float(0xff) * 1), ((int(color) >> 8 & 0xff) / float(0xff) * 1), ((int(color) & 0xff) / float(0xff) * 1)))
+ color += block
+
+ #Set window
+ self.set_title("KGTP")
+ self.connect("destroy", gtk.main_quit)
+ gtk.Window.maximize(self)
+
+ #menubar
+ mb = gtk.MenuBar()
+ #file
+ filemenu = gtk.Menu()
+ filem = gtk.MenuItem("File")
+ filem.set_submenu(filemenu)
+ save = gtk.CheckMenuItem("Save log to a CSV file")
+ save.connect("activate", self.mb_save)
+ save.set_active(False)
+ exit = gtk.MenuItem("Exit")
+ exit.connect("activate", gtk.main_quit)
+ filemenu.append(save)
+ filemenu.append(gtk.SeparatorMenuItem())
+ filemenu.append(exit)
+ mb.append(filem)
+ #set
+ setmenu = gtk.Menu()
+ setm = gtk.MenuItem("Settings")
+ setm.set_submenu(setmenu)
+ show_buttons = gtk.CheckMenuItem("Show buttons")
+ show_buttons.set_active(True)
+ show_buttons.connect("activate", self.show_buttons)
+ setmenu.append(show_buttons)
+ mb.append(setm)
+
+ #Widget
+ #Creat self.darea
+ self.darea = gtk.DrawingArea()
+ self.darea.connect("expose-event", self.expose)
+ self.darea.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#FFFFFF"))
+ #Creat all ToggleButton for each pe
+ each_entry(self.pe_gtk_creat_button)
+ #Creat button_hboxes
+ self.button_hboxes = self.pe_gtk_creat_button_hboxes_first()
+
+ #Add mb and widget to window
+ self.vbox = gtk.VBox(False, 0)
+ self.vbox.pack_start(mb, False, False, 0)
+ self.vbox.pack_start(self.darea, True, True, 0)
+ for e in self.button_hboxes:
+ self.vbox.pack_start(e, False, False, 0)
+ self.add(self.vbox)
+
+ #First show to get the right size
+ self.show_all()
+ size = self.pe_gtk_get_size()
+
+ #Reset the button_hboxes
+ each_entry(self.pe_gtk_remove_creat_button_hboxes)
+ for e in self.button_hboxes:
+ self.vbox.remove(e)
+ self.button_hboxes = self.pe_gtk_creat_button_hboxes_second(size)
+ for e in self.button_hboxes:
+ self.vbox.pack_start(e, False, False, 0)
+ self.show_all()
+
+ #Reset the value of each button
+ each_entry(self.button_reset)
+
+ #Add timer
+ glib.timeout_add(int(sleep_sec * 1000), self.timer_cb)
+ #Remove the first entry because it already record a big value
+ glib.timeout_add(int(sleep_sec * 1100), self.timer_remove_first_record)
+
+ def __del__(self):
+ if self.logfd:
+ self.logfd.close()
+ self.logfd = False
+
+ def pe_init_callback(self, i, e):
+ if (len(e) < pe_list_value + 1):
+ e.append([])
+ e[pe_list_value].append([])
+ if (len(e) < pe_list_x + 1):
+ e.append([])
+ e[pe_list_x].append([])
+ if (len(e) < pe_list_button + 1):
+ e.append([])
+ if (len(e) < pe_list_button + 1):
+ e.append([])
+ if (len(e) < pe_list_bcolor + 1):
+ e.append([])
+ if (len(e) < pe_list_lcolor + 1):
+ e.append([])
+
+ def pe_gtk_creat_button(self, i, e):
+ e[pe_list_button].append(gtk.ToggleButton(e[pe_list_name]+":"+str(18446744073709551615)))
+ self.set_button_color(e[pe_list_button][i], e[pe_list_bcolor][i])
+ e[pe_list_button][i].connect("clicked", self.button_click)
+
+ def pe_gtk_creat_button_hboxes_first(self):
+ global pe_list, cpu_number
+
+ hboxes = []
+ self.label_list = []
+ for i in range(0, cpu_number):
+ hboxes.append(gtk.HBox(False, 0))
+ self.label_list.append(gtk.Label("CPU"+str(i)))
+ hboxes[i].pack_start(self.label_list[i], False, False, 0)
+ for e in pe_list:
+ hboxes[i].pack_start(e[pe_list_button][i], False, False, 0)
+
+ return hboxes
+
+ def pe_gtk_get_size(self):
+ global pe_list, cpu_number
+
+ #0 label size 1 button size
+ size = ([],[])
+ for i in range(0, cpu_number):
+ size[0].append(self.label_list[i].allocation.width)
+ size[1].append([])
+ for e in pe_list:
+ size[1][i].append(e[pe_list_button][i].allocation.width)
+
+ return size
+
+ def pe_gtk_remove_creat_button_hboxes(self, i, e):
+ self.button_hboxes[i].remove(e[pe_list_button][i])
+
+ def pe_gtk_creat_button_hboxes_second(self, size):
+ global pe_list, cpu_number
+
+ hboxes = []
+ hbox_id = -1
+ for i in range(0, cpu_number):
+ keep_going = True
+ prev_entry_id = 0
+ while keep_going == True:
+ width = self.allocation.width
+ keep_going = False
+ hbox_id += 1
+ hboxes.append(gtk.HBox(False, 0))
+ width -= size[0][i]
+ hboxes[hbox_id].pack_start(gtk.Label("CPU"+str(i)), False, False, 0)
+ for j in range(prev_entry_id, len(pe_list)):
+ if width - size[1][i][j] <= 0:
+ prev_entry_id = j
+ keep_going = True
+ break
+ width -= size[1][i][j] + 200
+ hboxes[hbox_id].pack_start(pe_list[j][pe_list_button][i], False, False, 0)
+
+ return hboxes
+
+ def button_reset(self, i, e):
+ e[pe_list_button][i].set_label(e[pe_list_name]+":0")
+
+ #Dialog -------------------------------------------------------
+ def dialog_error(self, msg):
+ md = gtk.MessageDialog(self,gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, msg)
+ md.run()
+ md.destroy()
+
+ #Menubar -------------------------------------------------------
+ def show_buttons(self, widget):
+ if widget.active:
+ for e in self.button_hboxes:
+ e.show()
+ else:
+ for e in self.button_hboxes:
+ e.hide()
+
+ def log_write_name(self, i, e):
+ self.logfd.write("CPU"+str(i)+" "+e[pe_list_name]+",")
+
+ def mb_save(self, widget):
+ if widget.active:
+ md = gtk.FileChooserDialog(title="Save log to a CSV file", action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons = (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK, gtk.RESPONSE_OK))
+ md.set_do_overwrite_confirmation(True)
+ md.set_current_name("pe.csv")
+ if md.run() == gtk.RESPONSE_OK:
+ try:
+ self.logfd = open(md.get_filename(), "w")
+ each_entry(self.log_write_name)
+ self.logfd.write("\n")
+ except:
+ self.dialog_error("Try to open file "+md.get_filename()+" got error")
+ widget.set_active(False)
+ if self.logfd:
+ self.logfd.close()
+ self.logfd = False
+ else:
+ widget.set_active(False)
+ md.destroy()
+ else:
+ if self.logfd:
+ self.logfd.close()
+ self.logfd = False
+
+ #Button --------------------------------------------------------
+ def refind_max_value(self, i, e):
+ if e[pe_list_button][i].get_active():
+ return
+ for i in e[pe_list_value][i]:
+ if i > self.max_value:
+ self.max_value = i
+ self.y_ratio = 0
+
+ def set_button_color(self, button, color):
+ style = button.get_style().copy()
+ style.bg[gtk.STATE_NORMAL] = color
+ style.bg[gtk.STATE_ACTIVE] = color
+ style.bg[gtk.STATE_PRELIGHT] = color
+ style.bg[gtk.STATE_SELECTED] = color
+ style.bg[gtk.STATE_INSENSITIVE] = color
+ button.set_style(style)
+
+ def button_click(self, widget):
+ if widget.get_active():
+ self.set_button_color(widget, gtk.gdk.Color("#FFFFFF"))
+ else:
+ color = False
+ for i in range(0, cpu_number):
+ for e in pe_list:
+ if e[pe_list_button][i] == widget:
+ color = e[pe_list_bcolor][i]
+ break
+ if color:
+ break
+ if color:
+ self.set_button_color(widget, color)
+ each_entry(self.refind_max_value)
+ self.darea.queue_draw()
+
+ #Timer ---------------------------------------------------------
+ def write_csv(self, msg):
+ try:
+ self.logfd.write(msg)
+ except:
+ self.dialog_error("Writ CSV file got error")
+ widget.set_active(False)
+ self.logfd.close()
+ self.logfd = False
+
+ def pe_gtk_add(self, i, e):
+ if in_gdb:
+ current_value = long(gdb.parse_and_eval("$pc_pe_val_"+e[pe_list_type]+e[pe_list_config]+"_"+str(i)))
+ else:
+ current_value = gtp.tvariable_val_raw(e[pe_list_qtv][i])
+ if current_value == None:
+ print "Fail when get val from KGTP"
+ exit(0)
+ this_value = current_value-e[pe_list_prev][i]
+ e[pe_list_value][i].append(this_value)
+ if this_value > self.max_value and not e[pe_list_button][i].get_active():
+ self.max_value = this_value
+ self.y_ratio = 0
+ e[pe_list_x][i].append(-1)
+ e[pe_list_prev][i] = current_value
+ e[pe_list_button][i].set_label(e[pe_list_name]+":"+str(this_value))
+ if self.logfd:
+ write_csv(str(this_value)+",")
+
+ def timer_cb(self):
+ each_entry(self.pe_gtk_add)
+ if self.logfd:
+ write_csv("\n")
+ self.darea.queue_draw()
+ return True
+
+ def timer_remove_first_record(self):
+ if len(pe_list[0][pe_list_value][0]) >= 1:
+ self.pe_remove_entry_num = 1
+ each_entry(self.pe_remove_entry)
+ return False
+ else:
+ return True
+
+ #DrawingArea ---------------------------------------------------
+ def pe_gtk_line(self, i, e):
+ if len(e[pe_list_value][i]) < 2:
+ return
+ if e[pe_list_button][i].get_active():
+ return
+
+ self.cr.set_source_rgb(e[pe_list_lcolor][i][0], e[pe_list_lcolor][i][1], e[pe_list_lcolor][i][2])
+ x = 0
+ for num in range(0, len(e[pe_list_value][i])):
+ if e[pe_list_value][i][num] > self.line_max:
+ self.line_max = e[pe_list_value][i][num]
+ if self.height_change or e[pe_list_x][i][num] < 0:
+ e[pe_list_x][i][num] = self.prev_height - e[pe_list_value][i][num] * self.y_ratio
+ if num == 0:
+ self.cr.move_to(x, e[pe_list_x][i][num])
+ else:
+ self.cr.line_to(x, e[pe_list_x][i][num])
+ x += self.entry_width
+ self.cr.stroke()
+
+ def pe_remove_entry(self, i, e):
+ del(e[pe_list_value][i][0:self.pe_remove_entry_num])
+ del(e[pe_list_x][i][0:self.pe_remove_entry_num])
+
+ def expose(self, widget, event):
+ self.cr = widget.window.cairo_create()
+
+ #y
+ if self.prev_height != self.darea.allocation.height:
+ self.height_change = True
+ self.prev_height = self.darea.allocation.height
+ else:
+ self.height_change = False
+ if self.max_value > 0 and (self.height_change or self.y_ratio == 0):
+ self.max_value += 100 - self.max_value % 100
+ self.y_ratio = float(self.prev_height)/self.max_value
+ self.height_change = True
+
+ #x
+ x_size = len(pe_list[0][pe_list_value][0])
+ entry_number = 0
+ if self.entry_width * x_size > self.darea.allocation.width:
+ entry_number = self.darea.allocation.width // self.entry_width
+ self.pe_remove_entry_num = x_size - entry_number
+ each_entry(self.pe_remove_entry)
+
+ #dash
+ self.cr.set_source_rgb(0, 0, 0)
+ self.cr.set_dash((1, 5))
+ #dash line for x
+ if entry_number == 0:
+ entry_number = self.darea.allocation.width // self.entry_width
+ x = 0
+ while x < self.darea.allocation.width:
+ x += self.entry_width * 10
+ self.cr.move_to(x, 0)
+ self.cr.line_to(x, self.prev_height)
+ #dash line for y
+ self.cr.move_to(0, 10)
+ self.cr.show_text(str(self.max_value))
+
+ self.cr.move_to(0, self.darea.allocation.height/4*3)
+ self.cr.show_text(str(self.max_value/4*3))
+ self.cr.line_to(self.darea.allocation.width, self.darea.allocation.height/4*3)
+
+ self.cr.move_to(0, self.darea.allocation.height/2)
+ self.cr.show_text(str(self.max_value/2))
+ self.cr.line_to(self.darea.allocation.width, self.darea.allocation.height/2)
+
+ self.cr.move_to(0, self.darea.allocation.height/4)
+ self.cr.show_text(str(self.max_value/4))
+ self.cr.line_to(self.darea.allocation.width, self.darea.allocation.height/4)
+
+ self.cr.stroke()
+ self.cr.set_dash(())
+
+ self.line_max = 0
+ each_entry(self.pe_gtk_line)
+ if self.line_max > 0 and self.line_max * 2 < self.max_value:
+ self.max_value = self.line_max
+ self.y_ratio = 0
+
+ self.height_change = False
+
+ PyApp()
+ gtk.main()
+ if in_gdb:
+ gdb.execute("tstop", True, False)
+ else:
+ gtp.tstop()
+ exit(0)
--- /dev/null
+++ b/scripts/gtp/getgtprsp.pl
@@ -0,0 +1,141 @@
+#!/usr/bin/perl
+
+# This script to get the GDB tracepoint RSP package and save it
+# to ./gtpstart and ./gtpstop file.
+# GPL
+# Copyright(C) Hui Zhu (teawater@xxxxxxxxx), 2010, 2011
+
+binmode STDIN, ":raw";
+$| = 1;
+
+$status = 0;
+$circular = 0;
+$var_count = 0;
+
+while (1) {
+ sysread STDIN, $c, 1 or next;
+ if ($c eq '') {
+ next;
+ } elsif ($c eq '+' || $c eq '-') {
+ $c = '';
+ }
+
+ sysread STDIN, $line, 1024 or next;
+ print '+';
+ $line = $c.$line;
+
+ open(LOG, ">>./log");
+ print LOG $line."\n";
+ close (LOG);
+
+ if ($status == 0) {
+ if ($line eq '$?#3f') {
+ print '$S05#b8';
+ } elsif ($line eq '$g#67') {
+ print '$00000000#80';
+ } elsif ($line eq '$k#6b') {
+ exit;
+ } elsif ($line =~ /^\$m/ || $line =~ /^\$p/) {
+ print '$00000000#80';
+ } elsif ($line eq '$qTStatus#49') {
+ print '$T0;tnotrun:0;tframes:0;tcreated:0;tsize:';
+ print '500000;tfree:500000;circular:0;disconn:0#d1';
+ } elsif ($line eq '$QTBuffer:circular:1#f9') {
+ print '$OK#9a';
+ $circular = 1;
+ } elsif ($line eq '$QTBuffer:circular:0#f8') {
+ print '$OK#9a';
+ $circular = 0;
+ } elsif ($line eq '$QTStop#4b') {
+ print '$OK#9a';
+ } elsif ($line =~ /^\$qSupported/) {
+ print '$ConditionalTracepoints+;TracepointSource+#1b';
+ } elsif ($line eq '$QTinit#59') {
+ $status = 1;
+ open(STARTFILE, ">./gtpstart");
+ print STARTFILE '$QTDisconnected:1#e3'."\n";
+ if ($circular) {
+ print STARTFILE '$QTBuffer:circular:1#f9'."\n";
+ } else {
+ print STARTFILE '$QTBuffer:circular:0#f8'."\n";
+ }
+ } elsif ($line eq '$qTfV#81') {
+ print '$18:0:1:6972715f636f756e74#ca';
+ } elsif ($line eq '$qTsV#8e') {
+ if ($var_count == 0) {
+ print '$17:0:1:736f66746972715f636f756e74#a6';
+ } elsif ($var_count == 1) {
+ print '$16:0:1:686172646972715f636f756e74#70';
+ } elsif ($var_count == 2) {
+ print '$15:0:1:6c6173745f6572726e6f#59';
+ } elsif ($var_count == 3) {
+ print '$14:0:1:69676e6f72655f6572726f72#38';
+ } elsif ($var_count == 4) {
+ print '$13:0:1:7874696d655f6e736563#35';
+ } elsif ($var_count == 5) {
+ print '$12:0:1:7874696d655f736563#99';
+ } elsif ($var_count == 6) {
+ print '$11:0:1:6b726574#48';
+ } elsif ($var_count == 7) {
+ print '$10:0:1:70635f70655f656e#4e';
+ } elsif ($var_count == 8) {
+ print '$f:0:1:6370755f6e756d626572#29';
+ } elsif ($var_count == 9) {
+ print '$e:0:1:6e6f5f73656c665f7472616365#ca';
+ } elsif ($var_count == 10) {
+ print '$d:0:1:64756d705f737461636b#22';
+ } elsif ($var_count == 11) {
+ print '$c:0:1:7072696e746b5f666f726d6174#c7';
+ } elsif ($var_count == 12) {
+ print '$b:8:1:7072696e746b5f6c6576656c#66';
+ } elsif ($var_count == 13) {
+ print '$a:0:1:7072696e746b5f746d70#54';
+ } elsif ($var_count == 14) {
+ print '$9:0:1:646973636172645f706167655f6e756d#ab';
+ } elsif ($var_count == 15) {
+ print '$8:0:1:636f6f6b65645f7264747363#01';
+ } elsif ($var_count == 16) {
+ print '$7:0:1:7264747363#57';
+ } elsif ($var_count == 17) {
+ print '$6:0:1:636f6f6b65645f636c6f636b#8d';
+ } elsif ($var_count == 18) {
+ print '$5:0:1:636c6f636b#e3';
+ } elsif ($var_count == 19) {
+ print '$4:0:1:63757272656e745f7468726561645f696e666f#21';
+ } elsif ($var_count == 20) {
+ print '$3:0:1:63757272656e745f7461736b#c9';
+ } elsif ($var_count == 21) {
+ print '$2:0:1:6370755f6964#f1';
+ } elsif ($var_count == 22) {
+ print '$1:0:1:6774705f76657273696f6e#6b';
+ } elsif ($var_count == 23) {
+ print '$19:0:1:706970655f7472616365#cb';
+ } elsif ($var_count == 24) {
+ print '$1a:0:1:63757272656e745f7461736b5f706964#03';
+ } elsif ($var_count == 25) {
+ print '$1b:200:1:6274#d7';
+ } else {
+ print '$l#6c';
+ }
+ $var_count++;
+ } else {
+ print '$#00';
+ }
+ }
+
+ if ($status == 1) {
+ print '$OK#9a';
+
+ print STARTFILE $line."\n";
+
+ if ($line eq '$QTStart#b3') {
+ $status = 0;
+
+ close(STARTFILE);
+
+ open(STOPFILE, ">./gtpstop");
+ print STOPFILE '$QTStop#4b'."\n";
+ close(STOPFILE);
+ }
+ }
+}
--- /dev/null
+++ b/scripts/gtp/getmod.py
@@ -0,0 +1,148 @@
+#!/usr/bin/python
+
+# This script is used by GDB to load the symbols from Linux kernel modules
+# GPL
+# Copyright(C) KGTP team (https://code.google.com/p/kgtp/), 2011, 2012
+
+#Set special mod_search_dir
+#set $mod_search_dir="dir"
+#Clear special mod_search_dir
+#set $mod_search_dir=(void)1
+#Not ignore gtp.ko
+#set $ignore_gtp_ko=0
+
+import gdb
+import os
+
+def get_pagination():
+ buf = gdb.execute("show pagination", False, True)
+ begin = buf.find("State of pagination is ") + len("State of pagination is ")
+ if begin < 0:
+ raise NotImplementedError("Cannot get pagination")
+ buf = buf[begin:]
+ end = buf.rfind(".")
+ buf = buf[:end]
+
+ return buf
+
+pagination = get_pagination()
+gdb.execute("set pagination off", False, False)
+
+def format_file(name):
+ tmp = ""
+ for c in name:
+ if c == "_":
+ c = "-"
+ tmp += c
+ return tmp
+
+#Check if the target is available
+if str(gdb.selected_thread()) == "None":
+ raise gdb.error("Please connect to Linux Kernel before use the script.")
+
+#Output the help
+print "Use GDB command \"set $mod_search_dir=dir\" to set an directory for search the modules."
+
+ignore_gtp_ko = gdb.parse_and_eval("$ignore_gtp_ko")
+if ignore_gtp_ko.type.code == gdb.TYPE_CODE_INT:
+ ignore_gtp_ko = int(ignore_gtp_ko)
+else:
+ ignore_gtp_ko = 1
+
+#Get the mod_search_dir
+mod_search_dir_list = []
+#Get dir from $mod_search_dir
+tmp_dir = gdb.parse_and_eval("$mod_search_dir")
+if tmp_dir.type.code == gdb.TYPE_CODE_ARRAY:
+ tmp_dir = str(tmp_dir)
+ tmp_dir = tmp_dir[1:len(tmp_dir)]
+ tmp_dir = tmp_dir[0:tmp_dir.index("\"")]
+ mod_search_dir_list.append(tmp_dir)
+#Get dir that same with current vmlinux
+tmp_dir = str(gdb.execute("info files", False, True))
+tmp_dir = tmp_dir[tmp_dir.index("Symbols from \"")+len("Symbols from \""):len(tmp_dir)]
+tmp_dir = tmp_dir[0:tmp_dir.index("\"")]
+tmp_dir = tmp_dir[0:tmp_dir.rindex("/")]
+mod_search_dir_list.append(tmp_dir)
+#Get the dir of current Kernel
+tmp_dir = "/lib/modules/" + str(os.uname()[2])
+if os.path.isdir(tmp_dir):
+ mod_search_dir_list.append(tmp_dir)
+#Let user choice dir
+mod_search_dir = ""
+while mod_search_dir == "":
+ for i in range(0, len(mod_search_dir_list)):
+ print str(i)+". "+mod_search_dir_list[i]
+ try:
+ s = input('Select a directory for search the modules [0]:')
+ except SyntaxError:
+ s = 0
+ except:
+ continue
+ if s < 0 or s >= len(mod_search_dir_list):
+ continue
+ mod_search_dir = mod_search_dir_list[s]
+
+mod_list_offset = long(gdb.parse_and_eval("((size_t) &(((struct module *)0)->list))"))
+mod_list = long(gdb.parse_and_eval("(&modules)"))
+mod_list_current = mod_list
+
+while 1:
+ mod_list_current = long(gdb.parse_and_eval("((struct list_head *) "+str(mod_list_current)+")->next"))
+
+ #check if need break the loop
+ if mod_list == mod_list_current:
+ break
+
+ mod = mod_list_current - mod_list_offset
+
+ #get mod_name
+ mod_name = str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->name"))
+ mod_name = mod_name[mod_name.index("\"")+1:len(mod_name)]
+ mod_name = mod_name[0:mod_name.index("\"")]
+ mod_name += ".ko"
+ mod_name = format_file(mod_name)
+
+ #get mod_dir_name
+ mod_dir_name = ""
+ for root, dirs, files in os.walk(mod_search_dir):
+ for afile in files:
+ tmp_file = format_file(afile)
+ if tmp_file == mod_name:
+ mod_dir_name = os.path.join(root,afile)
+ break
+ if mod_dir_name != "":
+ break
+
+ command = " "
+
+ #Add module_core to command
+ command += str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->module_core"))
+
+ #Add each sect_attrs->attrs to command
+ #get nsections
+ nsections = int(gdb.parse_and_eval("((struct module *)"+str(mod)+")->sect_attrs->nsections"))
+ sect_attrs = long(gdb.parse_and_eval("(u64)((struct module *)"+str(mod)+")->sect_attrs"))
+ for i in range(0, nsections):
+ command += " -s"
+ tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].name"))
+ tmp = tmp[tmp.index("\"")+1:len(tmp)]
+ tmp = tmp[0:tmp.index("\"")]
+ command += " "+tmp
+ tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].address"))
+ command += " "+tmp
+
+ if mod_dir_name == "":
+ print "Cannot find out",mod_name,"from directory."
+ print "Please use following command load the symbols from it:"
+ print "add-symbol-file some_dir/"+mod_name+command
+ else:
+ if ignore_gtp_ko and mod_name == "gtp.ko":
+ print "gtp.ko is ignored. You can use command \"set $ignore_gtp_ko=0\" to close this ignore."
+ print "Or you can use following command load the symbols from it:"
+ print "add-symbol-file "+mod_dir_name+command
+ else:
+ #print "add-symbol-file "+mod_dir_name+command
+ gdb.execute("add-symbol-file "+mod_dir_name+command, False, False)
+
+gdb.execute("set pagination " + pagination, False, False)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/