All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hui Zhu <hui_zhu@mentor.com>
To: <linux-kernel@vger.kernel.org>
Subject: KGTP (Linux Kernel debugger and tracer) 20120424 release(doc update)[3/3]script
Date: Tue, 24 Apr 2012 21:20:50 +0800	[thread overview]
Message-ID: <4F96A8B2.2050004@mentor.com> (raw)

Signed-off-by: Hui Zhu <teawater@gmail.com>
---
  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@gmail.com), 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@gmail.com), 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@gmail.com), 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)

                 reply	other threads:[~2012-04-24 13:21 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F96A8B2.2050004@mentor.com \
    --to=hui_zhu@mentor.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.