[kgtp] r1561 committed - Update patches

  • From: kgtp@xxxxxxxxxxxxxx
  • To: kgtp@xxxxxxxxxxxxx
  • Date: Wed, 08 May 2013 09:16:23 +0000

Revision: 1561
Author:   teawater
Date:     Wed May  8 02:15:45 2013
Log:      Update patches

http://code.google.com/p/kgtp/source/detail?r=1561

Modified:
 /trunk/gtp_2.6.20_to_2.6.32.patch
 /trunk/gtp_2.6.33_to_2.6.38.patch
 /trunk/gtp_2.6.39.patch
 /trunk/gtp_3.0_to_3.6.patch
 /trunk/gtp_3.7_to_upstream.patch
 /trunk/gtp_older_to_2.6.19.patch
 /trunk/gtp_taobao.patch
 /trunk/howto.txt
 /trunk/howtocn.txt

=======================================
--- /trunk/gtp_2.6.20_to_2.6.32.patch   Mon May  6 19:06:35 2013
+++ /trunk/gtp_2.6.20_to_2.6.32.patch   Wed May  8 02:15:45 2013
@@ -1,15 +1,16 @@
 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
-@@ -0,0 +1,1679 @@
+@@ -0,0 +1,1778 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTO
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +What is KGTP
 +Get help or report issues about KGTP
++Table of different between GDB debug normal program and KGTP
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -18,6 +19,7 @@
 +Fedora
 +Others
 +Make sure current Linux kernel debug image is right
++Where is the current Linux kernel debug image
 +Use /proc/kallsyms
 +Use linux_banner
+Handle the issue that cannot find any file in "/sys/" or "/sys/kernel/debug/"
@@ -56,7 +58,7 @@
 +while-stepping n
 +Start and stop the tracepoint
 +Enable and disable the tracepoint
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
 +How to handle error "No such file or directory."
 +Save the trace frame info to a file
 +Show and save the tracepoint
@@ -75,7 +77,7 @@
 +Example 1
 +Example 2
+Special trace state variables $current_task, $current_task_pid, $current_thread_info, $cpu_id, $dump_stack, $printk_level, $printk_format, $printk_tmp ,$clock, $hardirq_count, $softirq_count and $irq_count
-+Special trace state variable $no_self_trace
++Special trace state variable $self_trace
 +Trace the function return with $kret
 +Use $ignore_error and $last_errno to ignore the error of tstart
 +Use $cooked_clock and $cooked_rdtsc the time without KGTP used
@@ -90,6 +92,9 @@
 +Trace state variables of watch tracepoint
 +Static watch tracepoint
 +Dynamic watch tracepoint
++Use while-stepping let Linux kernel do single step
++Howto use while-stepping
++Read the traceframe of while-stepping
 +Howto show a variable whose value has been optimized away
 +Update your GCC
 +How to get the function pointer point to
@@ -133,6 +138,24 @@
+You can post it to http://code.google.com/p/kgtp/issues/list, write Email to kgtp@xxxxxxxxxxxxx or write Email to teawater@xxxxxxxxx .
 +The KGTP team will try our best to help you.
 +
++Table of different between GDB debug normal program and KGTP
++This table is for the people that have experience using GDB debug normal program. It will help you understand and remember the function of KGTP.
++
++Function      GDB debug normal program        GDB control KGTP debug Linux 
kernel
++Preparatory work       Have a GDB installed in your system.
++Program built with "-g". KGTP need GDB 7.3 or newer version because it use some new functions of GDB. If your system doesn't supply it,you can get new version GDB built with "-static" that can running is most of Linux system in http://code.google.com/p/gdbt/ and you can get an introduce about howto built new GDB step by step in there. ++You alse need do some preparatory work with Linux kernel and KGTP. Please goto HOWTO#Preparatory_work_before_use_KGTP get howto do it. ++Attach Use command "gdb -p pid" or GDB command "attach pid" can attach a program that running in the system. Need insmod gtp.ko first, see #Exec_it.
++Then let GDB connect to KGTP, see #Make_GDB_connect_to_gtp.
++Please note that after GDB connect to KGTP, Linux kernel will not stop.
++Breakpoints GDB command "b place_will_stop", let program execute after this command. Then programe will stop in the place that setup a breakpoint. KGTP doesn't support breakpoints but it support tracepoints. Tracepoints can be considered as a special kind of breakpoints. It can be setup in some place of Linux kernel and define some commands that you want to do in its actions. When tracepoints start, they will execute these commands when Linux kernel execute to these place. When tracepoint stop, you can use some GDB commands parse the data that get by tracepoints like what you do when program stop by breakpoints. Difference is breakpoints will stop the program But the tracepoints of KGTP not. Please goto #GDB_tracepoint get howto use it. ++Memory read After GDB stop the program(maybe doesn't need), it can read memory of program with GDB command "print", "x" and so on. You can set special actions to collect memory to traceframe in tracepoints, and get the its value when tracepoint stop.#collect_expr1,_expr2,_... #Use_tfind_select_the_entry_inside_the_trace_frame_info ++Or you can read memory directly when Linux kernel or program is running.#Direct_access_the_current_value_in_normal_mode ++Step and continue GDB can continue program execution with command "continue" and stop it with CTRL-C. KGTP never stop the Linux kernel. But tracepoint can be start and stop.#Start_and_stop_the_tracepoint ++Or use while-stepping tracepoint record Linux kernel with some times single step and Let KGTP switch to replay mode. Then it support execution commands (continue, step) and reverse-execute commands (reverse-continue, reverse-step). #Use_while-stepping_let_Linux_kernel_do_single_step ++Backtrace GDB can print backtrace of all stack frames with command "backtrace". KGTP can do it too.#Howto_backtrace_(stack_dump) ++Watchpoint GDB can let programe stop when some memory access happen with watchpoint. KGTP can record the memory access with watch tracepoint. #Howto_use_watch_tracepoint_control_hardware_breakpoints_to_recor ++Call function GDB can call function of program with command "call function(xx,xx)". KGTP can call function of Linux kernel with plugin.#How_to_add_plugin_in_C
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -200,6 +223,11 @@
 +
+Please note that if you determine you use the right Linux kernel debug image, but cannot pass these ways. Please see HOWTO#Handle_the_issue_that_Linux_kernel_debug_image's_address_in.
 +
++Where is the current Linux kernel debug image
++In UBUNTU, you can find it in "/usr/lib/debug/boot/vmlinux-$(uname -r)".
++In Fedora, you can find it in "/usr/lib/debug/lib/modules/$(uname -r)/vmlinux". ++If you build Linux kernel with yourself, you can find vmlinux file in the Linux kernel build directory.
++
 +Use /proc/kallsyms
+In the system that its Linux kernel is what you want to trace, use following command to get the address of sys_read and sys_write:
 +
@@ -354,6 +382,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +Make GDB connect to gtp
++Please note that let GDB open a right vmlinux file is very important. Please goto #Make_sure_current_Linux_kernel_debug_image_is_right get how to do it.
++
 +GDB on the current machine
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -407,7 +437,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +Direct access the current value in normal mode
+After GDB connect to KGTP, if it doesn't select any a entry of trace frame bufffer with GDB command "tfind", GDB in the normal mode. Then you can direct access the current value of memory (Linux kernel or the user space program) and the trace state variables without stop anything. -+If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto [HOWTO#Use"tfind"select_the_entry_inside_the_trace_frame_in] get more info about GDB command "tfind". ++If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto #Use_tfind_select_the_entry_inside_the_trace_frame_info get more info about GDB command "tfind".
 +
 +The memory of Linux kernel
 +For example, you can access to "jiffies_64" with following command:
@@ -521,7 +551,7 @@
+Evaluate the given expressions when the tracepoint is hit. This command accepts a comma-separated list of expressions. The results are discarded, so this is mainly useful for assigning values to trace state variables (see HOWTO#Simple_trace_state_variables) without adding those values to the trace buffer, as would be the case if the collect action were used.
 +
 +while-stepping n
-+Please goto HOWTO#If_the_debug_info_of_the_function_pointer_is_optimized_out see howto use it. ++Please goto #Use_while-stepping_let_Linux_kernel_do_single_step see howto use it.
 +
 +Start and stop the tracepoint
+Tracepoint will exec actions only when it is starting use this GDB command:
@@ -533,7 +563,7 @@
 +Enable and disable the tracepoint
+Like breakpoint, tracepoint can be control by GDB commands "enable" and "disable". But please note that it only useful when tracepoint stop.
 +
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
+GDB command "tfind" is used to select a entry of trace frame bufffer when tracepoint stop. +When GDB inside "tfind" mode, it will just show the values of this entry that the tracepoint action collect. So it will output some error when print some values that action doesn't collect for example the argument of function. That is not a bug, please don't worry about it.
 +Use "tfind" again will select next entry. "tfind id" will select entry id.
@@ -897,17 +927,15 @@
 +$c1             0           1904
+sys_read() execute 3255 times in cpu0 and 1904 times in cpu1. Please note that this example just to howto use $cpu_id. Actially, this example use per_cpu trace state variables is better.
 +
-+Special trace state variable $no_self_trace
-+$no_self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. -+If the action of a tracepoint include a command access to the $no_self_trace. The tracepoint will not trace anything if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). -+For example, if we want trace vfs_read or something that have process context, and we don't want trace the operation of KGTP self process. Add following command to the action:
-+
-+>collect $no_self_trace
-+Please note that the code that doesn't about process context (Irq handler, softirq) doesn't need set this variable.
++Special trace state variable $self_trace
++$self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. ++In default, when tracepoint is triggered, the actions will not execute if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). ++If you want tracepoint actions execute with any task, please include a command access to the $self_trace in the actions i.e. add following command to the actions:
 +
++>teval $self_trace=0
 +Trace the function return with $kret
+Sometime, set the tracepoint to the end of function is hard because the Kernel is compiled with optimization. At this time, you can get help from $kret. -+$kret is a special trace state variable like $no_self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. ++$kret is a special trace state variable like $self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. +Please note that this tracepoint must set in the first address of the function in format "function_name".
 +
 +Following part is an example:
@@ -1208,6 +1236,78 @@
 +  end
+Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.
 +
++Use while-stepping let Linux kernel do single step
++Please note that while-stepping is just support by X86 and X86_64 now.
++
++Howto use while-stepping
++while-stepping is a special tracepoint action that include some actions with it. ++When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
++
++trace vfs_read
++#Because single step will make system slow, so use passcount or condition to limit the execution times of tracepoint is better.
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #do 2000 times single steps.
++    while-stepping 2000
++      #Following part is actions of "while-stepping 2000".
++ #Because step maybe execute to other functions, so does not access local variables is better.
++      collect $bt
++      collect $step_count
++    end
++  end
++Please note that tracepoint will disable the interrupt of current CPU when it do single step. Access $step_count in actions will get the count of this step that begin with 1.
++
++Read the traceframe of while-stepping
++The data of different step that is recorded by while-stepping actions will be saved in different traceframe that you can use tfind (#Use_tfind_select_the_entry_inside_the_trace_frame_info) to select them. ++Or you can switch KGTP to replay mode to select all the traceframe of a while-stepping tracepoint with GDB execution and reverse-execution commands. For example:
++Use tfind select one the traceframe of a while-stepping tracepoint.
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Following commands will swith KGTP to replay mode.
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Then you can use execution commands.
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++Set breakpoints (Just valid in replay mode, will not affect Linux kernel execution).
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++Use reverse-execution commands.
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB commands tstart, tfind or quit can auto close the replay mode.
++
 +Howto show a variable whose value has been optimized away
 +Sometimes, GDB will output some value like:
 +
@@ -1679,19 +1779,19 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/howtocn.txt
-@@ -0,0 +1,1676 @@
+@@ -0,0 +1,1775 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTOCN
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +什么是KGTP
 +需要帮助或者汇报问题
++GDB调试普通程序和KGTP的区别表
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1700,6 +1800,7 @@
 +Fedora
 +其他系统
 +确定Linux内核调试镜像是正确的
++当前Linux内核调试镜像在哪
 +使用/proc/kallsyms
 +使用linux_banner
 +处理不能在"/sys/"或者"/sys/kernel/debug/"找到任何文件的问题
@@ -1738,7 +1839,7 @@
 +while-stepping n
 +启动和停止 tracepoint
 +Enable 和 disable tracepoint
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +如何处理错误 "No such file or directory." 或者 "没有那个文件或目录."
 +保存trace帧信息到一个文件中
 +显示和存储tracepoint
@@ -1757,7 +1858,7 @@
 +例子1
 +例子2
+特殊trace状态变量 $current_task,$current_task_pid,$current_thread_info,$cpu_id,$dump_stack,$printk_level,$printk_format,$printk_tmp,$clock,$hardirq_count,$softirq_count 和 $irq_count
-+特殊trace状态变量 $no_self_trace
++特殊trace状态变量 $self_trace
 +用$kret trace函数的结尾
 +用 $ignore_error 和 $last_errno 忽略tstart的错误
 +使用 $cooked_clock 和 $cooked_rdtsc 取得不包含KGTP运行时间的时间信息
@@ -1772,6 +1873,9 @@
 +watch tracepoint的trace状态变量
 +静态watch tracepoint
 +动态watch tracepoint
++使用while-stepping让Linux内核做单步
++如何使用 while-stepping
++读while-stepping的traceframe
 +如何显示被优化掉的变量值
 +升级你的GCC
 +如何取得函数指针指向的函数
@@ -1816,6 +1920,24 @@
+你可以把问题发到 http://code.google.com/p/kgtp/issues/list 或者写信到 kgtp@xxxxxxxxxxxxx 或者写信到 teawater@xxxxxxxxx 。
 +KGTP小组将尽全力帮助你。
 +
++GDB调试普通程序和KGTP的区别表
++这个表是给在使用过GDB调试程序的人准备的,他可以帮助你理解和记住KGTP的功 能。
++
++功能    GDB调试普通程序       GDB控制KGTP调试Linux内核
++准备工作   系统里安装了GDB。
++程序用 "-g"选项编译。 因为使用了一些GDB中的新功能,所以KGTP需要和GDB 7.3或者更新的版本。如果你的系统不提供这么新版本的GDB,你可以到 http://code.google.com/p/gdbt/取得新版本GDB的静态编译版本,它可以在大部分 Linux上使用。同时你可以在这里取得一步一步编译新版本GDB的介绍。 ++你还需要做一些Linux内核和KGTP的准备工作,请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#使用KGTP前的准备工作 取得如果做的 介绍。 ++Attach 使用命令"gdb -p pid"或者GDB命令"attach pid"可以attach系统中的某个 程序. 需要先insmod gtp.ko,请看 https://code.google.com/p/kgtp/wiki/HOWTOCN#执行。 ++然后让GDB连接KGTP,请看https://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连 接到KGTP。
++请 注意 GDB连接到KGTP以后,Linux内核不会停止。
++Breakpoints GDB命令"b place_will_stop",让程序在执行这个命令后执行,则程 序将停止在设置这个断点的地方。 KGTP不支持断点但是支持tracepoint。 Tracepoints可以被看作一种特殊的断点。其可以设置在Linux kernel中的一些地方然 后定义一些命令到它的action中。当tracepoint开始的时候,他们将会在内核执行到这 些地方的时候执行这些命令。当tracepoint停止的时候,你可以像断点停止程序后你做 的那样用GDB命令分析tracepoint得到的数据。 区别 是断点会停止程序但是KGTP中的 tracepoint不会。 请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#GDB_tracepoint 看如何使用它。 ++读Memory GDB停止程序后(也许不需要),它可以用GDB命令"print"或者"x"等应用程 序的内存。 你可以在tracepoint中设置特殊的action收集内存到traceframe中,在 tracepoint停止后取得他们的值。 https://code.google.com/p/kgtp/wiki/HOWTOCN#collect_expr1,_expr2,_... http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 ++或者你可以在内核或者应用程序执行的时候直接读他们的内存。 https://code.google.com/p/kgtp/wiki/HOWTOCN#在普通模式直接访问当前值 ++Step 和 continue GDB可以用命令"continue"继续程序的执行,用CTRL-C停止其。 KGTP不会停止Linux内核,但是tracepoint可以开始和停止。 https://code.google.com/p/kgtp/wiki/HOWTOCN#启动和停止_tracepoint ++或者用 while-stepping tracepoint记录一定次数的single-stepping然后让KGTP切 换到回放模式。这样其就支持执行和方向执行命令了。 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让Linux内核做 单步 ++Backtrace GDB可以用命令"backtrace"打印全部调用栈。 KGTP也可以。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何_backtrace_(stack_dump) ++Watchpoint GDB可以用watchpoint让程序在某些内存访问发生的时候停止。 KGTP可以用watch tracepoint记录内存访问。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何用watch_tracepoint控制硬件断 点记录内存访问 ++调用函数 GDB可以用命令"call function(xx,xx)"调用程序中的函数。 KGTP可以 用插件调用内核中的函数。https://code.google.com/p/kgtp/wiki/HOWTOCN#如何增加 用C写的插件
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1883,6 +2005,11 @@
 +
+请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。 请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信 息和Linux内核执行时 。
 +
++当前Linux内核调试镜像在哪
++在UBUNTU中,你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到它。
++在Fedora中,你可以在"/usr/lib/debug/lib/modules/$(uname -r)/vmlinux"找到 它。
++如果你自己编译的内核,你可以在内核编译目录找到vmlinux文件。
++
 +使用/proc/kallsyms
 +在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
 +
@@ -2034,6 +2161,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +让GDB连接到KGTP
++请 注意 让GDB打开正确的vmlinux文件非常重要。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的看下如何做。
++
 +GDB在本地主机上
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -2087,7 +2216,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +在普通模式直接访问当前值
+在GDB连到KGTP上以后,如果没有用GDB命令"tfind"选择一条trace帧缓存里面的条 目,GDB就处于 普通模式。于是你可以直接访问内存(Linux内核或者用户程序)的值和 trace状态变量的值。 -+如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用"tfind"选择trace帧缓存里面的条 目取得GDB命令"tfind"的更多信息。 ++如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 取得GDB命令"tfind"的更多信息。
 +
 +Linux内核的内存
 +例如你可以用下面的命令访问"jiffies_64":
@@ -2200,7 +2329,7 @@
+当tracepoint触发的时候,执行指定的表达式。这个命令可接受用逗号分割的一组列 表。表达式的结果将被删除,所以最主要的作用是把值设置到trace状态变量中 (see http://code.google.com/p/kgtp/wiki/HOWTOCN#普通trace状态变量),而不用想 collect一样把这些值存到trace帧中。
 +
 +while-stepping n
-+请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#如果函数指针被优化掉了看如何使用它。 ++请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让 Linux内核做单步 去看如何使用它。
 +
 +启动和停止 tracepoint
 +tracepoint只有在用下面的GDB命令启动后才可以执行action:
@@ -2212,7 +2341,7 @@
 +Enable 和 disable tracepoint
+和breakpoint一样,tracepoint可以使用GDB命令 "enable" 和 "disable"。但是请 注意 它们只在tracepoint停止的时候有效。
 +
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +tracepoint停止的时候,GDB命令"tfind"可以用来选择trace帧缓存里面的条目。
+当GDB在"tfind"模式的时候,其只能显示tracepoint action collect的存在于这个 条目中的数据。所以GDB将输出一些错误信息如果想打印没有collect的数据例如函数的 参数。这不是bug,不用担心。 +如果想选择下一个条目,可以再次使用命令"tfind"。还可以用"tfind 条目ID"去选 择某个条目。
@@ -2575,17 +2704,15 @@
 +$c1             0           1904
+sys_read() 在CPU0上被执行了3255次,CPU1上执行了1904次。请 注意 这个例子只 是为了显示如何使用$cpu_id,实际上用per_cpu trace状态变量写更好。
 +
-+特殊trace状态变量 $no_self_trace
-+$no_self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的 行为的。 -+如果一个tracepoint包含一个访问到$no_self_trace的action,则当当前task是 KGTP自己的进程(GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其 将不进行记录。 -+例如,如果你要记录vfs_read或者其他有进程上下文的东西时候而且你不想trace KGTP自己的进程的时候,增加下面的命令到action里:
++特殊trace状态变量 $self_trace
++$self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的行为 的。 ++默认情况下,tracepoint被触发后,如果current_task是KGTP自己的进程 (GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其将不执行任何 actions。 ++如果你想让tracepoint actions和任何task的时候都执行,请包含一个包含一个访问 到$self_trace的命令到actions中,也就是说增加下面的命令到actions中:
 +
-+>collect $no_self_trace
-+请 注意 不和进程上下文(Irq handler, softirq)有关的部分不需要设置这个变 量。
-+
++>teval $self_trace=0
 +用$kret trace函数的结尾
+有时,因为内核是用优化编译的,所以在函数结尾设置tracepoint有时很困难。这时 你可以用$kret帮助你。 -+$kret是一个类似$no_self_trace的特殊trace状态变量。当你在tracepoint action里设置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是 其就可以trace一个函数的结尾。 ++$kret是一个类似$self_trace的特殊trace状态变量。当你在tracepoint action里设 置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是其就可以 trace一个函数的结尾。 +请 注意 这个tracepoint 必须用 "function_name" 的格式设置在函数的第一个地址 上。
 +
 +下面的部分是一个例子:
@@ -2886,6 +3013,78 @@
 +  end
+在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。
 +
++使用while-stepping让Linux内核做单步
++请 注意 while-stepping现在只有X86和X86_64支持。
++
++如何使用 while-stepping
++while-stepping 是一种可以包含actions的特殊tracepoint action。
++当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:
++
++trace vfs_read
++#因为单步会影响系统速度,所以最好用passcount或者condition限制tracepoint的 执行次数。
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #做2000次单步。
++    while-stepping 2000
++      #下面这部分是"while-stepping 2000"的actions。
++      #因为单步可能会执行到其他函数,所以最好不要访问局部变量。
++      collect $bt
++      collect $step_count
++    end
++  end
++请 注意 tracepoint在执行单步的时候会关闭当前CPU的中断。 在actions中访问 $step_count 将得到从1开始的这步的计数。
++
++读while-stepping的traceframe
++不同step的数据将会被记录到不同的traceframe中,你可以用tfind (https://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条 目) 选择他们。 ++或者你可以将KGTP切换到回放模式,这样GDB可以用执行和反向执行命令选择一个 while-stepping tracepoint的traceframe。例如:
++用tfind选择一个while-stepping的traceframe。
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++下面的命令将切换KGTP到回放模式。
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++于是可以使用执行命令。
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++设置断点 (只在回放模式下有效,不会影响到Linux内核执行)。
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++使用反向执行命令。
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB命令tstart,tstop,tfind或者quit可以自动关闭回放模式。
++
 +如何显示被优化掉的变量值
 +有时GDB会这样输出信息:
 +
@@ -3358,7 +3557,6 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/quickstart.txt
 @@ -0,0 +1,250 @@
@@ -3662,7 +3860,7 @@

 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,12887 @@
+@@ -0,0 +1,12890 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -3685,7 +3883,7 @@
 + */
 +
 +/* If "* 10" means that this is not a release version.  */
-+#define GTP_VERSION                   (20130218 * 10)
++#define GTP_VERSION                   (20130508)
 +
 +#include <linux/version.h>
 +#ifndef RHEL_RELEASE_VERSION
@@ -12064,6 +12262,9 @@
 +#ifdef CONFIG_X86
 +              if (tpe->step > 1)
 +                      gtp_have_step = 1;
++#else
++              if (tpe->step > 1)
++                      tpe->step = 1;
 +#endif
 +
 +              /* Get pass.  */
=======================================
--- /trunk/gtp_2.6.33_to_2.6.38.patch   Mon May  6 19:06:35 2013
+++ /trunk/gtp_2.6.33_to_2.6.38.patch   Wed May  8 02:15:45 2013
@@ -1,15 +1,16 @@
 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
-@@ -0,0 +1,1679 @@
+@@ -0,0 +1,1778 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTO
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +What is KGTP
 +Get help or report issues about KGTP
++Table of different between GDB debug normal program and KGTP
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -18,6 +19,7 @@
 +Fedora
 +Others
 +Make sure current Linux kernel debug image is right
++Where is the current Linux kernel debug image
 +Use /proc/kallsyms
 +Use linux_banner
+Handle the issue that cannot find any file in "/sys/" or "/sys/kernel/debug/"
@@ -56,7 +58,7 @@
 +while-stepping n
 +Start and stop the tracepoint
 +Enable and disable the tracepoint
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
 +How to handle error "No such file or directory."
 +Save the trace frame info to a file
 +Show and save the tracepoint
@@ -75,7 +77,7 @@
 +Example 1
 +Example 2
+Special trace state variables $current_task, $current_task_pid, $current_thread_info, $cpu_id, $dump_stack, $printk_level, $printk_format, $printk_tmp ,$clock, $hardirq_count, $softirq_count and $irq_count
-+Special trace state variable $no_self_trace
++Special trace state variable $self_trace
 +Trace the function return with $kret
 +Use $ignore_error and $last_errno to ignore the error of tstart
 +Use $cooked_clock and $cooked_rdtsc the time without KGTP used
@@ -90,6 +92,9 @@
 +Trace state variables of watch tracepoint
 +Static watch tracepoint
 +Dynamic watch tracepoint
++Use while-stepping let Linux kernel do single step
++Howto use while-stepping
++Read the traceframe of while-stepping
 +Howto show a variable whose value has been optimized away
 +Update your GCC
 +How to get the function pointer point to
@@ -133,6 +138,24 @@
+You can post it to http://code.google.com/p/kgtp/issues/list, write Email to kgtp@xxxxxxxxxxxxx or write Email to teawater@xxxxxxxxx .
 +The KGTP team will try our best to help you.
 +
++Table of different between GDB debug normal program and KGTP
++This table is for the people that have experience using GDB debug normal program. It will help you understand and remember the function of KGTP.
++
++Function      GDB debug normal program        GDB control KGTP debug Linux 
kernel
++Preparatory work       Have a GDB installed in your system.
++Program built with "-g". KGTP need GDB 7.3 or newer version because it use some new functions of GDB. If your system doesn't supply it,you can get new version GDB built with "-static" that can running is most of Linux system in http://code.google.com/p/gdbt/ and you can get an introduce about howto built new GDB step by step in there. ++You alse need do some preparatory work with Linux kernel and KGTP. Please goto HOWTO#Preparatory_work_before_use_KGTP get howto do it. ++Attach Use command "gdb -p pid" or GDB command "attach pid" can attach a program that running in the system. Need insmod gtp.ko first, see #Exec_it.
++Then let GDB connect to KGTP, see #Make_GDB_connect_to_gtp.
++Please note that after GDB connect to KGTP, Linux kernel will not stop.
++Breakpoints GDB command "b place_will_stop", let program execute after this command. Then programe will stop in the place that setup a breakpoint. KGTP doesn't support breakpoints but it support tracepoints. Tracepoints can be considered as a special kind of breakpoints. It can be setup in some place of Linux kernel and define some commands that you want to do in its actions. When tracepoints start, they will execute these commands when Linux kernel execute to these place. When tracepoint stop, you can use some GDB commands parse the data that get by tracepoints like what you do when program stop by breakpoints. Difference is breakpoints will stop the program But the tracepoints of KGTP not. Please goto #GDB_tracepoint get howto use it. ++Memory read After GDB stop the program(maybe doesn't need), it can read memory of program with GDB command "print", "x" and so on. You can set special actions to collect memory to traceframe in tracepoints, and get the its value when tracepoint stop.#collect_expr1,_expr2,_... #Use_tfind_select_the_entry_inside_the_trace_frame_info ++Or you can read memory directly when Linux kernel or program is running.#Direct_access_the_current_value_in_normal_mode ++Step and continue GDB can continue program execution with command "continue" and stop it with CTRL-C. KGTP never stop the Linux kernel. But tracepoint can be start and stop.#Start_and_stop_the_tracepoint ++Or use while-stepping tracepoint record Linux kernel with some times single step and Let KGTP switch to replay mode. Then it support execution commands (continue, step) and reverse-execute commands (reverse-continue, reverse-step). #Use_while-stepping_let_Linux_kernel_do_single_step ++Backtrace GDB can print backtrace of all stack frames with command "backtrace". KGTP can do it too.#Howto_backtrace_(stack_dump) ++Watchpoint GDB can let programe stop when some memory access happen with watchpoint. KGTP can record the memory access with watch tracepoint. #Howto_use_watch_tracepoint_control_hardware_breakpoints_to_recor ++Call function GDB can call function of program with command "call function(xx,xx)". KGTP can call function of Linux kernel with plugin.#How_to_add_plugin_in_C
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -200,6 +223,11 @@
 +
+Please note that if you determine you use the right Linux kernel debug image, but cannot pass these ways. Please see HOWTO#Handle_the_issue_that_Linux_kernel_debug_image's_address_in.
 +
++Where is the current Linux kernel debug image
++In UBUNTU, you can find it in "/usr/lib/debug/boot/vmlinux-$(uname -r)".
++In Fedora, you can find it in "/usr/lib/debug/lib/modules/$(uname -r)/vmlinux". ++If you build Linux kernel with yourself, you can find vmlinux file in the Linux kernel build directory.
++
 +Use /proc/kallsyms
+In the system that its Linux kernel is what you want to trace, use following command to get the address of sys_read and sys_write:
 +
@@ -354,6 +382,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +Make GDB connect to gtp
++Please note that let GDB open a right vmlinux file is very important. Please goto #Make_sure_current_Linux_kernel_debug_image_is_right get how to do it.
++
 +GDB on the current machine
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -407,7 +437,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +Direct access the current value in normal mode
+After GDB connect to KGTP, if it doesn't select any a entry of trace frame bufffer with GDB command "tfind", GDB in the normal mode. Then you can direct access the current value of memory (Linux kernel or the user space program) and the trace state variables without stop anything. -+If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto [HOWTO#Use"tfind"select_the_entry_inside_the_trace_frame_in] get more info about GDB command "tfind". ++If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto #Use_tfind_select_the_entry_inside_the_trace_frame_info get more info about GDB command "tfind".
 +
 +The memory of Linux kernel
 +For example, you can access to "jiffies_64" with following command:
@@ -521,7 +551,7 @@
+Evaluate the given expressions when the tracepoint is hit. This command accepts a comma-separated list of expressions. The results are discarded, so this is mainly useful for assigning values to trace state variables (see HOWTO#Simple_trace_state_variables) without adding those values to the trace buffer, as would be the case if the collect action were used.
 +
 +while-stepping n
-+Please goto HOWTO#If_the_debug_info_of_the_function_pointer_is_optimized_out see howto use it. ++Please goto #Use_while-stepping_let_Linux_kernel_do_single_step see howto use it.
 +
 +Start and stop the tracepoint
+Tracepoint will exec actions only when it is starting use this GDB command:
@@ -533,7 +563,7 @@
 +Enable and disable the tracepoint
+Like breakpoint, tracepoint can be control by GDB commands "enable" and "disable". But please note that it only useful when tracepoint stop.
 +
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
+GDB command "tfind" is used to select a entry of trace frame bufffer when tracepoint stop. +When GDB inside "tfind" mode, it will just show the values of this entry that the tracepoint action collect. So it will output some error when print some values that action doesn't collect for example the argument of function. That is not a bug, please don't worry about it.
 +Use "tfind" again will select next entry. "tfind id" will select entry id.
@@ -897,17 +927,15 @@
 +$c1             0           1904
+sys_read() execute 3255 times in cpu0 and 1904 times in cpu1. Please note that this example just to howto use $cpu_id. Actially, this example use per_cpu trace state variables is better.
 +
-+Special trace state variable $no_self_trace
-+$no_self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. -+If the action of a tracepoint include a command access to the $no_self_trace. The tracepoint will not trace anything if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). -+For example, if we want trace vfs_read or something that have process context, and we don't want trace the operation of KGTP self process. Add following command to the action:
-+
-+>collect $no_self_trace
-+Please note that the code that doesn't about process context (Irq handler, softirq) doesn't need set this variable.
++Special trace state variable $self_trace
++$self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. ++In default, when tracepoint is triggered, the actions will not execute if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). ++If you want tracepoint actions execute with any task, please include a command access to the $self_trace in the actions i.e. add following command to the actions:
 +
++>teval $self_trace=0
 +Trace the function return with $kret
+Sometime, set the tracepoint to the end of function is hard because the Kernel is compiled with optimization. At this time, you can get help from $kret. -+$kret is a special trace state variable like $no_self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. ++$kret is a special trace state variable like $self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. +Please note that this tracepoint must set in the first address of the function in format "function_name".
 +
 +Following part is an example:
@@ -1208,6 +1236,78 @@
 +  end
+Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.
 +
++Use while-stepping let Linux kernel do single step
++Please note that while-stepping is just support by X86 and X86_64 now.
++
++Howto use while-stepping
++while-stepping is a special tracepoint action that include some actions with it. ++When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
++
++trace vfs_read
++#Because single step will make system slow, so use passcount or condition to limit the execution times of tracepoint is better.
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #do 2000 times single steps.
++    while-stepping 2000
++      #Following part is actions of "while-stepping 2000".
++ #Because step maybe execute to other functions, so does not access local variables is better.
++      collect $bt
++      collect $step_count
++    end
++  end
++Please note that tracepoint will disable the interrupt of current CPU when it do single step. Access $step_count in actions will get the count of this step that begin with 1.
++
++Read the traceframe of while-stepping
++The data of different step that is recorded by while-stepping actions will be saved in different traceframe that you can use tfind (#Use_tfind_select_the_entry_inside_the_trace_frame_info) to select them. ++Or you can switch KGTP to replay mode to select all the traceframe of a while-stepping tracepoint with GDB execution and reverse-execution commands. For example:
++Use tfind select one the traceframe of a while-stepping tracepoint.
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Following commands will swith KGTP to replay mode.
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Then you can use execution commands.
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++Set breakpoints (Just valid in replay mode, will not affect Linux kernel execution).
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++Use reverse-execution commands.
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB commands tstart, tfind or quit can auto close the replay mode.
++
 +Howto show a variable whose value has been optimized away
 +Sometimes, GDB will output some value like:
 +
@@ -1679,19 +1779,19 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/howtocn.txt
-@@ -0,0 +1,1676 @@
+@@ -0,0 +1,1775 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTOCN
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +什么是KGTP
 +需要帮助或者汇报问题
++GDB调试普通程序和KGTP的区别表
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1700,6 +1800,7 @@
 +Fedora
 +其他系统
 +确定Linux内核调试镜像是正确的
++当前Linux内核调试镜像在哪
 +使用/proc/kallsyms
 +使用linux_banner
 +处理不能在"/sys/"或者"/sys/kernel/debug/"找到任何文件的问题
@@ -1738,7 +1839,7 @@
 +while-stepping n
 +启动和停止 tracepoint
 +Enable 和 disable tracepoint
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +如何处理错误 "No such file or directory." 或者 "没有那个文件或目录."
 +保存trace帧信息到一个文件中
 +显示和存储tracepoint
@@ -1757,7 +1858,7 @@
 +例子1
 +例子2
+特殊trace状态变量 $current_task,$current_task_pid,$current_thread_info,$cpu_id,$dump_stack,$printk_level,$printk_format,$printk_tmp,$clock,$hardirq_count,$softirq_count 和 $irq_count
-+特殊trace状态变量 $no_self_trace
++特殊trace状态变量 $self_trace
 +用$kret trace函数的结尾
 +用 $ignore_error 和 $last_errno 忽略tstart的错误
 +使用 $cooked_clock 和 $cooked_rdtsc 取得不包含KGTP运行时间的时间信息
@@ -1772,6 +1873,9 @@
 +watch tracepoint的trace状态变量
 +静态watch tracepoint
 +动态watch tracepoint
++使用while-stepping让Linux内核做单步
++如何使用 while-stepping
++读while-stepping的traceframe
 +如何显示被优化掉的变量值
 +升级你的GCC
 +如何取得函数指针指向的函数
@@ -1816,6 +1920,24 @@
+你可以把问题发到 http://code.google.com/p/kgtp/issues/list 或者写信到 kgtp@xxxxxxxxxxxxx 或者写信到 teawater@xxxxxxxxx 。
 +KGTP小组将尽全力帮助你。
 +
++GDB调试普通程序和KGTP的区别表
++这个表是给在使用过GDB调试程序的人准备的,他可以帮助你理解和记住KGTP的功 能。
++
++功能    GDB调试普通程序       GDB控制KGTP调试Linux内核
++准备工作   系统里安装了GDB。
++程序用 "-g"选项编译。 因为使用了一些GDB中的新功能,所以KGTP需要和GDB 7.3或者更新的版本。如果你的系统不提供这么新版本的GDB,你可以到 http://code.google.com/p/gdbt/取得新版本GDB的静态编译版本,它可以在大部分 Linux上使用。同时你可以在这里取得一步一步编译新版本GDB的介绍。 ++你还需要做一些Linux内核和KGTP的准备工作,请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#使用KGTP前的准备工作 取得如果做的 介绍。 ++Attach 使用命令"gdb -p pid"或者GDB命令"attach pid"可以attach系统中的某个 程序. 需要先insmod gtp.ko,请看 https://code.google.com/p/kgtp/wiki/HOWTOCN#执行。 ++然后让GDB连接KGTP,请看https://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连 接到KGTP。
++请 注意 GDB连接到KGTP以后,Linux内核不会停止。
++Breakpoints GDB命令"b place_will_stop",让程序在执行这个命令后执行,则程 序将停止在设置这个断点的地方。 KGTP不支持断点但是支持tracepoint。 Tracepoints可以被看作一种特殊的断点。其可以设置在Linux kernel中的一些地方然 后定义一些命令到它的action中。当tracepoint开始的时候,他们将会在内核执行到这 些地方的时候执行这些命令。当tracepoint停止的时候,你可以像断点停止程序后你做 的那样用GDB命令分析tracepoint得到的数据。 区别 是断点会停止程序但是KGTP中的 tracepoint不会。 请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#GDB_tracepoint 看如何使用它。 ++读Memory GDB停止程序后(也许不需要),它可以用GDB命令"print"或者"x"等应用程 序的内存。 你可以在tracepoint中设置特殊的action收集内存到traceframe中,在 tracepoint停止后取得他们的值。 https://code.google.com/p/kgtp/wiki/HOWTOCN#collect_expr1,_expr2,_... http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 ++或者你可以在内核或者应用程序执行的时候直接读他们的内存。 https://code.google.com/p/kgtp/wiki/HOWTOCN#在普通模式直接访问当前值 ++Step 和 continue GDB可以用命令"continue"继续程序的执行,用CTRL-C停止其。 KGTP不会停止Linux内核,但是tracepoint可以开始和停止。 https://code.google.com/p/kgtp/wiki/HOWTOCN#启动和停止_tracepoint ++或者用 while-stepping tracepoint记录一定次数的single-stepping然后让KGTP切 换到回放模式。这样其就支持执行和方向执行命令了。 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让Linux内核做 单步 ++Backtrace GDB可以用命令"backtrace"打印全部调用栈。 KGTP也可以。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何_backtrace_(stack_dump) ++Watchpoint GDB可以用watchpoint让程序在某些内存访问发生的时候停止。 KGTP可以用watch tracepoint记录内存访问。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何用watch_tracepoint控制硬件断 点记录内存访问 ++调用函数 GDB可以用命令"call function(xx,xx)"调用程序中的函数。 KGTP可以 用插件调用内核中的函数。https://code.google.com/p/kgtp/wiki/HOWTOCN#如何增加 用C写的插件
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1883,6 +2005,11 @@
 +
+请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。 请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信 息和Linux内核执行时 。
 +
++当前Linux内核调试镜像在哪
++在UBUNTU中,你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到它。
++在Fedora中,你可以在"/usr/lib/debug/lib/modules/$(uname -r)/vmlinux"找到 它。
++如果你自己编译的内核,你可以在内核编译目录找到vmlinux文件。
++
 +使用/proc/kallsyms
 +在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
 +
@@ -2034,6 +2161,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +让GDB连接到KGTP
++请 注意 让GDB打开正确的vmlinux文件非常重要。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的看下如何做。
++
 +GDB在本地主机上
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -2087,7 +2216,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +在普通模式直接访问当前值
+在GDB连到KGTP上以后,如果没有用GDB命令"tfind"选择一条trace帧缓存里面的条 目,GDB就处于 普通模式。于是你可以直接访问内存(Linux内核或者用户程序)的值和 trace状态变量的值。 -+如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用"tfind"选择trace帧缓存里面的条 目取得GDB命令"tfind"的更多信息。 ++如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 取得GDB命令"tfind"的更多信息。
 +
 +Linux内核的内存
 +例如你可以用下面的命令访问"jiffies_64":
@@ -2200,7 +2329,7 @@
+当tracepoint触发的时候,执行指定的表达式。这个命令可接受用逗号分割的一组列 表。表达式的结果将被删除,所以最主要的作用是把值设置到trace状态变量中 (see http://code.google.com/p/kgtp/wiki/HOWTOCN#普通trace状态变量),而不用想 collect一样把这些值存到trace帧中。
 +
 +while-stepping n
-+请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#如果函数指针被优化掉了看如何使用它。 ++请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让 Linux内核做单步 去看如何使用它。
 +
 +启动和停止 tracepoint
 +tracepoint只有在用下面的GDB命令启动后才可以执行action:
@@ -2212,7 +2341,7 @@
 +Enable 和 disable tracepoint
+和breakpoint一样,tracepoint可以使用GDB命令 "enable" 和 "disable"。但是请 注意 它们只在tracepoint停止的时候有效。
 +
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +tracepoint停止的时候,GDB命令"tfind"可以用来选择trace帧缓存里面的条目。
+当GDB在"tfind"模式的时候,其只能显示tracepoint action collect的存在于这个 条目中的数据。所以GDB将输出一些错误信息如果想打印没有collect的数据例如函数的 参数。这不是bug,不用担心。 +如果想选择下一个条目,可以再次使用命令"tfind"。还可以用"tfind 条目ID"去选 择某个条目。
@@ -2575,17 +2704,15 @@
 +$c1             0           1904
+sys_read() 在CPU0上被执行了3255次,CPU1上执行了1904次。请 注意 这个例子只 是为了显示如何使用$cpu_id,实际上用per_cpu trace状态变量写更好。
 +
-+特殊trace状态变量 $no_self_trace
-+$no_self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的 行为的。 -+如果一个tracepoint包含一个访问到$no_self_trace的action,则当当前task是 KGTP自己的进程(GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其 将不进行记录。 -+例如,如果你要记录vfs_read或者其他有进程上下文的东西时候而且你不想trace KGTP自己的进程的时候,增加下面的命令到action里:
++特殊trace状态变量 $self_trace
++$self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的行为 的。 ++默认情况下,tracepoint被触发后,如果current_task是KGTP自己的进程 (GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其将不执行任何 actions。 ++如果你想让tracepoint actions和任何task的时候都执行,请包含一个包含一个访问 到$self_trace的命令到actions中,也就是说增加下面的命令到actions中:
 +
-+>collect $no_self_trace
-+请 注意 不和进程上下文(Irq handler, softirq)有关的部分不需要设置这个变 量。
-+
++>teval $self_trace=0
 +用$kret trace函数的结尾
+有时,因为内核是用优化编译的,所以在函数结尾设置tracepoint有时很困难。这时 你可以用$kret帮助你。 -+$kret是一个类似$no_self_trace的特殊trace状态变量。当你在tracepoint action里设置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是 其就可以trace一个函数的结尾。 ++$kret是一个类似$self_trace的特殊trace状态变量。当你在tracepoint action里设 置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是其就可以 trace一个函数的结尾。 +请 注意 这个tracepoint 必须用 "function_name" 的格式设置在函数的第一个地址 上。
 +
 +下面的部分是一个例子:
@@ -2886,6 +3013,78 @@
 +  end
+在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。
 +
++使用while-stepping让Linux内核做单步
++请 注意 while-stepping现在只有X86和X86_64支持。
++
++如何使用 while-stepping
++while-stepping 是一种可以包含actions的特殊tracepoint action。
++当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:
++
++trace vfs_read
++#因为单步会影响系统速度,所以最好用passcount或者condition限制tracepoint的 执行次数。
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #做2000次单步。
++    while-stepping 2000
++      #下面这部分是"while-stepping 2000"的actions。
++      #因为单步可能会执行到其他函数,所以最好不要访问局部变量。
++      collect $bt
++      collect $step_count
++    end
++  end
++请 注意 tracepoint在执行单步的时候会关闭当前CPU的中断。 在actions中访问 $step_count 将得到从1开始的这步的计数。
++
++读while-stepping的traceframe
++不同step的数据将会被记录到不同的traceframe中,你可以用tfind (https://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条 目) 选择他们。 ++或者你可以将KGTP切换到回放模式,这样GDB可以用执行和反向执行命令选择一个 while-stepping tracepoint的traceframe。例如:
++用tfind选择一个while-stepping的traceframe。
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++下面的命令将切换KGTP到回放模式。
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++于是可以使用执行命令。
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++设置断点 (只在回放模式下有效,不会影响到Linux内核执行)。
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++使用反向执行命令。
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB命令tstart,tstop,tfind或者quit可以自动关闭回放模式。
++
 +如何显示被优化掉的变量值
 +有时GDB会这样输出信息:
 +
@@ -3358,7 +3557,6 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/quickstart.txt
 @@ -0,0 +1,250 @@
@@ -3726,7 +3924,7 @@

 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,12887 @@
+@@ -0,0 +1,12890 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -3749,7 +3947,7 @@
 + */
 +
 +/* If "* 10" means that this is not a release version.  */
-+#define GTP_VERSION                   (20130218 * 10)
++#define GTP_VERSION                   (20130508)
 +
 +#include <linux/version.h>
 +#ifndef RHEL_RELEASE_VERSION
@@ -12128,6 +12326,9 @@
 +#ifdef CONFIG_X86
 +              if (tpe->step > 1)
 +                      gtp_have_step = 1;
++#else
++              if (tpe->step > 1)
++                      tpe->step = 1;
 +#endif
 +
 +              /* Get pass.  */
=======================================
--- /trunk/gtp_2.6.39.patch     Mon May  6 19:06:35 2013
+++ /trunk/gtp_2.6.39.patch     Wed May  8 02:15:45 2013
@@ -1,15 +1,16 @@
 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
-@@ -0,0 +1,1679 @@
+@@ -0,0 +1,1778 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTO
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +What is KGTP
 +Get help or report issues about KGTP
++Table of different between GDB debug normal program and KGTP
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -18,6 +19,7 @@
 +Fedora
 +Others
 +Make sure current Linux kernel debug image is right
++Where is the current Linux kernel debug image
 +Use /proc/kallsyms
 +Use linux_banner
+Handle the issue that cannot find any file in "/sys/" or "/sys/kernel/debug/"
@@ -56,7 +58,7 @@
 +while-stepping n
 +Start and stop the tracepoint
 +Enable and disable the tracepoint
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
 +How to handle error "No such file or directory."
 +Save the trace frame info to a file
 +Show and save the tracepoint
@@ -75,7 +77,7 @@
 +Example 1
 +Example 2
+Special trace state variables $current_task, $current_task_pid, $current_thread_info, $cpu_id, $dump_stack, $printk_level, $printk_format, $printk_tmp ,$clock, $hardirq_count, $softirq_count and $irq_count
-+Special trace state variable $no_self_trace
++Special trace state variable $self_trace
 +Trace the function return with $kret
 +Use $ignore_error and $last_errno to ignore the error of tstart
 +Use $cooked_clock and $cooked_rdtsc the time without KGTP used
@@ -90,6 +92,9 @@
 +Trace state variables of watch tracepoint
 +Static watch tracepoint
 +Dynamic watch tracepoint
++Use while-stepping let Linux kernel do single step
++Howto use while-stepping
++Read the traceframe of while-stepping
 +Howto show a variable whose value has been optimized away
 +Update your GCC
 +How to get the function pointer point to
@@ -133,6 +138,24 @@
+You can post it to http://code.google.com/p/kgtp/issues/list, write Email to kgtp@xxxxxxxxxxxxx or write Email to teawater@xxxxxxxxx .
 +The KGTP team will try our best to help you.
 +
++Table of different between GDB debug normal program and KGTP
++This table is for the people that have experience using GDB debug normal program. It will help you understand and remember the function of KGTP.
++
++Function      GDB debug normal program        GDB control KGTP debug Linux 
kernel
++Preparatory work       Have a GDB installed in your system.
++Program built with "-g". KGTP need GDB 7.3 or newer version because it use some new functions of GDB. If your system doesn't supply it,you can get new version GDB built with "-static" that can running is most of Linux system in http://code.google.com/p/gdbt/ and you can get an introduce about howto built new GDB step by step in there. ++You alse need do some preparatory work with Linux kernel and KGTP. Please goto HOWTO#Preparatory_work_before_use_KGTP get howto do it. ++Attach Use command "gdb -p pid" or GDB command "attach pid" can attach a program that running in the system. Need insmod gtp.ko first, see #Exec_it.
++Then let GDB connect to KGTP, see #Make_GDB_connect_to_gtp.
++Please note that after GDB connect to KGTP, Linux kernel will not stop.
++Breakpoints GDB command "b place_will_stop", let program execute after this command. Then programe will stop in the place that setup a breakpoint. KGTP doesn't support breakpoints but it support tracepoints. Tracepoints can be considered as a special kind of breakpoints. It can be setup in some place of Linux kernel and define some commands that you want to do in its actions. When tracepoints start, they will execute these commands when Linux kernel execute to these place. When tracepoint stop, you can use some GDB commands parse the data that get by tracepoints like what you do when program stop by breakpoints. Difference is breakpoints will stop the program But the tracepoints of KGTP not. Please goto #GDB_tracepoint get howto use it. ++Memory read After GDB stop the program(maybe doesn't need), it can read memory of program with GDB command "print", "x" and so on. You can set special actions to collect memory to traceframe in tracepoints, and get the its value when tracepoint stop.#collect_expr1,_expr2,_... #Use_tfind_select_the_entry_inside_the_trace_frame_info ++Or you can read memory directly when Linux kernel or program is running.#Direct_access_the_current_value_in_normal_mode ++Step and continue GDB can continue program execution with command "continue" and stop it with CTRL-C. KGTP never stop the Linux kernel. But tracepoint can be start and stop.#Start_and_stop_the_tracepoint ++Or use while-stepping tracepoint record Linux kernel with some times single step and Let KGTP switch to replay mode. Then it support execution commands (continue, step) and reverse-execute commands (reverse-continue, reverse-step). #Use_while-stepping_let_Linux_kernel_do_single_step ++Backtrace GDB can print backtrace of all stack frames with command "backtrace". KGTP can do it too.#Howto_backtrace_(stack_dump) ++Watchpoint GDB can let programe stop when some memory access happen with watchpoint. KGTP can record the memory access with watch tracepoint. #Howto_use_watch_tracepoint_control_hardware_breakpoints_to_recor ++Call function GDB can call function of program with command "call function(xx,xx)". KGTP can call function of Linux kernel with plugin.#How_to_add_plugin_in_C
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -200,6 +223,11 @@
 +
+Please note that if you determine you use the right Linux kernel debug image, but cannot pass these ways. Please see HOWTO#Handle_the_issue_that_Linux_kernel_debug_image's_address_in.
 +
++Where is the current Linux kernel debug image
++In UBUNTU, you can find it in "/usr/lib/debug/boot/vmlinux-$(uname -r)".
++In Fedora, you can find it in "/usr/lib/debug/lib/modules/$(uname -r)/vmlinux". ++If you build Linux kernel with yourself, you can find vmlinux file in the Linux kernel build directory.
++
 +Use /proc/kallsyms
+In the system that its Linux kernel is what you want to trace, use following command to get the address of sys_read and sys_write:
 +
@@ -354,6 +382,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +Make GDB connect to gtp
++Please note that let GDB open a right vmlinux file is very important. Please goto #Make_sure_current_Linux_kernel_debug_image_is_right get how to do it.
++
 +GDB on the current machine
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -407,7 +437,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +Direct access the current value in normal mode
+After GDB connect to KGTP, if it doesn't select any a entry of trace frame bufffer with GDB command "tfind", GDB in the normal mode. Then you can direct access the current value of memory (Linux kernel or the user space program) and the trace state variables without stop anything. -+If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto [HOWTO#Use"tfind"select_the_entry_inside_the_trace_frame_in] get more info about GDB command "tfind". ++If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto #Use_tfind_select_the_entry_inside_the_trace_frame_info get more info about GDB command "tfind".
 +
 +The memory of Linux kernel
 +For example, you can access to "jiffies_64" with following command:
@@ -521,7 +551,7 @@
+Evaluate the given expressions when the tracepoint is hit. This command accepts a comma-separated list of expressions. The results are discarded, so this is mainly useful for assigning values to trace state variables (see HOWTO#Simple_trace_state_variables) without adding those values to the trace buffer, as would be the case if the collect action were used.
 +
 +while-stepping n
-+Please goto HOWTO#If_the_debug_info_of_the_function_pointer_is_optimized_out see howto use it. ++Please goto #Use_while-stepping_let_Linux_kernel_do_single_step see howto use it.
 +
 +Start and stop the tracepoint
+Tracepoint will exec actions only when it is starting use this GDB command:
@@ -533,7 +563,7 @@
 +Enable and disable the tracepoint
+Like breakpoint, tracepoint can be control by GDB commands "enable" and "disable". But please note that it only useful when tracepoint stop.
 +
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
+GDB command "tfind" is used to select a entry of trace frame bufffer when tracepoint stop. +When GDB inside "tfind" mode, it will just show the values of this entry that the tracepoint action collect. So it will output some error when print some values that action doesn't collect for example the argument of function. That is not a bug, please don't worry about it.
 +Use "tfind" again will select next entry. "tfind id" will select entry id.
@@ -897,17 +927,15 @@
 +$c1             0           1904
+sys_read() execute 3255 times in cpu0 and 1904 times in cpu1. Please note that this example just to howto use $cpu_id. Actially, this example use per_cpu trace state variables is better.
 +
-+Special trace state variable $no_self_trace
-+$no_self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. -+If the action of a tracepoint include a command access to the $no_self_trace. The tracepoint will not trace anything if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). -+For example, if we want trace vfs_read or something that have process context, and we don't want trace the operation of KGTP self process. Add following command to the action:
-+
-+>collect $no_self_trace
-+Please note that the code that doesn't about process context (Irq handler, softirq) doesn't need set this variable.
++Special trace state variable $self_trace
++$self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. ++In default, when tracepoint is triggered, the actions will not execute if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). ++If you want tracepoint actions execute with any task, please include a command access to the $self_trace in the actions i.e. add following command to the actions:
 +
++>teval $self_trace=0
 +Trace the function return with $kret
+Sometime, set the tracepoint to the end of function is hard because the Kernel is compiled with optimization. At this time, you can get help from $kret. -+$kret is a special trace state variable like $no_self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. ++$kret is a special trace state variable like $self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. +Please note that this tracepoint must set in the first address of the function in format "function_name".
 +
 +Following part is an example:
@@ -1208,6 +1236,78 @@
 +  end
+Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.
 +
++Use while-stepping let Linux kernel do single step
++Please note that while-stepping is just support by X86 and X86_64 now.
++
++Howto use while-stepping
++while-stepping is a special tracepoint action that include some actions with it. ++When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
++
++trace vfs_read
++#Because single step will make system slow, so use passcount or condition to limit the execution times of tracepoint is better.
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #do 2000 times single steps.
++    while-stepping 2000
++      #Following part is actions of "while-stepping 2000".
++ #Because step maybe execute to other functions, so does not access local variables is better.
++      collect $bt
++      collect $step_count
++    end
++  end
++Please note that tracepoint will disable the interrupt of current CPU when it do single step. Access $step_count in actions will get the count of this step that begin with 1.
++
++Read the traceframe of while-stepping
++The data of different step that is recorded by while-stepping actions will be saved in different traceframe that you can use tfind (#Use_tfind_select_the_entry_inside_the_trace_frame_info) to select them. ++Or you can switch KGTP to replay mode to select all the traceframe of a while-stepping tracepoint with GDB execution and reverse-execution commands. For example:
++Use tfind select one the traceframe of a while-stepping tracepoint.
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Following commands will swith KGTP to replay mode.
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Then you can use execution commands.
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++Set breakpoints (Just valid in replay mode, will not affect Linux kernel execution).
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++Use reverse-execution commands.
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB commands tstart, tfind or quit can auto close the replay mode.
++
 +Howto show a variable whose value has been optimized away
 +Sometimes, GDB will output some value like:
 +
@@ -1679,19 +1779,19 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/howtocn.txt
-@@ -0,0 +1,1676 @@
+@@ -0,0 +1,1775 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTOCN
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +什么是KGTP
 +需要帮助或者汇报问题
++GDB调试普通程序和KGTP的区别表
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1700,6 +1800,7 @@
 +Fedora
 +其他系统
 +确定Linux内核调试镜像是正确的
++当前Linux内核调试镜像在哪
 +使用/proc/kallsyms
 +使用linux_banner
 +处理不能在"/sys/"或者"/sys/kernel/debug/"找到任何文件的问题
@@ -1738,7 +1839,7 @@
 +while-stepping n
 +启动和停止 tracepoint
 +Enable 和 disable tracepoint
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +如何处理错误 "No such file or directory." 或者 "没有那个文件或目录."
 +保存trace帧信息到一个文件中
 +显示和存储tracepoint
@@ -1757,7 +1858,7 @@
 +例子1
 +例子2
+特殊trace状态变量 $current_task,$current_task_pid,$current_thread_info,$cpu_id,$dump_stack,$printk_level,$printk_format,$printk_tmp,$clock,$hardirq_count,$softirq_count 和 $irq_count
-+特殊trace状态变量 $no_self_trace
++特殊trace状态变量 $self_trace
 +用$kret trace函数的结尾
 +用 $ignore_error 和 $last_errno 忽略tstart的错误
 +使用 $cooked_clock 和 $cooked_rdtsc 取得不包含KGTP运行时间的时间信息
@@ -1772,6 +1873,9 @@
 +watch tracepoint的trace状态变量
 +静态watch tracepoint
 +动态watch tracepoint
++使用while-stepping让Linux内核做单步
++如何使用 while-stepping
++读while-stepping的traceframe
 +如何显示被优化掉的变量值
 +升级你的GCC
 +如何取得函数指针指向的函数
@@ -1816,6 +1920,24 @@
+你可以把问题发到 http://code.google.com/p/kgtp/issues/list 或者写信到 kgtp@xxxxxxxxxxxxx 或者写信到 teawater@xxxxxxxxx 。
 +KGTP小组将尽全力帮助你。
 +
++GDB调试普通程序和KGTP的区别表
++这个表是给在使用过GDB调试程序的人准备的,他可以帮助你理解和记住KGTP的功 能。
++
++功能    GDB调试普通程序       GDB控制KGTP调试Linux内核
++准备工作   系统里安装了GDB。
++程序用 "-g"选项编译。 因为使用了一些GDB中的新功能,所以KGTP需要和GDB 7.3或者更新的版本。如果你的系统不提供这么新版本的GDB,你可以到 http://code.google.com/p/gdbt/取得新版本GDB的静态编译版本,它可以在大部分 Linux上使用。同时你可以在这里取得一步一步编译新版本GDB的介绍。 ++你还需要做一些Linux内核和KGTP的准备工作,请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#使用KGTP前的准备工作 取得如果做的 介绍。 ++Attach 使用命令"gdb -p pid"或者GDB命令"attach pid"可以attach系统中的某个 程序. 需要先insmod gtp.ko,请看 https://code.google.com/p/kgtp/wiki/HOWTOCN#执行。 ++然后让GDB连接KGTP,请看https://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连 接到KGTP。
++请 注意 GDB连接到KGTP以后,Linux内核不会停止。
++Breakpoints GDB命令"b place_will_stop",让程序在执行这个命令后执行,则程 序将停止在设置这个断点的地方。 KGTP不支持断点但是支持tracepoint。 Tracepoints可以被看作一种特殊的断点。其可以设置在Linux kernel中的一些地方然 后定义一些命令到它的action中。当tracepoint开始的时候,他们将会在内核执行到这 些地方的时候执行这些命令。当tracepoint停止的时候,你可以像断点停止程序后你做 的那样用GDB命令分析tracepoint得到的数据。 区别 是断点会停止程序但是KGTP中的 tracepoint不会。 请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#GDB_tracepoint 看如何使用它。 ++读Memory GDB停止程序后(也许不需要),它可以用GDB命令"print"或者"x"等应用程 序的内存。 你可以在tracepoint中设置特殊的action收集内存到traceframe中,在 tracepoint停止后取得他们的值。 https://code.google.com/p/kgtp/wiki/HOWTOCN#collect_expr1,_expr2,_... http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 ++或者你可以在内核或者应用程序执行的时候直接读他们的内存。 https://code.google.com/p/kgtp/wiki/HOWTOCN#在普通模式直接访问当前值 ++Step 和 continue GDB可以用命令"continue"继续程序的执行,用CTRL-C停止其。 KGTP不会停止Linux内核,但是tracepoint可以开始和停止。 https://code.google.com/p/kgtp/wiki/HOWTOCN#启动和停止_tracepoint ++或者用 while-stepping tracepoint记录一定次数的single-stepping然后让KGTP切 换到回放模式。这样其就支持执行和方向执行命令了。 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让Linux内核做 单步 ++Backtrace GDB可以用命令"backtrace"打印全部调用栈。 KGTP也可以。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何_backtrace_(stack_dump) ++Watchpoint GDB可以用watchpoint让程序在某些内存访问发生的时候停止。 KGTP可以用watch tracepoint记录内存访问。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何用watch_tracepoint控制硬件断 点记录内存访问 ++调用函数 GDB可以用命令"call function(xx,xx)"调用程序中的函数。 KGTP可以 用插件调用内核中的函数。https://code.google.com/p/kgtp/wiki/HOWTOCN#如何增加 用C写的插件
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1883,6 +2005,11 @@
 +
+请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。 请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信 息和Linux内核执行时 。
 +
++当前Linux内核调试镜像在哪
++在UBUNTU中,你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到它。
++在Fedora中,你可以在"/usr/lib/debug/lib/modules/$(uname -r)/vmlinux"找到 它。
++如果你自己编译的内核,你可以在内核编译目录找到vmlinux文件。
++
 +使用/proc/kallsyms
 +在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
 +
@@ -2034,6 +2161,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +让GDB连接到KGTP
++请 注意 让GDB打开正确的vmlinux文件非常重要。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的看下如何做。
++
 +GDB在本地主机上
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -2087,7 +2216,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +在普通模式直接访问当前值
+在GDB连到KGTP上以后,如果没有用GDB命令"tfind"选择一条trace帧缓存里面的条 目,GDB就处于 普通模式。于是你可以直接访问内存(Linux内核或者用户程序)的值和 trace状态变量的值。 -+如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用"tfind"选择trace帧缓存里面的条 目取得GDB命令"tfind"的更多信息。 ++如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 取得GDB命令"tfind"的更多信息。
 +
 +Linux内核的内存
 +例如你可以用下面的命令访问"jiffies_64":
@@ -2200,7 +2329,7 @@
+当tracepoint触发的时候,执行指定的表达式。这个命令可接受用逗号分割的一组列 表。表达式的结果将被删除,所以最主要的作用是把值设置到trace状态变量中 (see http://code.google.com/p/kgtp/wiki/HOWTOCN#普通trace状态变量),而不用想 collect一样把这些值存到trace帧中。
 +
 +while-stepping n
-+请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#如果函数指针被优化掉了看如何使用它。 ++请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让 Linux内核做单步 去看如何使用它。
 +
 +启动和停止 tracepoint
 +tracepoint只有在用下面的GDB命令启动后才可以执行action:
@@ -2212,7 +2341,7 @@
 +Enable 和 disable tracepoint
+和breakpoint一样,tracepoint可以使用GDB命令 "enable" 和 "disable"。但是请 注意 它们只在tracepoint停止的时候有效。
 +
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +tracepoint停止的时候,GDB命令"tfind"可以用来选择trace帧缓存里面的条目。
+当GDB在"tfind"模式的时候,其只能显示tracepoint action collect的存在于这个 条目中的数据。所以GDB将输出一些错误信息如果想打印没有collect的数据例如函数的 参数。这不是bug,不用担心。 +如果想选择下一个条目,可以再次使用命令"tfind"。还可以用"tfind 条目ID"去选 择某个条目。
@@ -2575,17 +2704,15 @@
 +$c1             0           1904
+sys_read() 在CPU0上被执行了3255次,CPU1上执行了1904次。请 注意 这个例子只 是为了显示如何使用$cpu_id,实际上用per_cpu trace状态变量写更好。
 +
-+特殊trace状态变量 $no_self_trace
-+$no_self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的 行为的。 -+如果一个tracepoint包含一个访问到$no_self_trace的action,则当当前task是 KGTP自己的进程(GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其 将不进行记录。 -+例如,如果你要记录vfs_read或者其他有进程上下文的东西时候而且你不想trace KGTP自己的进程的时候,增加下面的命令到action里:
++特殊trace状态变量 $self_trace
++$self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的行为 的。 ++默认情况下,tracepoint被触发后,如果current_task是KGTP自己的进程 (GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其将不执行任何 actions。 ++如果你想让tracepoint actions和任何task的时候都执行,请包含一个包含一个访问 到$self_trace的命令到actions中,也就是说增加下面的命令到actions中:
 +
-+>collect $no_self_trace
-+请 注意 不和进程上下文(Irq handler, softirq)有关的部分不需要设置这个变 量。
-+
++>teval $self_trace=0
 +用$kret trace函数的结尾
+有时,因为内核是用优化编译的,所以在函数结尾设置tracepoint有时很困难。这时 你可以用$kret帮助你。 -+$kret是一个类似$no_self_trace的特殊trace状态变量。当你在tracepoint action里设置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是 其就可以trace一个函数的结尾。 ++$kret是一个类似$self_trace的特殊trace状态变量。当你在tracepoint action里设 置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是其就可以 trace一个函数的结尾。 +请 注意 这个tracepoint 必须用 "function_name" 的格式设置在函数的第一个地址 上。
 +
 +下面的部分是一个例子:
@@ -2886,6 +3013,78 @@
 +  end
+在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。
 +
++使用while-stepping让Linux内核做单步
++请 注意 while-stepping现在只有X86和X86_64支持。
++
++如何使用 while-stepping
++while-stepping 是一种可以包含actions的特殊tracepoint action。
++当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:
++
++trace vfs_read
++#因为单步会影响系统速度,所以最好用passcount或者condition限制tracepoint的 执行次数。
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #做2000次单步。
++    while-stepping 2000
++      #下面这部分是"while-stepping 2000"的actions。
++      #因为单步可能会执行到其他函数,所以最好不要访问局部变量。
++      collect $bt
++      collect $step_count
++    end
++  end
++请 注意 tracepoint在执行单步的时候会关闭当前CPU的中断。 在actions中访问 $step_count 将得到从1开始的这步的计数。
++
++读while-stepping的traceframe
++不同step的数据将会被记录到不同的traceframe中,你可以用tfind (https://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条 目) 选择他们。 ++或者你可以将KGTP切换到回放模式,这样GDB可以用执行和反向执行命令选择一个 while-stepping tracepoint的traceframe。例如:
++用tfind选择一个while-stepping的traceframe。
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++下面的命令将切换KGTP到回放模式。
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++于是可以使用执行命令。
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++设置断点 (只在回放模式下有效,不会影响到Linux内核执行)。
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++使用反向执行命令。
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB命令tstart,tstop,tfind或者quit可以自动关闭回放模式。
++
 +如何显示被优化掉的变量值
 +有时GDB会这样输出信息:
 +
@@ -3358,7 +3557,6 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/quickstart.txt
 @@ -0,0 +1,250 @@
@@ -3716,7 +3914,7 @@

 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,12887 @@
+@@ -0,0 +1,12890 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -3739,7 +3937,7 @@
 + */
 +
 +/* If "* 10" means that this is not a release version.  */
-+#define GTP_VERSION                   (20130218 * 10)
++#define GTP_VERSION                   (20130508)
 +
 +#include <linux/version.h>
 +#ifndef RHEL_RELEASE_VERSION
@@ -12118,6 +12316,9 @@
 +#ifdef CONFIG_X86
 +              if (tpe->step > 1)
 +                      gtp_have_step = 1;
++#else
++              if (tpe->step > 1)
++                      tpe->step = 1;
 +#endif
 +
 +              /* Get pass.  */
=======================================
--- /trunk/gtp_3.0_to_3.6.patch Mon May  6 19:06:35 2013
+++ /trunk/gtp_3.0_to_3.6.patch Wed May  8 02:15:45 2013
@@ -1,15 +1,16 @@
 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
-@@ -0,0 +1,1679 @@
+@@ -0,0 +1,1778 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTO
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +What is KGTP
 +Get help or report issues about KGTP
++Table of different between GDB debug normal program and KGTP
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -18,6 +19,7 @@
 +Fedora
 +Others
 +Make sure current Linux kernel debug image is right
++Where is the current Linux kernel debug image
 +Use /proc/kallsyms
 +Use linux_banner
+Handle the issue that cannot find any file in "/sys/" or "/sys/kernel/debug/"
@@ -56,7 +58,7 @@
 +while-stepping n
 +Start and stop the tracepoint
 +Enable and disable the tracepoint
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
 +How to handle error "No such file or directory."
 +Save the trace frame info to a file
 +Show and save the tracepoint
@@ -75,7 +77,7 @@
 +Example 1
 +Example 2
+Special trace state variables $current_task, $current_task_pid, $current_thread_info, $cpu_id, $dump_stack, $printk_level, $printk_format, $printk_tmp ,$clock, $hardirq_count, $softirq_count and $irq_count
-+Special trace state variable $no_self_trace
++Special trace state variable $self_trace
 +Trace the function return with $kret
 +Use $ignore_error and $last_errno to ignore the error of tstart
 +Use $cooked_clock and $cooked_rdtsc the time without KGTP used
@@ -90,6 +92,9 @@
 +Trace state variables of watch tracepoint
 +Static watch tracepoint
 +Dynamic watch tracepoint
++Use while-stepping let Linux kernel do single step
++Howto use while-stepping
++Read the traceframe of while-stepping
 +Howto show a variable whose value has been optimized away
 +Update your GCC
 +How to get the function pointer point to
@@ -133,6 +138,24 @@
+You can post it to http://code.google.com/p/kgtp/issues/list, write Email to kgtp@xxxxxxxxxxxxx or write Email to teawater@xxxxxxxxx .
 +The KGTP team will try our best to help you.
 +
++Table of different between GDB debug normal program and KGTP
++This table is for the people that have experience using GDB debug normal program. It will help you understand and remember the function of KGTP.
++
++Function      GDB debug normal program        GDB control KGTP debug Linux 
kernel
++Preparatory work       Have a GDB installed in your system.
++Program built with "-g". KGTP need GDB 7.3 or newer version because it use some new functions of GDB. If your system doesn't supply it,you can get new version GDB built with "-static" that can running is most of Linux system in http://code.google.com/p/gdbt/ and you can get an introduce about howto built new GDB step by step in there. ++You alse need do some preparatory work with Linux kernel and KGTP. Please goto HOWTO#Preparatory_work_before_use_KGTP get howto do it. ++Attach Use command "gdb -p pid" or GDB command "attach pid" can attach a program that running in the system. Need insmod gtp.ko first, see #Exec_it.
++Then let GDB connect to KGTP, see #Make_GDB_connect_to_gtp.
++Please note that after GDB connect to KGTP, Linux kernel will not stop.
++Breakpoints GDB command "b place_will_stop", let program execute after this command. Then programe will stop in the place that setup a breakpoint. KGTP doesn't support breakpoints but it support tracepoints. Tracepoints can be considered as a special kind of breakpoints. It can be setup in some place of Linux kernel and define some commands that you want to do in its actions. When tracepoints start, they will execute these commands when Linux kernel execute to these place. When tracepoint stop, you can use some GDB commands parse the data that get by tracepoints like what you do when program stop by breakpoints. Difference is breakpoints will stop the program But the tracepoints of KGTP not. Please goto #GDB_tracepoint get howto use it. ++Memory read After GDB stop the program(maybe doesn't need), it can read memory of program with GDB command "print", "x" and so on. You can set special actions to collect memory to traceframe in tracepoints, and get the its value when tracepoint stop.#collect_expr1,_expr2,_... #Use_tfind_select_the_entry_inside_the_trace_frame_info ++Or you can read memory directly when Linux kernel or program is running.#Direct_access_the_current_value_in_normal_mode ++Step and continue GDB can continue program execution with command "continue" and stop it with CTRL-C. KGTP never stop the Linux kernel. But tracepoint can be start and stop.#Start_and_stop_the_tracepoint ++Or use while-stepping tracepoint record Linux kernel with some times single step and Let KGTP switch to replay mode. Then it support execution commands (continue, step) and reverse-execute commands (reverse-continue, reverse-step). #Use_while-stepping_let_Linux_kernel_do_single_step ++Backtrace GDB can print backtrace of all stack frames with command "backtrace". KGTP can do it too.#Howto_backtrace_(stack_dump) ++Watchpoint GDB can let programe stop when some memory access happen with watchpoint. KGTP can record the memory access with watch tracepoint. #Howto_use_watch_tracepoint_control_hardware_breakpoints_to_recor ++Call function GDB can call function of program with command "call function(xx,xx)". KGTP can call function of Linux kernel with plugin.#How_to_add_plugin_in_C
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -200,6 +223,11 @@
 +
+Please note that if you determine you use the right Linux kernel debug image, but cannot pass these ways. Please see HOWTO#Handle_the_issue_that_Linux_kernel_debug_image's_address_in.
 +
++Where is the current Linux kernel debug image
++In UBUNTU, you can find it in "/usr/lib/debug/boot/vmlinux-$(uname -r)".
++In Fedora, you can find it in "/usr/lib/debug/lib/modules/$(uname -r)/vmlinux". ++If you build Linux kernel with yourself, you can find vmlinux file in the Linux kernel build directory.
++
 +Use /proc/kallsyms
+In the system that its Linux kernel is what you want to trace, use following command to get the address of sys_read and sys_write:
 +
@@ -354,6 +382,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +Make GDB connect to gtp
++Please note that let GDB open a right vmlinux file is very important. Please goto #Make_sure_current_Linux_kernel_debug_image_is_right get how to do it.
++
 +GDB on the current machine
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -407,7 +437,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +Direct access the current value in normal mode
+After GDB connect to KGTP, if it doesn't select any a entry of trace frame bufffer with GDB command "tfind", GDB in the normal mode. Then you can direct access the current value of memory (Linux kernel or the user space program) and the trace state variables without stop anything. -+If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto [HOWTO#Use"tfind"select_the_entry_inside_the_trace_frame_in] get more info about GDB command "tfind". ++If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto #Use_tfind_select_the_entry_inside_the_trace_frame_info get more info about GDB command "tfind".
 +
 +The memory of Linux kernel
 +For example, you can access to "jiffies_64" with following command:
@@ -521,7 +551,7 @@
+Evaluate the given expressions when the tracepoint is hit. This command accepts a comma-separated list of expressions. The results are discarded, so this is mainly useful for assigning values to trace state variables (see HOWTO#Simple_trace_state_variables) without adding those values to the trace buffer, as would be the case if the collect action were used.
 +
 +while-stepping n
-+Please goto HOWTO#If_the_debug_info_of_the_function_pointer_is_optimized_out see howto use it. ++Please goto #Use_while-stepping_let_Linux_kernel_do_single_step see howto use it.
 +
 +Start and stop the tracepoint
+Tracepoint will exec actions only when it is starting use this GDB command:
@@ -533,7 +563,7 @@
 +Enable and disable the tracepoint
+Like breakpoint, tracepoint can be control by GDB commands "enable" and "disable". But please note that it only useful when tracepoint stop.
 +
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
+GDB command "tfind" is used to select a entry of trace frame bufffer when tracepoint stop. +When GDB inside "tfind" mode, it will just show the values of this entry that the tracepoint action collect. So it will output some error when print some values that action doesn't collect for example the argument of function. That is not a bug, please don't worry about it.
 +Use "tfind" again will select next entry. "tfind id" will select entry id.
@@ -897,17 +927,15 @@
 +$c1             0           1904
+sys_read() execute 3255 times in cpu0 and 1904 times in cpu1. Please note that this example just to howto use $cpu_id. Actially, this example use per_cpu trace state variables is better.
 +
-+Special trace state variable $no_self_trace
-+$no_self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. -+If the action of a tracepoint include a command access to the $no_self_trace. The tracepoint will not trace anything if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). -+For example, if we want trace vfs_read or something that have process context, and we don't want trace the operation of KGTP self process. Add following command to the action:
-+
-+>collect $no_self_trace
-+Please note that the code that doesn't about process context (Irq handler, softirq) doesn't need set this variable.
++Special trace state variable $self_trace
++$self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. ++In default, when tracepoint is triggered, the actions will not execute if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). ++If you want tracepoint actions execute with any task, please include a command access to the $self_trace in the actions i.e. add following command to the actions:
 +
++>teval $self_trace=0
 +Trace the function return with $kret
+Sometime, set the tracepoint to the end of function is hard because the Kernel is compiled with optimization. At this time, you can get help from $kret. -+$kret is a special trace state variable like $no_self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. ++$kret is a special trace state variable like $self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. +Please note that this tracepoint must set in the first address of the function in format "function_name".
 +
 +Following part is an example:
@@ -1208,6 +1236,78 @@
 +  end
+Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.
 +
++Use while-stepping let Linux kernel do single step
++Please note that while-stepping is just support by X86 and X86_64 now.
++
++Howto use while-stepping
++while-stepping is a special tracepoint action that include some actions with it. ++When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
++
++trace vfs_read
++#Because single step will make system slow, so use passcount or condition to limit the execution times of tracepoint is better.
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #do 2000 times single steps.
++    while-stepping 2000
++      #Following part is actions of "while-stepping 2000".
++ #Because step maybe execute to other functions, so does not access local variables is better.
++      collect $bt
++      collect $step_count
++    end
++  end
++Please note that tracepoint will disable the interrupt of current CPU when it do single step. Access $step_count in actions will get the count of this step that begin with 1.
++
++Read the traceframe of while-stepping
++The data of different step that is recorded by while-stepping actions will be saved in different traceframe that you can use tfind (#Use_tfind_select_the_entry_inside_the_trace_frame_info) to select them. ++Or you can switch KGTP to replay mode to select all the traceframe of a while-stepping tracepoint with GDB execution and reverse-execution commands. For example:
++Use tfind select one the traceframe of a while-stepping tracepoint.
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Following commands will swith KGTP to replay mode.
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Then you can use execution commands.
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++Set breakpoints (Just valid in replay mode, will not affect Linux kernel execution).
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++Use reverse-execution commands.
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB commands tstart, tfind or quit can auto close the replay mode.
++
 +Howto show a variable whose value has been optimized away
 +Sometimes, GDB will output some value like:
 +
@@ -1679,19 +1779,19 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/howtocn.txt
-@@ -0,0 +1,1676 @@
+@@ -0,0 +1,1775 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTOCN
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +什么是KGTP
 +需要帮助或者汇报问题
++GDB调试普通程序和KGTP的区别表
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1700,6 +1800,7 @@
 +Fedora
 +其他系统
 +确定Linux内核调试镜像是正确的
++当前Linux内核调试镜像在哪
 +使用/proc/kallsyms
 +使用linux_banner
 +处理不能在"/sys/"或者"/sys/kernel/debug/"找到任何文件的问题
@@ -1738,7 +1839,7 @@
 +while-stepping n
 +启动和停止 tracepoint
 +Enable 和 disable tracepoint
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +如何处理错误 "No such file or directory." 或者 "没有那个文件或目录."
 +保存trace帧信息到一个文件中
 +显示和存储tracepoint
@@ -1757,7 +1858,7 @@
 +例子1
 +例子2
+特殊trace状态变量 $current_task,$current_task_pid,$current_thread_info,$cpu_id,$dump_stack,$printk_level,$printk_format,$printk_tmp,$clock,$hardirq_count,$softirq_count 和 $irq_count
-+特殊trace状态变量 $no_self_trace
++特殊trace状态变量 $self_trace
 +用$kret trace函数的结尾
 +用 $ignore_error 和 $last_errno 忽略tstart的错误
 +使用 $cooked_clock 和 $cooked_rdtsc 取得不包含KGTP运行时间的时间信息
@@ -1772,6 +1873,9 @@
 +watch tracepoint的trace状态变量
 +静态watch tracepoint
 +动态watch tracepoint
++使用while-stepping让Linux内核做单步
++如何使用 while-stepping
++读while-stepping的traceframe
 +如何显示被优化掉的变量值
 +升级你的GCC
 +如何取得函数指针指向的函数
@@ -1816,6 +1920,24 @@
+你可以把问题发到 http://code.google.com/p/kgtp/issues/list 或者写信到 kgtp@xxxxxxxxxxxxx 或者写信到 teawater@xxxxxxxxx 。
 +KGTP小组将尽全力帮助你。
 +
++GDB调试普通程序和KGTP的区别表
++这个表是给在使用过GDB调试程序的人准备的,他可以帮助你理解和记住KGTP的功 能。
++
++功能    GDB调试普通程序       GDB控制KGTP调试Linux内核
++准备工作   系统里安装了GDB。
++程序用 "-g"选项编译。 因为使用了一些GDB中的新功能,所以KGTP需要和GDB 7.3或者更新的版本。如果你的系统不提供这么新版本的GDB,你可以到 http://code.google.com/p/gdbt/取得新版本GDB的静态编译版本,它可以在大部分 Linux上使用。同时你可以在这里取得一步一步编译新版本GDB的介绍。 ++你还需要做一些Linux内核和KGTP的准备工作,请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#使用KGTP前的准备工作 取得如果做的 介绍。 ++Attach 使用命令"gdb -p pid"或者GDB命令"attach pid"可以attach系统中的某个 程序. 需要先insmod gtp.ko,请看 https://code.google.com/p/kgtp/wiki/HOWTOCN#执行。 ++然后让GDB连接KGTP,请看https://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连 接到KGTP。
++请 注意 GDB连接到KGTP以后,Linux内核不会停止。
++Breakpoints GDB命令"b place_will_stop",让程序在执行这个命令后执行,则程 序将停止在设置这个断点的地方。 KGTP不支持断点但是支持tracepoint。 Tracepoints可以被看作一种特殊的断点。其可以设置在Linux kernel中的一些地方然 后定义一些命令到它的action中。当tracepoint开始的时候,他们将会在内核执行到这 些地方的时候执行这些命令。当tracepoint停止的时候,你可以像断点停止程序后你做 的那样用GDB命令分析tracepoint得到的数据。 区别 是断点会停止程序但是KGTP中的 tracepoint不会。 请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#GDB_tracepoint 看如何使用它。 ++读Memory GDB停止程序后(也许不需要),它可以用GDB命令"print"或者"x"等应用程 序的内存。 你可以在tracepoint中设置特殊的action收集内存到traceframe中,在 tracepoint停止后取得他们的值。 https://code.google.com/p/kgtp/wiki/HOWTOCN#collect_expr1,_expr2,_... http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 ++或者你可以在内核或者应用程序执行的时候直接读他们的内存。 https://code.google.com/p/kgtp/wiki/HOWTOCN#在普通模式直接访问当前值 ++Step 和 continue GDB可以用命令"continue"继续程序的执行,用CTRL-C停止其。 KGTP不会停止Linux内核,但是tracepoint可以开始和停止。 https://code.google.com/p/kgtp/wiki/HOWTOCN#启动和停止_tracepoint ++或者用 while-stepping tracepoint记录一定次数的single-stepping然后让KGTP切 换到回放模式。这样其就支持执行和方向执行命令了。 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让Linux内核做 单步 ++Backtrace GDB可以用命令"backtrace"打印全部调用栈。 KGTP也可以。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何_backtrace_(stack_dump) ++Watchpoint GDB可以用watchpoint让程序在某些内存访问发生的时候停止。 KGTP可以用watch tracepoint记录内存访问。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何用watch_tracepoint控制硬件断 点记录内存访问 ++调用函数 GDB可以用命令"call function(xx,xx)"调用程序中的函数。 KGTP可以 用插件调用内核中的函数。https://code.google.com/p/kgtp/wiki/HOWTOCN#如何增加 用C写的插件
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1883,6 +2005,11 @@
 +
+请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。 请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信 息和Linux内核执行时 。
 +
++当前Linux内核调试镜像在哪
++在UBUNTU中,你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到它。
++在Fedora中,你可以在"/usr/lib/debug/lib/modules/$(uname -r)/vmlinux"找到 它。
++如果你自己编译的内核,你可以在内核编译目录找到vmlinux文件。
++
 +使用/proc/kallsyms
 +在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
 +
@@ -2034,6 +2161,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +让GDB连接到KGTP
++请 注意 让GDB打开正确的vmlinux文件非常重要。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的看下如何做。
++
 +GDB在本地主机上
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -2087,7 +2216,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +在普通模式直接访问当前值
+在GDB连到KGTP上以后,如果没有用GDB命令"tfind"选择一条trace帧缓存里面的条 目,GDB就处于 普通模式。于是你可以直接访问内存(Linux内核或者用户程序)的值和 trace状态变量的值。 -+如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用"tfind"选择trace帧缓存里面的条 目取得GDB命令"tfind"的更多信息。 ++如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 取得GDB命令"tfind"的更多信息。
 +
 +Linux内核的内存
 +例如你可以用下面的命令访问"jiffies_64":
@@ -2200,7 +2329,7 @@
+当tracepoint触发的时候,执行指定的表达式。这个命令可接受用逗号分割的一组列 表。表达式的结果将被删除,所以最主要的作用是把值设置到trace状态变量中 (see http://code.google.com/p/kgtp/wiki/HOWTOCN#普通trace状态变量),而不用想 collect一样把这些值存到trace帧中。
 +
 +while-stepping n
-+请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#如果函数指针被优化掉了看如何使用它。 ++请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让 Linux内核做单步 去看如何使用它。
 +
 +启动和停止 tracepoint
 +tracepoint只有在用下面的GDB命令启动后才可以执行action:
@@ -2212,7 +2341,7 @@
 +Enable 和 disable tracepoint
+和breakpoint一样,tracepoint可以使用GDB命令 "enable" 和 "disable"。但是请 注意 它们只在tracepoint停止的时候有效。
 +
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +tracepoint停止的时候,GDB命令"tfind"可以用来选择trace帧缓存里面的条目。
+当GDB在"tfind"模式的时候,其只能显示tracepoint action collect的存在于这个 条目中的数据。所以GDB将输出一些错误信息如果想打印没有collect的数据例如函数的 参数。这不是bug,不用担心。 +如果想选择下一个条目,可以再次使用命令"tfind"。还可以用"tfind 条目ID"去选 择某个条目。
@@ -2575,17 +2704,15 @@
 +$c1             0           1904
+sys_read() 在CPU0上被执行了3255次,CPU1上执行了1904次。请 注意 这个例子只 是为了显示如何使用$cpu_id,实际上用per_cpu trace状态变量写更好。
 +
-+特殊trace状态变量 $no_self_trace
-+$no_self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的 行为的。 -+如果一个tracepoint包含一个访问到$no_self_trace的action,则当当前task是 KGTP自己的进程(GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其 将不进行记录。 -+例如,如果你要记录vfs_read或者其他有进程上下文的东西时候而且你不想trace KGTP自己的进程的时候,增加下面的命令到action里:
++特殊trace状态变量 $self_trace
++$self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的行为 的。 ++默认情况下,tracepoint被触发后,如果current_task是KGTP自己的进程 (GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其将不执行任何 actions。 ++如果你想让tracepoint actions和任何task的时候都执行,请包含一个包含一个访问 到$self_trace的命令到actions中,也就是说增加下面的命令到actions中:
 +
-+>collect $no_self_trace
-+请 注意 不和进程上下文(Irq handler, softirq)有关的部分不需要设置这个变 量。
-+
++>teval $self_trace=0
 +用$kret trace函数的结尾
+有时,因为内核是用优化编译的,所以在函数结尾设置tracepoint有时很困难。这时 你可以用$kret帮助你。 -+$kret是一个类似$no_self_trace的特殊trace状态变量。当你在tracepoint action里设置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是 其就可以trace一个函数的结尾。 ++$kret是一个类似$self_trace的特殊trace状态变量。当你在tracepoint action里设 置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是其就可以 trace一个函数的结尾。 +请 注意 这个tracepoint 必须用 "function_name" 的格式设置在函数的第一个地址 上。
 +
 +下面的部分是一个例子:
@@ -2886,6 +3013,78 @@
 +  end
+在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。
 +
++使用while-stepping让Linux内核做单步
++请 注意 while-stepping现在只有X86和X86_64支持。
++
++如何使用 while-stepping
++while-stepping 是一种可以包含actions的特殊tracepoint action。
++当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:
++
++trace vfs_read
++#因为单步会影响系统速度,所以最好用passcount或者condition限制tracepoint的 执行次数。
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #做2000次单步。
++    while-stepping 2000
++      #下面这部分是"while-stepping 2000"的actions。
++      #因为单步可能会执行到其他函数,所以最好不要访问局部变量。
++      collect $bt
++      collect $step_count
++    end
++  end
++请 注意 tracepoint在执行单步的时候会关闭当前CPU的中断。 在actions中访问 $step_count 将得到从1开始的这步的计数。
++
++读while-stepping的traceframe
++不同step的数据将会被记录到不同的traceframe中,你可以用tfind (https://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条 目) 选择他们。 ++或者你可以将KGTP切换到回放模式,这样GDB可以用执行和反向执行命令选择一个 while-stepping tracepoint的traceframe。例如:
++用tfind选择一个while-stepping的traceframe。
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++下面的命令将切换KGTP到回放模式。
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++于是可以使用执行命令。
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++设置断点 (只在回放模式下有效,不会影响到Linux内核执行)。
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++使用反向执行命令。
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB命令tstart,tstop,tfind或者quit可以自动关闭回放模式。
++
 +如何显示被优化掉的变量值
 +有时GDB会这样输出信息:
 +
@@ -3358,7 +3557,6 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/quickstart.txt
 @@ -0,0 +1,250 @@
@@ -3734,7 +3932,7 @@

 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,12887 @@
+@@ -0,0 +1,12890 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -3757,7 +3955,7 @@
 + */
 +
 +/* If "* 10" means that this is not a release version.  */
-+#define GTP_VERSION                   (20130218 * 10)
++#define GTP_VERSION                   (20130508)
 +
 +#include <linux/version.h>
 +#ifndef RHEL_RELEASE_VERSION
@@ -12136,6 +12334,9 @@
 +#ifdef CONFIG_X86
 +              if (tpe->step > 1)
 +                      gtp_have_step = 1;
++#else
++              if (tpe->step > 1)
++                      tpe->step = 1;
 +#endif
 +
 +              /* Get pass.  */
=======================================
--- /trunk/gtp_3.7_to_upstream.patch    Mon May  6 19:06:35 2013
+++ /trunk/gtp_3.7_to_upstream.patch    Wed May  8 02:15:45 2013
@@ -1,15 +1,16 @@
 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
-@@ -0,0 +1,1679 @@
+@@ -0,0 +1,1778 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTO
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +What is KGTP
 +Get help or report issues about KGTP
++Table of different between GDB debug normal program and KGTP
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -18,6 +19,7 @@
 +Fedora
 +Others
 +Make sure current Linux kernel debug image is right
++Where is the current Linux kernel debug image
 +Use /proc/kallsyms
 +Use linux_banner
+Handle the issue that cannot find any file in "/sys/" or "/sys/kernel/debug/"
@@ -56,7 +58,7 @@
 +while-stepping n
 +Start and stop the tracepoint
 +Enable and disable the tracepoint
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
 +How to handle error "No such file or directory."
 +Save the trace frame info to a file
 +Show and save the tracepoint
@@ -75,7 +77,7 @@
 +Example 1
 +Example 2
+Special trace state variables $current_task, $current_task_pid, $current_thread_info, $cpu_id, $dump_stack, $printk_level, $printk_format, $printk_tmp ,$clock, $hardirq_count, $softirq_count and $irq_count
-+Special trace state variable $no_self_trace
++Special trace state variable $self_trace
 +Trace the function return with $kret
 +Use $ignore_error and $last_errno to ignore the error of tstart
 +Use $cooked_clock and $cooked_rdtsc the time without KGTP used
@@ -90,6 +92,9 @@
 +Trace state variables of watch tracepoint
 +Static watch tracepoint
 +Dynamic watch tracepoint
++Use while-stepping let Linux kernel do single step
++Howto use while-stepping
++Read the traceframe of while-stepping
 +Howto show a variable whose value has been optimized away
 +Update your GCC
 +How to get the function pointer point to
@@ -133,6 +138,24 @@
+You can post it to http://code.google.com/p/kgtp/issues/list, write Email to kgtp@xxxxxxxxxxxxx or write Email to teawater@xxxxxxxxx .
 +The KGTP team will try our best to help you.
 +
++Table of different between GDB debug normal program and KGTP
++This table is for the people that have experience using GDB debug normal program. It will help you understand and remember the function of KGTP.
++
++Function      GDB debug normal program        GDB control KGTP debug Linux 
kernel
++Preparatory work       Have a GDB installed in your system.
++Program built with "-g". KGTP need GDB 7.3 or newer version because it use some new functions of GDB. If your system doesn't supply it,you can get new version GDB built with "-static" that can running is most of Linux system in http://code.google.com/p/gdbt/ and you can get an introduce about howto built new GDB step by step in there. ++You alse need do some preparatory work with Linux kernel and KGTP. Please goto HOWTO#Preparatory_work_before_use_KGTP get howto do it. ++Attach Use command "gdb -p pid" or GDB command "attach pid" can attach a program that running in the system. Need insmod gtp.ko first, see #Exec_it.
++Then let GDB connect to KGTP, see #Make_GDB_connect_to_gtp.
++Please note that after GDB connect to KGTP, Linux kernel will not stop.
++Breakpoints GDB command "b place_will_stop", let program execute after this command. Then programe will stop in the place that setup a breakpoint. KGTP doesn't support breakpoints but it support tracepoints. Tracepoints can be considered as a special kind of breakpoints. It can be setup in some place of Linux kernel and define some commands that you want to do in its actions. When tracepoints start, they will execute these commands when Linux kernel execute to these place. When tracepoint stop, you can use some GDB commands parse the data that get by tracepoints like what you do when program stop by breakpoints. Difference is breakpoints will stop the program But the tracepoints of KGTP not. Please goto #GDB_tracepoint get howto use it. ++Memory read After GDB stop the program(maybe doesn't need), it can read memory of program with GDB command "print", "x" and so on. You can set special actions to collect memory to traceframe in tracepoints, and get the its value when tracepoint stop.#collect_expr1,_expr2,_... #Use_tfind_select_the_entry_inside_the_trace_frame_info ++Or you can read memory directly when Linux kernel or program is running.#Direct_access_the_current_value_in_normal_mode ++Step and continue GDB can continue program execution with command "continue" and stop it with CTRL-C. KGTP never stop the Linux kernel. But tracepoint can be start and stop.#Start_and_stop_the_tracepoint ++Or use while-stepping tracepoint record Linux kernel with some times single step and Let KGTP switch to replay mode. Then it support execution commands (continue, step) and reverse-execute commands (reverse-continue, reverse-step). #Use_while-stepping_let_Linux_kernel_do_single_step ++Backtrace GDB can print backtrace of all stack frames with command "backtrace". KGTP can do it too.#Howto_backtrace_(stack_dump) ++Watchpoint GDB can let programe stop when some memory access happen with watchpoint. KGTP can record the memory access with watch tracepoint. #Howto_use_watch_tracepoint_control_hardware_breakpoints_to_recor ++Call function GDB can call function of program with command "call function(xx,xx)". KGTP can call function of Linux kernel with plugin.#How_to_add_plugin_in_C
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -200,6 +223,11 @@
 +
+Please note that if you determine you use the right Linux kernel debug image, but cannot pass these ways. Please see HOWTO#Handle_the_issue_that_Linux_kernel_debug_image's_address_in.
 +
++Where is the current Linux kernel debug image
++In UBUNTU, you can find it in "/usr/lib/debug/boot/vmlinux-$(uname -r)".
++In Fedora, you can find it in "/usr/lib/debug/lib/modules/$(uname -r)/vmlinux". ++If you build Linux kernel with yourself, you can find vmlinux file in the Linux kernel build directory.
++
 +Use /proc/kallsyms
+In the system that its Linux kernel is what you want to trace, use following command to get the address of sys_read and sys_write:
 +
@@ -354,6 +382,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +Make GDB connect to gtp
++Please note that let GDB open a right vmlinux file is very important. Please goto #Make_sure_current_Linux_kernel_debug_image_is_right get how to do it.
++
 +GDB on the current machine
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -407,7 +437,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +Direct access the current value in normal mode
+After GDB connect to KGTP, if it doesn't select any a entry of trace frame bufffer with GDB command "tfind", GDB in the normal mode. Then you can direct access the current value of memory (Linux kernel or the user space program) and the trace state variables without stop anything. -+If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto [HOWTO#Use"tfind"select_the_entry_inside_the_trace_frame_in] get more info about GDB command "tfind". ++If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto #Use_tfind_select_the_entry_inside_the_trace_frame_info get more info about GDB command "tfind".
 +
 +The memory of Linux kernel
 +For example, you can access to "jiffies_64" with following command:
@@ -521,7 +551,7 @@
+Evaluate the given expressions when the tracepoint is hit. This command accepts a comma-separated list of expressions. The results are discarded, so this is mainly useful for assigning values to trace state variables (see HOWTO#Simple_trace_state_variables) without adding those values to the trace buffer, as would be the case if the collect action were used.
 +
 +while-stepping n
-+Please goto HOWTO#If_the_debug_info_of_the_function_pointer_is_optimized_out see howto use it. ++Please goto #Use_while-stepping_let_Linux_kernel_do_single_step see howto use it.
 +
 +Start and stop the tracepoint
+Tracepoint will exec actions only when it is starting use this GDB command:
@@ -533,7 +563,7 @@
 +Enable and disable the tracepoint
+Like breakpoint, tracepoint can be control by GDB commands "enable" and "disable". But please note that it only useful when tracepoint stop.
 +
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
+GDB command "tfind" is used to select a entry of trace frame bufffer when tracepoint stop. +When GDB inside "tfind" mode, it will just show the values of this entry that the tracepoint action collect. So it will output some error when print some values that action doesn't collect for example the argument of function. That is not a bug, please don't worry about it.
 +Use "tfind" again will select next entry. "tfind id" will select entry id.
@@ -897,17 +927,15 @@
 +$c1             0           1904
+sys_read() execute 3255 times in cpu0 and 1904 times in cpu1. Please note that this example just to howto use $cpu_id. Actially, this example use per_cpu trace state variables is better.
 +
-+Special trace state variable $no_self_trace
-+$no_self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. -+If the action of a tracepoint include a command access to the $no_self_trace. The tracepoint will not trace anything if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). -+For example, if we want trace vfs_read or something that have process context, and we don't want trace the operation of KGTP self process. Add following command to the action:
-+
-+>collect $no_self_trace
-+Please note that the code that doesn't about process context (Irq handler, softirq) doesn't need set this variable.
++Special trace state variable $self_trace
++$self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. ++In default, when tracepoint is triggered, the actions will not execute if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). ++If you want tracepoint actions execute with any task, please include a command access to the $self_trace in the actions i.e. add following command to the actions:
 +
++>teval $self_trace=0
 +Trace the function return with $kret
+Sometime, set the tracepoint to the end of function is hard because the Kernel is compiled with optimization. At this time, you can get help from $kret. -+$kret is a special trace state variable like $no_self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. ++$kret is a special trace state variable like $self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. +Please note that this tracepoint must set in the first address of the function in format "function_name".
 +
 +Following part is an example:
@@ -1208,6 +1236,78 @@
 +  end
+Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.
 +
++Use while-stepping let Linux kernel do single step
++Please note that while-stepping is just support by X86 and X86_64 now.
++
++Howto use while-stepping
++while-stepping is a special tracepoint action that include some actions with it. ++When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
++
++trace vfs_read
++#Because single step will make system slow, so use passcount or condition to limit the execution times of tracepoint is better.
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #do 2000 times single steps.
++    while-stepping 2000
++      #Following part is actions of "while-stepping 2000".
++ #Because step maybe execute to other functions, so does not access local variables is better.
++      collect $bt
++      collect $step_count
++    end
++  end
++Please note that tracepoint will disable the interrupt of current CPU when it do single step. Access $step_count in actions will get the count of this step that begin with 1.
++
++Read the traceframe of while-stepping
++The data of different step that is recorded by while-stepping actions will be saved in different traceframe that you can use tfind (#Use_tfind_select_the_entry_inside_the_trace_frame_info) to select them. ++Or you can switch KGTP to replay mode to select all the traceframe of a while-stepping tracepoint with GDB execution and reverse-execution commands. For example:
++Use tfind select one the traceframe of a while-stepping tracepoint.
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Following commands will swith KGTP to replay mode.
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Then you can use execution commands.
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++Set breakpoints (Just valid in replay mode, will not affect Linux kernel execution).
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++Use reverse-execution commands.
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB commands tstart, tfind or quit can auto close the replay mode.
++
 +Howto show a variable whose value has been optimized away
 +Sometimes, GDB will output some value like:
 +
@@ -1679,19 +1779,19 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/howtocn.txt
-@@ -0,0 +1,1676 @@
+@@ -0,0 +1,1775 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTOCN
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +什么是KGTP
 +需要帮助或者汇报问题
++GDB调试普通程序和KGTP的区别表
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1700,6 +1800,7 @@
 +Fedora
 +其他系统
 +确定Linux内核调试镜像是正确的
++当前Linux内核调试镜像在哪
 +使用/proc/kallsyms
 +使用linux_banner
 +处理不能在"/sys/"或者"/sys/kernel/debug/"找到任何文件的问题
@@ -1738,7 +1839,7 @@
 +while-stepping n
 +启动和停止 tracepoint
 +Enable 和 disable tracepoint
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +如何处理错误 "No such file or directory." 或者 "没有那个文件或目录."
 +保存trace帧信息到一个文件中
 +显示和存储tracepoint
@@ -1757,7 +1858,7 @@
 +例子1
 +例子2
+特殊trace状态变量 $current_task,$current_task_pid,$current_thread_info,$cpu_id,$dump_stack,$printk_level,$printk_format,$printk_tmp,$clock,$hardirq_count,$softirq_count 和 $irq_count
-+特殊trace状态变量 $no_self_trace
++特殊trace状态变量 $self_trace
 +用$kret trace函数的结尾
 +用 $ignore_error 和 $last_errno 忽略tstart的错误
 +使用 $cooked_clock 和 $cooked_rdtsc 取得不包含KGTP运行时间的时间信息
@@ -1772,6 +1873,9 @@
 +watch tracepoint的trace状态变量
 +静态watch tracepoint
 +动态watch tracepoint
++使用while-stepping让Linux内核做单步
++如何使用 while-stepping
++读while-stepping的traceframe
 +如何显示被优化掉的变量值
 +升级你的GCC
 +如何取得函数指针指向的函数
@@ -1816,6 +1920,24 @@
+你可以把问题发到 http://code.google.com/p/kgtp/issues/list 或者写信到 kgtp@xxxxxxxxxxxxx 或者写信到 teawater@xxxxxxxxx 。
 +KGTP小组将尽全力帮助你。
 +
++GDB调试普通程序和KGTP的区别表
++这个表是给在使用过GDB调试程序的人准备的,他可以帮助你理解和记住KGTP的功 能。
++
++功能    GDB调试普通程序       GDB控制KGTP调试Linux内核
++准备工作   系统里安装了GDB。
++程序用 "-g"选项编译。 因为使用了一些GDB中的新功能,所以KGTP需要和GDB 7.3或者更新的版本。如果你的系统不提供这么新版本的GDB,你可以到 http://code.google.com/p/gdbt/取得新版本GDB的静态编译版本,它可以在大部分 Linux上使用。同时你可以在这里取得一步一步编译新版本GDB的介绍。 ++你还需要做一些Linux内核和KGTP的准备工作,请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#使用KGTP前的准备工作 取得如果做的 介绍。 ++Attach 使用命令"gdb -p pid"或者GDB命令"attach pid"可以attach系统中的某个 程序. 需要先insmod gtp.ko,请看 https://code.google.com/p/kgtp/wiki/HOWTOCN#执行。 ++然后让GDB连接KGTP,请看https://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连 接到KGTP。
++请 注意 GDB连接到KGTP以后,Linux内核不会停止。
++Breakpoints GDB命令"b place_will_stop",让程序在执行这个命令后执行,则程 序将停止在设置这个断点的地方。 KGTP不支持断点但是支持tracepoint。 Tracepoints可以被看作一种特殊的断点。其可以设置在Linux kernel中的一些地方然 后定义一些命令到它的action中。当tracepoint开始的时候,他们将会在内核执行到这 些地方的时候执行这些命令。当tracepoint停止的时候,你可以像断点停止程序后你做 的那样用GDB命令分析tracepoint得到的数据。 区别 是断点会停止程序但是KGTP中的 tracepoint不会。 请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#GDB_tracepoint 看如何使用它。 ++读Memory GDB停止程序后(也许不需要),它可以用GDB命令"print"或者"x"等应用程 序的内存。 你可以在tracepoint中设置特殊的action收集内存到traceframe中,在 tracepoint停止后取得他们的值。 https://code.google.com/p/kgtp/wiki/HOWTOCN#collect_expr1,_expr2,_... http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 ++或者你可以在内核或者应用程序执行的时候直接读他们的内存。 https://code.google.com/p/kgtp/wiki/HOWTOCN#在普通模式直接访问当前值 ++Step 和 continue GDB可以用命令"continue"继续程序的执行,用CTRL-C停止其。 KGTP不会停止Linux内核,但是tracepoint可以开始和停止。 https://code.google.com/p/kgtp/wiki/HOWTOCN#启动和停止_tracepoint ++或者用 while-stepping tracepoint记录一定次数的single-stepping然后让KGTP切 换到回放模式。这样其就支持执行和方向执行命令了。 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让Linux内核做 单步 ++Backtrace GDB可以用命令"backtrace"打印全部调用栈。 KGTP也可以。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何_backtrace_(stack_dump) ++Watchpoint GDB可以用watchpoint让程序在某些内存访问发生的时候停止。 KGTP可以用watch tracepoint记录内存访问。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何用watch_tracepoint控制硬件断 点记录内存访问 ++调用函数 GDB可以用命令"call function(xx,xx)"调用程序中的函数。 KGTP可以 用插件调用内核中的函数。https://code.google.com/p/kgtp/wiki/HOWTOCN#如何增加 用C写的插件
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1883,6 +2005,11 @@
 +
+请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。 请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信 息和Linux内核执行时 。
 +
++当前Linux内核调试镜像在哪
++在UBUNTU中,你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到它。
++在Fedora中,你可以在"/usr/lib/debug/lib/modules/$(uname -r)/vmlinux"找到 它。
++如果你自己编译的内核,你可以在内核编译目录找到vmlinux文件。
++
 +使用/proc/kallsyms
 +在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
 +
@@ -2034,6 +2161,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +让GDB连接到KGTP
++请 注意 让GDB打开正确的vmlinux文件非常重要。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的看下如何做。
++
 +GDB在本地主机上
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -2087,7 +2216,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +在普通模式直接访问当前值
+在GDB连到KGTP上以后,如果没有用GDB命令"tfind"选择一条trace帧缓存里面的条 目,GDB就处于 普通模式。于是你可以直接访问内存(Linux内核或者用户程序)的值和 trace状态变量的值。 -+如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用"tfind"选择trace帧缓存里面的条 目取得GDB命令"tfind"的更多信息。 ++如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 取得GDB命令"tfind"的更多信息。
 +
 +Linux内核的内存
 +例如你可以用下面的命令访问"jiffies_64":
@@ -2200,7 +2329,7 @@
+当tracepoint触发的时候,执行指定的表达式。这个命令可接受用逗号分割的一组列 表。表达式的结果将被删除,所以最主要的作用是把值设置到trace状态变量中 (see http://code.google.com/p/kgtp/wiki/HOWTOCN#普通trace状态变量),而不用想 collect一样把这些值存到trace帧中。
 +
 +while-stepping n
-+请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#如果函数指针被优化掉了看如何使用它。 ++请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让 Linux内核做单步 去看如何使用它。
 +
 +启动和停止 tracepoint
 +tracepoint只有在用下面的GDB命令启动后才可以执行action:
@@ -2212,7 +2341,7 @@
 +Enable 和 disable tracepoint
+和breakpoint一样,tracepoint可以使用GDB命令 "enable" 和 "disable"。但是请 注意 它们只在tracepoint停止的时候有效。
 +
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +tracepoint停止的时候,GDB命令"tfind"可以用来选择trace帧缓存里面的条目。
+当GDB在"tfind"模式的时候,其只能显示tracepoint action collect的存在于这个 条目中的数据。所以GDB将输出一些错误信息如果想打印没有collect的数据例如函数的 参数。这不是bug,不用担心。 +如果想选择下一个条目,可以再次使用命令"tfind"。还可以用"tfind 条目ID"去选 择某个条目。
@@ -2575,17 +2704,15 @@
 +$c1             0           1904
+sys_read() 在CPU0上被执行了3255次,CPU1上执行了1904次。请 注意 这个例子只 是为了显示如何使用$cpu_id,实际上用per_cpu trace状态变量写更好。
 +
-+特殊trace状态变量 $no_self_trace
-+$no_self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的 行为的。 -+如果一个tracepoint包含一个访问到$no_self_trace的action,则当当前task是 KGTP自己的进程(GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其 将不进行记录。 -+例如,如果你要记录vfs_read或者其他有进程上下文的东西时候而且你不想trace KGTP自己的进程的时候,增加下面的命令到action里:
++特殊trace状态变量 $self_trace
++$self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的行为 的。 ++默认情况下,tracepoint被触发后,如果current_task是KGTP自己的进程 (GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其将不执行任何 actions。 ++如果你想让tracepoint actions和任何task的时候都执行,请包含一个包含一个访问 到$self_trace的命令到actions中,也就是说增加下面的命令到actions中:
 +
-+>collect $no_self_trace
-+请 注意 不和进程上下文(Irq handler, softirq)有关的部分不需要设置这个变 量。
-+
++>teval $self_trace=0
 +用$kret trace函数的结尾
+有时,因为内核是用优化编译的,所以在函数结尾设置tracepoint有时很困难。这时 你可以用$kret帮助你。 -+$kret是一个类似$no_self_trace的特殊trace状态变量。当你在tracepoint action里设置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是 其就可以trace一个函数的结尾。 ++$kret是一个类似$self_trace的特殊trace状态变量。当你在tracepoint action里设 置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是其就可以 trace一个函数的结尾。 +请 注意 这个tracepoint 必须用 "function_name" 的格式设置在函数的第一个地址 上。
 +
 +下面的部分是一个例子:
@@ -2886,6 +3013,78 @@
 +  end
+在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。
 +
++使用while-stepping让Linux内核做单步
++请 注意 while-stepping现在只有X86和X86_64支持。
++
++如何使用 while-stepping
++while-stepping 是一种可以包含actions的特殊tracepoint action。
++当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:
++
++trace vfs_read
++#因为单步会影响系统速度,所以最好用passcount或者condition限制tracepoint的 执行次数。
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #做2000次单步。
++    while-stepping 2000
++      #下面这部分是"while-stepping 2000"的actions。
++      #因为单步可能会执行到其他函数,所以最好不要访问局部变量。
++      collect $bt
++      collect $step_count
++    end
++  end
++请 注意 tracepoint在执行单步的时候会关闭当前CPU的中断。 在actions中访问 $step_count 将得到从1开始的这步的计数。
++
++读while-stepping的traceframe
++不同step的数据将会被记录到不同的traceframe中,你可以用tfind (https://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条 目) 选择他们。 ++或者你可以将KGTP切换到回放模式,这样GDB可以用执行和反向执行命令选择一个 while-stepping tracepoint的traceframe。例如:
++用tfind选择一个while-stepping的traceframe。
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++下面的命令将切换KGTP到回放模式。
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++于是可以使用执行命令。
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++设置断点 (只在回放模式下有效,不会影响到Linux内核执行)。
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++使用反向执行命令。
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB命令tstart,tstop,tfind或者quit可以自动关闭回放模式。
++
 +如何显示被优化掉的变量值
 +有时GDB会这样输出信息:
 +
@@ -3358,7 +3557,6 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/quickstart.txt
 @@ -0,0 +1,250 @@
@@ -3733,7 +3931,7 @@

 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,12887 @@
+@@ -0,0 +1,12890 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -3756,7 +3954,7 @@
 + */
 +
 +/* If "* 10" means that this is not a release version.  */
-+#define GTP_VERSION                   (20130218 * 10)
++#define GTP_VERSION                   (20130508)
 +
 +#include <linux/version.h>
 +#ifndef RHEL_RELEASE_VERSION
@@ -12135,6 +12333,9 @@
 +#ifdef CONFIG_X86
 +              if (tpe->step > 1)
 +                      gtp_have_step = 1;
++#else
++              if (tpe->step > 1)
++                      tpe->step = 1;
 +#endif
 +
 +              /* Get pass.  */
=======================================
--- /trunk/gtp_older_to_2.6.19.patch    Mon May  6 19:06:35 2013
+++ /trunk/gtp_older_to_2.6.19.patch    Wed May  8 02:15:45 2013
@@ -1,15 +1,16 @@
 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
-@@ -0,0 +1,1679 @@
+@@ -0,0 +1,1778 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTO
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +What is KGTP
 +Get help or report issues about KGTP
++Table of different between GDB debug normal program and KGTP
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -18,6 +19,7 @@
 +Fedora
 +Others
 +Make sure current Linux kernel debug image is right
++Where is the current Linux kernel debug image
 +Use /proc/kallsyms
 +Use linux_banner
+Handle the issue that cannot find any file in "/sys/" or "/sys/kernel/debug/"
@@ -56,7 +58,7 @@
 +while-stepping n
 +Start and stop the tracepoint
 +Enable and disable the tracepoint
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
 +How to handle error "No such file or directory."
 +Save the trace frame info to a file
 +Show and save the tracepoint
@@ -75,7 +77,7 @@
 +Example 1
 +Example 2
+Special trace state variables $current_task, $current_task_pid, $current_thread_info, $cpu_id, $dump_stack, $printk_level, $printk_format, $printk_tmp ,$clock, $hardirq_count, $softirq_count and $irq_count
-+Special trace state variable $no_self_trace
++Special trace state variable $self_trace
 +Trace the function return with $kret
 +Use $ignore_error and $last_errno to ignore the error of tstart
 +Use $cooked_clock and $cooked_rdtsc the time without KGTP used
@@ -90,6 +92,9 @@
 +Trace state variables of watch tracepoint
 +Static watch tracepoint
 +Dynamic watch tracepoint
++Use while-stepping let Linux kernel do single step
++Howto use while-stepping
++Read the traceframe of while-stepping
 +Howto show a variable whose value has been optimized away
 +Update your GCC
 +How to get the function pointer point to
@@ -133,6 +138,24 @@
+You can post it to http://code.google.com/p/kgtp/issues/list, write Email to kgtp@xxxxxxxxxxxxx or write Email to teawater@xxxxxxxxx .
 +The KGTP team will try our best to help you.
 +
++Table of different between GDB debug normal program and KGTP
++This table is for the people that have experience using GDB debug normal program. It will help you understand and remember the function of KGTP.
++
++Function      GDB debug normal program        GDB control KGTP debug Linux 
kernel
++Preparatory work       Have a GDB installed in your system.
++Program built with "-g". KGTP need GDB 7.3 or newer version because it use some new functions of GDB. If your system doesn't supply it,you can get new version GDB built with "-static" that can running is most of Linux system in http://code.google.com/p/gdbt/ and you can get an introduce about howto built new GDB step by step in there. ++You alse need do some preparatory work with Linux kernel and KGTP. Please goto HOWTO#Preparatory_work_before_use_KGTP get howto do it. ++Attach Use command "gdb -p pid" or GDB command "attach pid" can attach a program that running in the system. Need insmod gtp.ko first, see #Exec_it.
++Then let GDB connect to KGTP, see #Make_GDB_connect_to_gtp.
++Please note that after GDB connect to KGTP, Linux kernel will not stop.
++Breakpoints GDB command "b place_will_stop", let program execute after this command. Then programe will stop in the place that setup a breakpoint. KGTP doesn't support breakpoints but it support tracepoints. Tracepoints can be considered as a special kind of breakpoints. It can be setup in some place of Linux kernel and define some commands that you want to do in its actions. When tracepoints start, they will execute these commands when Linux kernel execute to these place. When tracepoint stop, you can use some GDB commands parse the data that get by tracepoints like what you do when program stop by breakpoints. Difference is breakpoints will stop the program But the tracepoints of KGTP not. Please goto #GDB_tracepoint get howto use it. ++Memory read After GDB stop the program(maybe doesn't need), it can read memory of program with GDB command "print", "x" and so on. You can set special actions to collect memory to traceframe in tracepoints, and get the its value when tracepoint stop.#collect_expr1,_expr2,_... #Use_tfind_select_the_entry_inside_the_trace_frame_info ++Or you can read memory directly when Linux kernel or program is running.#Direct_access_the_current_value_in_normal_mode ++Step and continue GDB can continue program execution with command "continue" and stop it with CTRL-C. KGTP never stop the Linux kernel. But tracepoint can be start and stop.#Start_and_stop_the_tracepoint ++Or use while-stepping tracepoint record Linux kernel with some times single step and Let KGTP switch to replay mode. Then it support execution commands (continue, step) and reverse-execute commands (reverse-continue, reverse-step). #Use_while-stepping_let_Linux_kernel_do_single_step ++Backtrace GDB can print backtrace of all stack frames with command "backtrace". KGTP can do it too.#Howto_backtrace_(stack_dump) ++Watchpoint GDB can let programe stop when some memory access happen with watchpoint. KGTP can record the memory access with watch tracepoint. #Howto_use_watch_tracepoint_control_hardware_breakpoints_to_recor ++Call function GDB can call function of program with command "call function(xx,xx)". KGTP can call function of Linux kernel with plugin.#How_to_add_plugin_in_C
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -200,6 +223,11 @@
 +
+Please note that if you determine you use the right Linux kernel debug image, but cannot pass these ways. Please see HOWTO#Handle_the_issue_that_Linux_kernel_debug_image's_address_in.
 +
++Where is the current Linux kernel debug image
++In UBUNTU, you can find it in "/usr/lib/debug/boot/vmlinux-$(uname -r)".
++In Fedora, you can find it in "/usr/lib/debug/lib/modules/$(uname -r)/vmlinux". ++If you build Linux kernel with yourself, you can find vmlinux file in the Linux kernel build directory.
++
 +Use /proc/kallsyms
+In the system that its Linux kernel is what you want to trace, use following command to get the address of sys_read and sys_write:
 +
@@ -354,6 +382,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +Make GDB connect to gtp
++Please note that let GDB open a right vmlinux file is very important. Please goto #Make_sure_current_Linux_kernel_debug_image_is_right get how to do it.
++
 +GDB on the current machine
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -407,7 +437,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +Direct access the current value in normal mode
+After GDB connect to KGTP, if it doesn't select any a entry of trace frame bufffer with GDB command "tfind", GDB in the normal mode. Then you can direct access the current value of memory (Linux kernel or the user space program) and the trace state variables without stop anything. -+If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto [HOWTO#Use"tfind"select_the_entry_inside_the_trace_frame_in] get more info about GDB command "tfind". ++If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto #Use_tfind_select_the_entry_inside_the_trace_frame_info get more info about GDB command "tfind".
 +
 +The memory of Linux kernel
 +For example, you can access to "jiffies_64" with following command:
@@ -521,7 +551,7 @@
+Evaluate the given expressions when the tracepoint is hit. This command accepts a comma-separated list of expressions. The results are discarded, so this is mainly useful for assigning values to trace state variables (see HOWTO#Simple_trace_state_variables) without adding those values to the trace buffer, as would be the case if the collect action were used.
 +
 +while-stepping n
-+Please goto HOWTO#If_the_debug_info_of_the_function_pointer_is_optimized_out see howto use it. ++Please goto #Use_while-stepping_let_Linux_kernel_do_single_step see howto use it.
 +
 +Start and stop the tracepoint
+Tracepoint will exec actions only when it is starting use this GDB command:
@@ -533,7 +563,7 @@
 +Enable and disable the tracepoint
+Like breakpoint, tracepoint can be control by GDB commands "enable" and "disable". But please note that it only useful when tracepoint stop.
 +
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
+GDB command "tfind" is used to select a entry of trace frame bufffer when tracepoint stop. +When GDB inside "tfind" mode, it will just show the values of this entry that the tracepoint action collect. So it will output some error when print some values that action doesn't collect for example the argument of function. That is not a bug, please don't worry about it.
 +Use "tfind" again will select next entry. "tfind id" will select entry id.
@@ -897,17 +927,15 @@
 +$c1             0           1904
+sys_read() execute 3255 times in cpu0 and 1904 times in cpu1. Please note that this example just to howto use $cpu_id. Actially, this example use per_cpu trace state variables is better.
 +
-+Special trace state variable $no_self_trace
-+$no_self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. -+If the action of a tracepoint include a command access to the $no_self_trace. The tracepoint will not trace anything if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). -+For example, if we want trace vfs_read or something that have process context, and we don't want trace the operation of KGTP self process. Add following command to the action:
-+
-+>collect $no_self_trace
-+Please note that the code that doesn't about process context (Irq handler, softirq) doesn't need set this variable.
++Special trace state variable $self_trace
++$self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. ++In default, when tracepoint is triggered, the actions will not execute if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). ++If you want tracepoint actions execute with any task, please include a command access to the $self_trace in the actions i.e. add following command to the actions:
 +
++>teval $self_trace=0
 +Trace the function return with $kret
+Sometime, set the tracepoint to the end of function is hard because the Kernel is compiled with optimization. At this time, you can get help from $kret. -+$kret is a special trace state variable like $no_self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. ++$kret is a special trace state variable like $self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. +Please note that this tracepoint must set in the first address of the function in format "function_name".
 +
 +Following part is an example:
@@ -1208,6 +1236,78 @@
 +  end
+Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.
 +
++Use while-stepping let Linux kernel do single step
++Please note that while-stepping is just support by X86 and X86_64 now.
++
++Howto use while-stepping
++while-stepping is a special tracepoint action that include some actions with it. ++When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
++
++trace vfs_read
++#Because single step will make system slow, so use passcount or condition to limit the execution times of tracepoint is better.
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #do 2000 times single steps.
++    while-stepping 2000
++      #Following part is actions of "while-stepping 2000".
++ #Because step maybe execute to other functions, so does not access local variables is better.
++      collect $bt
++      collect $step_count
++    end
++  end
++Please note that tracepoint will disable the interrupt of current CPU when it do single step. Access $step_count in actions will get the count of this step that begin with 1.
++
++Read the traceframe of while-stepping
++The data of different step that is recorded by while-stepping actions will be saved in different traceframe that you can use tfind (#Use_tfind_select_the_entry_inside_the_trace_frame_info) to select them. ++Or you can switch KGTP to replay mode to select all the traceframe of a while-stepping tracepoint with GDB execution and reverse-execution commands. For example:
++Use tfind select one the traceframe of a while-stepping tracepoint.
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Following commands will swith KGTP to replay mode.
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Then you can use execution commands.
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++Set breakpoints (Just valid in replay mode, will not affect Linux kernel execution).
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++Use reverse-execution commands.
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB commands tstart, tfind or quit can auto close the replay mode.
++
 +Howto show a variable whose value has been optimized away
 +Sometimes, GDB will output some value like:
 +
@@ -1679,19 +1779,19 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/howtocn.txt
-@@ -0,0 +1,1676 @@
+@@ -0,0 +1,1775 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTOCN
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +什么是KGTP
 +需要帮助或者汇报问题
++GDB调试普通程序和KGTP的区别表
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1700,6 +1800,7 @@
 +Fedora
 +其他系统
 +确定Linux内核调试镜像是正确的
++当前Linux内核调试镜像在哪
 +使用/proc/kallsyms
 +使用linux_banner
 +处理不能在"/sys/"或者"/sys/kernel/debug/"找到任何文件的问题
@@ -1738,7 +1839,7 @@
 +while-stepping n
 +启动和停止 tracepoint
 +Enable 和 disable tracepoint
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +如何处理错误 "No such file or directory." 或者 "没有那个文件或目录."
 +保存trace帧信息到一个文件中
 +显示和存储tracepoint
@@ -1757,7 +1858,7 @@
 +例子1
 +例子2
+特殊trace状态变量 $current_task,$current_task_pid,$current_thread_info,$cpu_id,$dump_stack,$printk_level,$printk_format,$printk_tmp,$clock,$hardirq_count,$softirq_count 和 $irq_count
-+特殊trace状态变量 $no_self_trace
++特殊trace状态变量 $self_trace
 +用$kret trace函数的结尾
 +用 $ignore_error 和 $last_errno 忽略tstart的错误
 +使用 $cooked_clock 和 $cooked_rdtsc 取得不包含KGTP运行时间的时间信息
@@ -1772,6 +1873,9 @@
 +watch tracepoint的trace状态变量
 +静态watch tracepoint
 +动态watch tracepoint
++使用while-stepping让Linux内核做单步
++如何使用 while-stepping
++读while-stepping的traceframe
 +如何显示被优化掉的变量值
 +升级你的GCC
 +如何取得函数指针指向的函数
@@ -1816,6 +1920,24 @@
+你可以把问题发到 http://code.google.com/p/kgtp/issues/list 或者写信到 kgtp@xxxxxxxxxxxxx 或者写信到 teawater@xxxxxxxxx 。
 +KGTP小组将尽全力帮助你。
 +
++GDB调试普通程序和KGTP的区别表
++这个表是给在使用过GDB调试程序的人准备的,他可以帮助你理解和记住KGTP的功 能。
++
++功能    GDB调试普通程序       GDB控制KGTP调试Linux内核
++准备工作   系统里安装了GDB。
++程序用 "-g"选项编译。 因为使用了一些GDB中的新功能,所以KGTP需要和GDB 7.3或者更新的版本。如果你的系统不提供这么新版本的GDB,你可以到 http://code.google.com/p/gdbt/取得新版本GDB的静态编译版本,它可以在大部分 Linux上使用。同时你可以在这里取得一步一步编译新版本GDB的介绍。 ++你还需要做一些Linux内核和KGTP的准备工作,请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#使用KGTP前的准备工作 取得如果做的 介绍。 ++Attach 使用命令"gdb -p pid"或者GDB命令"attach pid"可以attach系统中的某个 程序. 需要先insmod gtp.ko,请看 https://code.google.com/p/kgtp/wiki/HOWTOCN#执行。 ++然后让GDB连接KGTP,请看https://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连 接到KGTP。
++请 注意 GDB连接到KGTP以后,Linux内核不会停止。
++Breakpoints GDB命令"b place_will_stop",让程序在执行这个命令后执行,则程 序将停止在设置这个断点的地方。 KGTP不支持断点但是支持tracepoint。 Tracepoints可以被看作一种特殊的断点。其可以设置在Linux kernel中的一些地方然 后定义一些命令到它的action中。当tracepoint开始的时候,他们将会在内核执行到这 些地方的时候执行这些命令。当tracepoint停止的时候,你可以像断点停止程序后你做 的那样用GDB命令分析tracepoint得到的数据。 区别 是断点会停止程序但是KGTP中的 tracepoint不会。 请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#GDB_tracepoint 看如何使用它。 ++读Memory GDB停止程序后(也许不需要),它可以用GDB命令"print"或者"x"等应用程 序的内存。 你可以在tracepoint中设置特殊的action收集内存到traceframe中,在 tracepoint停止后取得他们的值。 https://code.google.com/p/kgtp/wiki/HOWTOCN#collect_expr1,_expr2,_... http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 ++或者你可以在内核或者应用程序执行的时候直接读他们的内存。 https://code.google.com/p/kgtp/wiki/HOWTOCN#在普通模式直接访问当前值 ++Step 和 continue GDB可以用命令"continue"继续程序的执行,用CTRL-C停止其。 KGTP不会停止Linux内核,但是tracepoint可以开始和停止。 https://code.google.com/p/kgtp/wiki/HOWTOCN#启动和停止_tracepoint ++或者用 while-stepping tracepoint记录一定次数的single-stepping然后让KGTP切 换到回放模式。这样其就支持执行和方向执行命令了。 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让Linux内核做 单步 ++Backtrace GDB可以用命令"backtrace"打印全部调用栈。 KGTP也可以。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何_backtrace_(stack_dump) ++Watchpoint GDB可以用watchpoint让程序在某些内存访问发生的时候停止。 KGTP可以用watch tracepoint记录内存访问。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何用watch_tracepoint控制硬件断 点记录内存访问 ++调用函数 GDB可以用命令"call function(xx,xx)"调用程序中的函数。 KGTP可以 用插件调用内核中的函数。https://code.google.com/p/kgtp/wiki/HOWTOCN#如何增加 用C写的插件
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1883,6 +2005,11 @@
 +
+请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。 请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信 息和Linux内核执行时 。
 +
++当前Linux内核调试镜像在哪
++在UBUNTU中,你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到它。
++在Fedora中,你可以在"/usr/lib/debug/lib/modules/$(uname -r)/vmlinux"找到 它。
++如果你自己编译的内核,你可以在内核编译目录找到vmlinux文件。
++
 +使用/proc/kallsyms
 +在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
 +
@@ -2034,6 +2161,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +让GDB连接到KGTP
++请 注意 让GDB打开正确的vmlinux文件非常重要。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的看下如何做。
++
 +GDB在本地主机上
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -2087,7 +2216,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +在普通模式直接访问当前值
+在GDB连到KGTP上以后,如果没有用GDB命令"tfind"选择一条trace帧缓存里面的条 目,GDB就处于 普通模式。于是你可以直接访问内存(Linux内核或者用户程序)的值和 trace状态变量的值。 -+如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用"tfind"选择trace帧缓存里面的条 目取得GDB命令"tfind"的更多信息。 ++如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 取得GDB命令"tfind"的更多信息。
 +
 +Linux内核的内存
 +例如你可以用下面的命令访问"jiffies_64":
@@ -2200,7 +2329,7 @@
+当tracepoint触发的时候,执行指定的表达式。这个命令可接受用逗号分割的一组列 表。表达式的结果将被删除,所以最主要的作用是把值设置到trace状态变量中 (see http://code.google.com/p/kgtp/wiki/HOWTOCN#普通trace状态变量),而不用想 collect一样把这些值存到trace帧中。
 +
 +while-stepping n
-+请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#如果函数指针被优化掉了看如何使用它。 ++请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让 Linux内核做单步 去看如何使用它。
 +
 +启动和停止 tracepoint
 +tracepoint只有在用下面的GDB命令启动后才可以执行action:
@@ -2212,7 +2341,7 @@
 +Enable 和 disable tracepoint
+和breakpoint一样,tracepoint可以使用GDB命令 "enable" 和 "disable"。但是请 注意 它们只在tracepoint停止的时候有效。
 +
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +tracepoint停止的时候,GDB命令"tfind"可以用来选择trace帧缓存里面的条目。
+当GDB在"tfind"模式的时候,其只能显示tracepoint action collect的存在于这个 条目中的数据。所以GDB将输出一些错误信息如果想打印没有collect的数据例如函数的 参数。这不是bug,不用担心。 +如果想选择下一个条目,可以再次使用命令"tfind"。还可以用"tfind 条目ID"去选 择某个条目。
@@ -2575,17 +2704,15 @@
 +$c1             0           1904
+sys_read() 在CPU0上被执行了3255次,CPU1上执行了1904次。请 注意 这个例子只 是为了显示如何使用$cpu_id,实际上用per_cpu trace状态变量写更好。
 +
-+特殊trace状态变量 $no_self_trace
-+$no_self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的 行为的。 -+如果一个tracepoint包含一个访问到$no_self_trace的action,则当当前task是 KGTP自己的进程(GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其 将不进行记录。 -+例如,如果你要记录vfs_read或者其他有进程上下文的东西时候而且你不想trace KGTP自己的进程的时候,增加下面的命令到action里:
++特殊trace状态变量 $self_trace
++$self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的行为 的。 ++默认情况下,tracepoint被触发后,如果current_task是KGTP自己的进程 (GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其将不执行任何 actions。 ++如果你想让tracepoint actions和任何task的时候都执行,请包含一个包含一个访问 到$self_trace的命令到actions中,也就是说增加下面的命令到actions中:
 +
-+>collect $no_self_trace
-+请 注意 不和进程上下文(Irq handler, softirq)有关的部分不需要设置这个变 量。
-+
++>teval $self_trace=0
 +用$kret trace函数的结尾
+有时,因为内核是用优化编译的,所以在函数结尾设置tracepoint有时很困难。这时 你可以用$kret帮助你。 -+$kret是一个类似$no_self_trace的特殊trace状态变量。当你在tracepoint action里设置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是 其就可以trace一个函数的结尾。 ++$kret是一个类似$self_trace的特殊trace状态变量。当你在tracepoint action里设 置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是其就可以 trace一个函数的结尾。 +请 注意 这个tracepoint 必须用 "function_name" 的格式设置在函数的第一个地址 上。
 +
 +下面的部分是一个例子:
@@ -2886,6 +3013,78 @@
 +  end
+在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。
 +
++使用while-stepping让Linux内核做单步
++请 注意 while-stepping现在只有X86和X86_64支持。
++
++如何使用 while-stepping
++while-stepping 是一种可以包含actions的特殊tracepoint action。
++当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:
++
++trace vfs_read
++#因为单步会影响系统速度,所以最好用passcount或者condition限制tracepoint的 执行次数。
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #做2000次单步。
++    while-stepping 2000
++      #下面这部分是"while-stepping 2000"的actions。
++      #因为单步可能会执行到其他函数,所以最好不要访问局部变量。
++      collect $bt
++      collect $step_count
++    end
++  end
++请 注意 tracepoint在执行单步的时候会关闭当前CPU的中断。 在actions中访问 $step_count 将得到从1开始的这步的计数。
++
++读while-stepping的traceframe
++不同step的数据将会被记录到不同的traceframe中,你可以用tfind (https://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条 目) 选择他们。 ++或者你可以将KGTP切换到回放模式,这样GDB可以用执行和反向执行命令选择一个 while-stepping tracepoint的traceframe。例如:
++用tfind选择一个while-stepping的traceframe。
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++下面的命令将切换KGTP到回放模式。
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++于是可以使用执行命令。
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++设置断点 (只在回放模式下有效,不会影响到Linux内核执行)。
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++使用反向执行命令。
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB命令tstart,tstop,tfind或者quit可以自动关闭回放模式。
++
 +如何显示被优化掉的变量值
 +有时GDB会这样输出信息:
 +
@@ -3358,7 +3557,6 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/quickstart.txt
 @@ -0,0 +1,250 @@
@@ -3655,7 +3853,7 @@

 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,12887 @@
+@@ -0,0 +1,12890 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -3678,7 +3876,7 @@
 + */
 +
 +/* If "* 10" means that this is not a release version.  */
-+#define GTP_VERSION                   (20130218 * 10)
++#define GTP_VERSION                   (20130508)
 +
 +#include <linux/version.h>
 +#ifndef RHEL_RELEASE_VERSION
@@ -12057,6 +12255,9 @@
 +#ifdef CONFIG_X86
 +              if (tpe->step > 1)
 +                      gtp_have_step = 1;
++#else
++              if (tpe->step > 1)
++                      tpe->step = 1;
 +#endif
 +
 +              /* Get pass.  */
=======================================
--- /trunk/gtp_taobao.patch     Sun Feb 17 20:54:51 2013
+++ /trunk/gtp_taobao.patch     Wed May  8 02:15:45 2013
@@ -1,15 +1,16 @@
 --- /dev/null
 +++ b/Documentation/gtp/howto.txt
-@@ -0,0 +1,1679 @@
+@@ -0,0 +1,1778 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTO
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +What is KGTP
 +Get help or report issues about KGTP
++Table of different between GDB debug normal program and KGTP
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -18,6 +19,7 @@
 +Fedora
 +Others
 +Make sure current Linux kernel debug image is right
++Where is the current Linux kernel debug image
 +Use /proc/kallsyms
 +Use linux_banner
+Handle the issue that cannot find any file in "/sys/" or "/sys/kernel/debug/"
@@ -56,7 +58,7 @@
 +while-stepping n
 +Start and stop the tracepoint
 +Enable and disable the tracepoint
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
 +How to handle error "No such file or directory."
 +Save the trace frame info to a file
 +Show and save the tracepoint
@@ -75,7 +77,7 @@
 +Example 1
 +Example 2
+Special trace state variables $current_task, $current_task_pid, $current_thread_info, $cpu_id, $dump_stack, $printk_level, $printk_format, $printk_tmp ,$clock, $hardirq_count, $softirq_count and $irq_count
-+Special trace state variable $no_self_trace
++Special trace state variable $self_trace
 +Trace the function return with $kret
 +Use $ignore_error and $last_errno to ignore the error of tstart
 +Use $cooked_clock and $cooked_rdtsc the time without KGTP used
@@ -90,6 +92,9 @@
 +Trace state variables of watch tracepoint
 +Static watch tracepoint
 +Dynamic watch tracepoint
++Use while-stepping let Linux kernel do single step
++Howto use while-stepping
++Read the traceframe of while-stepping
 +Howto show a variable whose value has been optimized away
 +Update your GCC
 +How to get the function pointer point to
@@ -133,6 +138,24 @@
+You can post it to http://code.google.com/p/kgtp/issues/list, write Email to kgtp@xxxxxxxxxxxxx or write Email to teawater@xxxxxxxxx .
 +The KGTP team will try our best to help you.
 +
++Table of different between GDB debug normal program and KGTP
++This table is for the people that have experience using GDB debug normal program. It will help you understand and remember the function of KGTP.
++
++Function      GDB debug normal program        GDB control KGTP debug Linux 
kernel
++Preparatory work       Have a GDB installed in your system.
++Program built with "-g". KGTP need GDB 7.3 or newer version because it use some new functions of GDB. If your system doesn't supply it,you can get new version GDB built with "-static" that can running is most of Linux system in http://code.google.com/p/gdbt/ and you can get an introduce about howto built new GDB step by step in there. ++You alse need do some preparatory work with Linux kernel and KGTP. Please goto HOWTO#Preparatory_work_before_use_KGTP get howto do it. ++Attach Use command "gdb -p pid" or GDB command "attach pid" can attach a program that running in the system. Need insmod gtp.ko first, see #Exec_it.
++Then let GDB connect to KGTP, see #Make_GDB_connect_to_gtp.
++Please note that after GDB connect to KGTP, Linux kernel will not stop.
++Breakpoints GDB command "b place_will_stop", let program execute after this command. Then programe will stop in the place that setup a breakpoint. KGTP doesn't support breakpoints but it support tracepoints. Tracepoints can be considered as a special kind of breakpoints. It can be setup in some place of Linux kernel and define some commands that you want to do in its actions. When tracepoints start, they will execute these commands when Linux kernel execute to these place. When tracepoint stop, you can use some GDB commands parse the data that get by tracepoints like what you do when program stop by breakpoints. Difference is breakpoints will stop the program But the tracepoints of KGTP not. Please goto #GDB_tracepoint get howto use it. ++Memory read After GDB stop the program(maybe doesn't need), it can read memory of program with GDB command "print", "x" and so on. You can set special actions to collect memory to traceframe in tracepoints, and get the its value when tracepoint stop.#collect_expr1,_expr2,_... #Use_tfind_select_the_entry_inside_the_trace_frame_info ++Or you can read memory directly when Linux kernel or program is running.#Direct_access_the_current_value_in_normal_mode ++Step and continue GDB can continue program execution with command "continue" and stop it with CTRL-C. KGTP never stop the Linux kernel. But tracepoint can be start and stop.#Start_and_stop_the_tracepoint ++Or use while-stepping tracepoint record Linux kernel with some times single step and Let KGTP switch to replay mode. Then it support execution commands (continue, step) and reverse-execute commands (reverse-continue, reverse-step). #Use_while-stepping_let_Linux_kernel_do_single_step ++Backtrace GDB can print backtrace of all stack frames with command "backtrace". KGTP can do it too.#Howto_backtrace_(stack_dump) ++Watchpoint GDB can let programe stop when some memory access happen with watchpoint. KGTP can record the memory access with watch tracepoint. #Howto_use_watch_tracepoint_control_hardware_breakpoints_to_recor ++Call function GDB can call function of program with command "call function(xx,xx)". KGTP can call function of Linux kernel with plugin.#How_to_add_plugin_in_C
 +Preparatory work before use KGTP
 +Linux kernel
 +If your system use the Linux kernel that is built by yourself
@@ -200,6 +223,11 @@
 +
+Please note that if you determine you use the right Linux kernel debug image, but cannot pass these ways. Please see HOWTO#Handle_the_issue_that_Linux_kernel_debug_image's_address_in.
 +
++Where is the current Linux kernel debug image
++In UBUNTU, you can find it in "/usr/lib/debug/boot/vmlinux-$(uname -r)".
++In Fedora, you can find it in "/usr/lib/debug/lib/modules/$(uname -r)/vmlinux". ++If you build Linux kernel with yourself, you can find vmlinux file in the Linux kernel build directory.
++
 +Use /proc/kallsyms
+In the system that its Linux kernel is what you want to trace, use following command to get the address of sys_read and sys_write:
 +
@@ -354,6 +382,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +Make GDB connect to gtp
++Please note that let GDB open a right vmlinux file is very important. Please goto #Make_sure_current_Linux_kernel_debug_image_is_right get how to do it.
++
 +GDB on the current machine
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -407,7 +437,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +Direct access the current value in normal mode
+After GDB connect to KGTP, if it doesn't select any a entry of trace frame bufffer with GDB command "tfind", GDB in the normal mode. Then you can direct access the current value of memory (Linux kernel or the user space program) and the trace state variables without stop anything. -+If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto [HOWTO#Use"tfind"select_the_entry_inside_the_trace_frame_in] get more info about GDB command "tfind". ++If you have selected a trace frame entry, use GDB command "tfind -1" to return to normal mode. Please goto #Use_tfind_select_the_entry_inside_the_trace_frame_info get more info about GDB command "tfind".
 +
 +The memory of Linux kernel
 +For example, you can access to "jiffies_64" with following command:
@@ -521,7 +551,7 @@
+Evaluate the given expressions when the tracepoint is hit. This command accepts a comma-separated list of expressions. The results are discarded, so this is mainly useful for assigning values to trace state variables (see HOWTO#Simple_trace_state_variables) without adding those values to the trace buffer, as would be the case if the collect action were used.
 +
 +while-stepping n
-+Please goto HOWTO#If_the_debug_info_of_the_function_pointer_is_optimized_out see howto use it. ++Please goto #Use_while-stepping_let_Linux_kernel_do_single_step see howto use it.
 +
 +Start and stop the tracepoint
+Tracepoint will exec actions only when it is starting use this GDB command:
@@ -533,7 +563,7 @@
 +Enable and disable the tracepoint
+Like breakpoint, tracepoint can be control by GDB commands "enable" and "disable". But please note that it only useful when tracepoint stop.
 +
-+Use "tfind" select the entry inside the trace frame info
++Use tfind select the entry inside the trace frame info
+GDB command "tfind" is used to select a entry of trace frame bufffer when tracepoint stop. +When GDB inside "tfind" mode, it will just show the values of this entry that the tracepoint action collect. So it will output some error when print some values that action doesn't collect for example the argument of function. That is not a bug, please don't worry about it.
 +Use "tfind" again will select next entry. "tfind id" will select entry id.
@@ -897,17 +927,15 @@
 +$c1             0           1904
+sys_read() execute 3255 times in cpu0 and 1904 times in cpu1. Please note that this example just to howto use $cpu_id. Actially, this example use per_cpu trace state variables is better.
 +
-+Special trace state variable $no_self_trace
-+$no_self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. -+If the action of a tracepoint include a command access to the $no_self_trace. The tracepoint will not trace anything if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). -+For example, if we want trace vfs_read or something that have process context, and we don't want trace the operation of KGTP self process. Add following command to the action:
++Special trace state variable $self_trace
++$self_trace is different with the special trace state variables in the previous section. It is used to control the behavior of tracepoint. ++In default, when tracepoint is triggered, the actions will not execute if the current_task is the a KGTP self process (GDB, netcat, getframe or some others process that access to the interface of KGTP). ++If you want tracepoint actions execute with any task, please include a command access to the $self_trace in the actions i.e. add following command to the actions:
 +
-+>collect $no_self_trace
-+Please note that the code that doesn't about process context (Irq handler, softirq) doesn't need set this variable.
-+
++>teval $self_trace=0
 +Trace the function return with $kret
+Sometime, set the tracepoint to the end of function is hard because the Kernel is compiled with optimization. At this time, you can get help from $kret. -+$kret is a special trace state variable like $no_self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. ++$kret is a special trace state variable like $self_trace. When you set value of it inside the action of tracepoint, this tracepoint be set with kretprobe instead of kprobe. Then it can trace the end of this function. +Please note that this tracepoint must set in the first address of the function in format "function_name".
 +
 +Following part is an example:
@@ -1208,6 +1236,78 @@
 +  end
+Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.
 +
++Use while-stepping let Linux kernel do single step
++Please note that while-stepping is just support by X86 and X86_64 now.
++
++Howto use while-stepping
++while-stepping is a special tracepoint action that include some actions with it. ++When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
++
++trace vfs_read
++#Because single step will make system slow, so use passcount or condition to limit the execution times of tracepoint is better.
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #do 2000 times single steps.
++    while-stepping 2000
++      #Following part is actions of "while-stepping 2000".
++ #Because step maybe execute to other functions, so does not access local variables is better.
++      collect $bt
++      collect $step_count
++    end
++  end
++Please note that tracepoint will disable the interrupt of current CPU when it do single step. Access $step_count in actions will get the count of this step that begin with 1.
++
++Read the traceframe of while-stepping
++The data of different step that is recorded by while-stepping actions will be saved in different traceframe that you can use tfind (#Use_tfind_select_the_entry_inside_the_trace_frame_info) to select them. ++Or you can switch KGTP to replay mode to select all the traceframe of a while-stepping tracepoint with GDB execution and reverse-execution commands. For example:
++Use tfind select one the traceframe of a while-stepping tracepoint.
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Following commands will swith KGTP to replay mode.
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++Then you can use execution commands.
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++Set breakpoints (Just valid in replay mode, will not affect Linux kernel execution).
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++Use reverse-execution commands.
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB commands tstart, tfind or quit can auto close the replay mode.
++
 +Howto show a variable whose value has been optimized away
 +Sometimes, GDB will output some value like:
 +
@@ -1679,19 +1779,19 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/howtocn.txt
-@@ -0,0 +1,1676 @@
+@@ -0,0 +1,1775 @@
 +              Linux Kernel GDB tracepoint module (KGTP)
 +              =========================================
 +              By Hui Zhu <teawater@xxxxxxxxx>
 +              https://code.google.com/p/kgtp/wiki/HOWTOCN
 +
-+Update in 2013-02-18
++Update in 2013-05-08
 +
 +什么是KGTP
 +需要帮助或者汇报问题
++GDB调试普通程序和KGTP的区别表
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1700,6 +1800,7 @@
 +Fedora
 +其他系统
 +确定Linux内核调试镜像是正确的
++当前Linux内核调试镜像在哪
 +使用/proc/kallsyms
 +使用linux_banner
 +处理不能在"/sys/"或者"/sys/kernel/debug/"找到任何文件的问题
@@ -1738,7 +1839,7 @@
 +while-stepping n
 +启动和停止 tracepoint
 +Enable 和 disable tracepoint
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +如何处理错误 "No such file or directory." 或者 "没有那个文件或目录."
 +保存trace帧信息到一个文件中
 +显示和存储tracepoint
@@ -1757,7 +1858,7 @@
 +例子1
 +例子2
+特殊trace状态变量 $current_task,$current_task_pid,$current_thread_info,$cpu_id,$dump_stack,$printk_level,$printk_format,$printk_tmp,$clock,$hardirq_count,$softirq_count 和 $irq_count
-+特殊trace状态变量 $no_self_trace
++特殊trace状态变量 $self_trace
 +用$kret trace函数的结尾
 +用 $ignore_error 和 $last_errno 忽略tstart的错误
 +使用 $cooked_clock 和 $cooked_rdtsc 取得不包含KGTP运行时间的时间信息
@@ -1772,6 +1873,9 @@
 +watch tracepoint的trace状态变量
 +静态watch tracepoint
 +动态watch tracepoint
++使用while-stepping让Linux内核做单步
++如何使用 while-stepping
++读while-stepping的traceframe
 +如何显示被优化掉的变量值
 +升级你的GCC
 +如何取得函数指针指向的函数
@@ -1816,6 +1920,24 @@
+你可以把问题发到 http://code.google.com/p/kgtp/issues/list 或者写信到 kgtp@xxxxxxxxxxxxx 或者写信到 teawater@xxxxxxxxx 。
 +KGTP小组将尽全力帮助你。
 +
++GDB调试普通程序和KGTP的区别表
++这个表是给在使用过GDB调试程序的人准备的,他可以帮助你理解和记住KGTP的功 能。
++
++功能    GDB调试普通程序       GDB控制KGTP调试Linux内核
++准备工作   系统里安装了GDB。
++程序用 "-g"选项编译。 因为使用了一些GDB中的新功能,所以KGTP需要和GDB 7.3或者更新的版本。如果你的系统不提供这么新版本的GDB,你可以到 http://code.google.com/p/gdbt/取得新版本GDB的静态编译版本,它可以在大部分 Linux上使用。同时你可以在这里取得一步一步编译新版本GDB的介绍。 ++你还需要做一些Linux内核和KGTP的准备工作,请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#使用KGTP前的准备工作 取得如果做的 介绍。 ++Attach 使用命令"gdb -p pid"或者GDB命令"attach pid"可以attach系统中的某个 程序. 需要先insmod gtp.ko,请看 https://code.google.com/p/kgtp/wiki/HOWTOCN#执行。 ++然后让GDB连接KGTP,请看https://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连 接到KGTP。
++请 注意 GDB连接到KGTP以后,Linux内核不会停止。
++Breakpoints GDB命令"b place_will_stop",让程序在执行这个命令后执行,则程 序将停止在设置这个断点的地方。 KGTP不支持断点但是支持tracepoint。 Tracepoints可以被看作一种特殊的断点。其可以设置在Linux kernel中的一些地方然 后定义一些命令到它的action中。当tracepoint开始的时候,他们将会在内核执行到这 些地方的时候执行这些命令。当tracepoint停止的时候,你可以像断点停止程序后你做 的那样用GDB命令分析tracepoint得到的数据。 区别 是断点会停止程序但是KGTP中的 tracepoint不会。 请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#GDB_tracepoint 看如何使用它。 ++读Memory GDB停止程序后(也许不需要),它可以用GDB命令"print"或者"x"等应用程 序的内存。 你可以在tracepoint中设置特殊的action收集内存到traceframe中,在 tracepoint停止后取得他们的值。 https://code.google.com/p/kgtp/wiki/HOWTOCN#collect_expr1,_expr2,_... http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 ++或者你可以在内核或者应用程序执行的时候直接读他们的内存。 https://code.google.com/p/kgtp/wiki/HOWTOCN#在普通模式直接访问当前值 ++Step 和 continue GDB可以用命令"continue"继续程序的执行,用CTRL-C停止其。 KGTP不会停止Linux内核,但是tracepoint可以开始和停止。 https://code.google.com/p/kgtp/wiki/HOWTOCN#启动和停止_tracepoint ++或者用 while-stepping tracepoint记录一定次数的single-stepping然后让KGTP切 换到回放模式。这样其就支持执行和方向执行命令了。 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让Linux内核做 单步 ++Backtrace GDB可以用命令"backtrace"打印全部调用栈。 KGTP也可以。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何_backtrace_(stack_dump) ++Watchpoint GDB可以用watchpoint让程序在某些内存访问发生的时候停止。 KGTP可以用watch tracepoint记录内存访问。 https://code.google.com/p/kgtp/wiki/HOWTOCN#如何用watch_tracepoint控制硬件断 点记录内存访问 ++调用函数 GDB可以用命令"call function(xx,xx)"调用程序中的函数。 KGTP可以 用插件调用内核中的函数。https://code.google.com/p/kgtp/wiki/HOWTOCN#如何增加 用C写的插件
 +使用KGTP前的准备工作
 +Linux内核
 +如果你的系统内核是自己编译的
@@ -1883,6 +2005,11 @@
 +
+请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。 请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信 息和Linux内核执行时 。
 +
++当前Linux内核调试镜像在哪
++在UBUNTU中,你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到它。
++在Fedora中,你可以在"/usr/lib/debug/lib/modules/$(uname -r)/vmlinux"找到 它。
++如果你自己编译的内核,你可以在内核编译目录找到vmlinux文件。
++
 +使用/proc/kallsyms
 +在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
 +
@@ -2034,6 +2161,8 @@
 +cd kgtp/
 +sudo insmod gtp.ko
 +让GDB连接到KGTP
++请 注意 让GDB打开正确的vmlinux文件非常重要。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的看下如何做。
++
 +GDB在本地主机上
 +sudo gdb ./vmlinux
 +(gdb) target remote /sys/kernel/debug/gtp
@@ -2087,7 +2216,7 @@
 +sudo ./getmod -r /home/teawater/kernel/b26 >~/tmp/mi
 +在普通模式直接访问当前值
+在GDB连到KGTP上以后,如果没有用GDB命令"tfind"选择一条trace帧缓存里面的条 目,GDB就处于 普通模式。于是你可以直接访问内存(Linux内核或者用户程序)的值和 trace状态变量的值。 -+如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用"tfind"选择trace帧缓存里面的条 目取得GDB命令"tfind"的更多信息。 ++如果你选择了一个trace帧条目,可以用GDB命令"tfind -1"返回到普通模式。请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条目 取得GDB命令"tfind"的更多信息。
 +
 +Linux内核的内存
 +例如你可以用下面的命令访问"jiffies_64":
@@ -2200,7 +2329,7 @@
+当tracepoint触发的时候,执行指定的表达式。这个命令可接受用逗号分割的一组列 表。表达式的结果将被删除,所以最主要的作用是把值设置到trace状态变量中 (see http://code.google.com/p/kgtp/wiki/HOWTOCN#普通trace状态变量),而不用想 collect一样把这些值存到trace帧中。
 +
 +while-stepping n
-+请到 http://code.google.com/p/kgtp/wiki/HOWTOCN#如果函数指针被优化掉了看如何使用它。 ++请到 https://code.google.com/p/kgtp/wiki/HOWTOCN#使用while-stepping让 Linux内核做单步 去看如何使用它。
 +
 +启动和停止 tracepoint
 +tracepoint只有在用下面的GDB命令启动后才可以执行action:
@@ -2212,7 +2341,7 @@
 +Enable 和 disable tracepoint
+和breakpoint一样,tracepoint可以使用GDB命令 "enable" 和 "disable"。但是请 注意 它们只在tracepoint停止的时候有效。
 +
-+用"tfind"选择trace帧缓存里面的条目
++用tfind选择trace帧缓存里面的条目
 +tracepoint停止的时候,GDB命令"tfind"可以用来选择trace帧缓存里面的条目。
+当GDB在"tfind"模式的时候,其只能显示tracepoint action collect的存在于这个 条目中的数据。所以GDB将输出一些错误信息如果想打印没有collect的数据例如函数的 参数。这不是bug,不用担心。 +如果想选择下一个条目,可以再次使用命令"tfind"。还可以用"tfind 条目ID"去选 择某个条目。
@@ -2575,17 +2704,15 @@
 +$c1             0           1904
+sys_read() 在CPU0上被执行了3255次,CPU1上执行了1904次。请 注意 这个例子只 是为了显示如何使用$cpu_id,实际上用per_cpu trace状态变量写更好。
 +
-+特殊trace状态变量 $no_self_trace
-+$no_self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的 行为的。 -+如果一个tracepoint包含一个访问到$no_self_trace的action,则当当前task是 KGTP自己的进程(GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其 将不进行记录。 -+例如,如果你要记录vfs_read或者其他有进程上下文的东西时候而且你不想trace KGTP自己的进程的时候,增加下面的命令到action里:
++特殊trace状态变量 $self_trace
++$self_trace和前面介绍的特殊trace状态变量不同,它是用来控制tracepoint的行为 的。 ++默认情况下,tracepoint被触发后,如果current_task是KGTP自己的进程 (GDB,netcat,getframe或者其他访问KGTP接口的进程)的时候,其将不执行任何 actions。 ++如果你想让tracepoint actions和任何task的时候都执行,请包含一个包含一个访问 到$self_trace的命令到actions中,也就是说增加下面的命令到actions中:
 +
-+>collect $no_self_trace
-+请 注意 不和进程上下文(Irq handler, softirq)有关的部分不需要设置这个变 量。
-+
++>teval $self_trace=0
 +用$kret trace函数的结尾
+有时,因为内核是用优化编译的,所以在函数结尾设置tracepoint有时很困难。这时 你可以用$kret帮助你。 -+$kret是一个类似$no_self_trace的特殊trace状态变量。当你在tracepoint action里设置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是 其就可以trace一个函数的结尾。 ++$kret是一个类似$self_trace的特殊trace状态变量。当你在tracepoint action里设 置它的值的时候,这个tracepoint将用kretprobe而不是kprobe注册。于是其就可以 trace一个函数的结尾。 +请 注意 这个tracepoint 必须用 "function_name" 的格式设置在函数的第一个地址 上。
 +
 +下面的部分是一个例子:
@@ -2886,6 +3013,78 @@
 +  end
+在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。
 +
++使用while-stepping让Linux内核做单步
++请 注意 while-stepping现在只有X86和X86_64支持。
++
++如何使用 while-stepping
++while-stepping 是一种可以包含actions的特殊tracepoint action。
++当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:
++
++trace vfs_read
++#因为单步会影响系统速度,所以最好用passcount或者condition限制tracepoint的 执行次数。
++passcount 1
++  commands
++    collect $bt
++    collect $step_count
++    #做2000次单步。
++    while-stepping 2000
++      #下面这部分是"while-stepping 2000"的actions。
++      #因为单步可能会执行到其他函数,所以最好不要访问局部变量。
++      collect $bt
++      collect $step_count
++    end
++  end
++请 注意 tracepoint在执行单步的时候会关闭当前CPU的中断。 在actions中访问 $step_count 将得到从1开始的这步的计数。
++
++读while-stepping的traceframe
++不同step的数据将会被记录到不同的traceframe中,你可以用tfind (https://code.google.com/p/kgtp/wiki/HOWTOCN#用tfind选择trace帧缓存里面的条 目) 选择他们。 ++或者你可以将KGTP切换到回放模式,这样GDB可以用执行和反向执行命令选择一个 while-stepping tracepoint的traceframe。例如:
++用tfind选择一个while-stepping的traceframe。
++
++(gdb) tfind
++Found trace frame 0, tracepoint 1
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++下面的命令将切换KGTP到回放模式。
++
++(gdb) monitor replay
++(gdb) tfind -1
++No longer looking at any trace frame
++#0 vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:365
++365     {
++于是可以使用执行命令。
++
++(gdb) n
++368             if (!(file->f_mode & FMODE_READ))
++(gdb) p file->f_mode
++$5 = 3
++设置断点 (只在回放模式下有效,不会影响到Linux内核执行)。
++
++(gdb) b 375
++Breakpoint 2 at 0xffffffff81179b75: file /build/buildd/linux-3.2.0/fs/read_write.c, line 375.
++(gdb) c
++Continuing.
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) s
++rw_verify_area (read_write=0, file=0xffff8801f7bd4c00, ppos=0xffff8801f4b45f48, count=16)
++    at /build/buildd/linux-3.2.0/fs/read_write.c:300
++300             inode = file->f_path.dentry->d_inode;
++使用反向执行命令。
++
++(gdb) rs
++
++Breakpoint 2, vfs_read (file=0xffff8801f7bd4c00, buf=0x7fff74e4edb0 <Address 0x7fff74e4edb0 out of bounds>, count=16, ++ pos=0xffff8801f4b45f48) at /build/buildd/linux-3.2.0/fs/read_write.c:375
++375             ret = rw_verify_area(READ, file, pos, count);
++(gdb) rn
++372             if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
++GDB命令tstart,tstop,tfind或者quit可以自动关闭回放模式。
++
 +如何显示被优化掉的变量值
 +有时GDB会这样输出信息:
 +
@@ -3358,7 +3557,6 @@
 +$p_pe_val_03_2=7
 +(gdb) spe 0 5 $cpu_id
 +$p_pe_val_05_2=97
-+
 --- /dev/null
 +++ b/Documentation/gtp/quickstart.txt
 @@ -0,0 +1,250 @@
@@ -3622,7 +3820,7 @@
 +
 --- a/include/linux/perf_event.h
 +++ b/include/linux/perf_event.h
-@@ -1220,5 +1220,13 @@ do {                                                    
                \
+@@ -1222,5 +1222,13 @@ do {                                                    
                \
        register_cpu_notifier(&fn##_nb);                            \
  } while (0)

@@ -3671,7 +3869,7 @@

  /*
   * Test whether two contexts are equivalent, i.e. whether they
-@@ -3186,6 +3198,14 @@ static void perf_event_reset(struct perf
+@@ -3187,6 +3199,14 @@ static void perf_event_reset(struct perf
        perf_event_update_userpage(event);
  }

@@ -3686,7 +3884,7 @@
  /*
   * Holding the top-level event's child_mutex means that any
   * descendant process that has inherited this event will block
-@@ -7468,3 +7488,15 @@ struct cgroup_subsys perf_subsys = {
+@@ -7552,3 +7572,15 @@ struct cgroup_subsys perf_subsys = {
        .attach         = perf_cgroup_attach,
  };
  #endif /* CONFIG_CGROUP_PERF */
@@ -3704,9 +3902,9 @@
 +EXPORT_SYMBOL_GPL(local_perf_event_disable);
 --- a/lib/Kconfig.debug
 +++ b/lib/Kconfig.debug
-@@ -1144,6 +1144,16 @@ config ASYNC_RAID6_TEST
-
-         If unsure, say N.
+@@ -1132,6 +1132,16 @@ config DMA_API_DEBUG
+         This option causes a performance degredation.  Use only if you want
+         to debug device drivers. If unsure, say N.

 +config GTP
 +      tristate "GDB tracepoint support"
@@ -3723,9 +3921,9 @@
  source "lib/Kconfig.kgdb"
 --- a/lib/Makefile
 +++ b/lib/Makefile
-@@ -101,6 +101,8 @@ obj-$(CONFIG_GENERIC_ATOMIC64) += atomic
+@@ -99,6 +99,8 @@ obj-$(CONFIG_GENERIC_CSUM) += checksum.o

- obj-$(CONFIG_AVERAGE) += average.o
+ obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o

 +obj-$(CONFIG_GTP) += gtp.o
 +
@@ -3734,7 +3932,7 @@

 --- /dev/null
 +++ b/lib/gtp.c
-@@ -0,0 +1,12093 @@
+@@ -0,0 +1,12890 @@
 +/*
 + * Kernel GDB tracepoint module.
 + *
@@ -3752,12 +3950,12 @@
 + * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 + *
-+ * Copyright(C) KGTP team (https://code.google.com/p/kgtp/), 2010, 2011, 2012, 2013
++ * Copyright(C) KGTP team (https://code.google.com/p/kgtp/), 2010-2013
 + *
 + */
 +
 +/* If "* 10" means that this is not a release version.  */
-+#define GTP_VERSION                   (20130218)
++#define GTP_VERSION                   (20130508)
 +
 +#include <linux/version.h>
 +#ifndef RHEL_RELEASE_VERSION
@@ -3836,6 +4034,9 @@
 +#include <linux/slab.h>
 +#include <linux/ctype.h>
 +#include <asm/atomic.h>
++#ifdef CONFIG_X86
++#include <asm/debugreg.h>
++#endif
 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
 +#include <linux/kdebug.h>
 +#else
@@ -3946,7 +4147,9 @@
 +                               + sizeof(struct gtp_frame_var))
 +#endif
 +#ifdef GTP_RB
-+#define GTP_FRAME_HEAD_SIZE   (FID_SIZE + sizeof(u64) + sizeof(ULONGEST))
++/* The frame head size: FID_HEAD + count id + frame number + pointer to prev frem */ ++#define GTP_FRAME_HEAD_SIZE (FID_SIZE + sizeof(u64) + sizeof(ULONGEST) + sizeof(void *))
++/* The frame head size: FID_PAGE_BEGIN + count id */
 +#define GTP_FRAME_PAGE_BEGIN_SIZE     (FID_SIZE + sizeof(u64))
 +#endif
 +#ifdef GTP_FTRACE_RING_BUFFER
@@ -4029,7 +4232,7 @@
 +/* This gtp entry is registered inside the system.  */
 +#define GTP_ENTRY_FLAGS_REG           2
 +/* See $no_self_trace.  */
-+#define GTP_ENTRY_FLAGS_NO_SELF_TRACE 4
++#define GTP_ENTRY_FLAGS_SELF_TRACE    4
 +/* This gtp entry has passcount.  */
 +#define GTP_ENTRY_FLAGS_HAVE_PASS     8
 +/* See $printk_level.  */
@@ -4201,13 +4404,31 @@
 +static pid_t                  gtp_current_pid;
 +
 +#ifdef CONFIG_X86
++/* Following part is for while-stepping.  */
++struct gtp_step_s {
++      spinlock_t              lock;
++      int                     step;
++      int                     irq_need_open;
++      struct gtp_entry        *tpe;
++};
++static DEFINE_PER_CPU(struct gtp_step_s, gtp_step);
++#endif
++
++#ifdef CONFIG_X86
++static int    gtp_have_watch_tracepoint;
++static int    gtp_have_step;
++#endif
++
++#ifdef CONFIG_X86
++/* Following part is for watch tracepoint.  */
 +/* This part is X86 special.  */
 +#define HWB_NUM                       4
 +
 +static unsigned long          gtp_hwb_drx[HWB_NUM];
 +static unsigned long          gtp_hwb_dr7;
 +
-+#define GTP_HWB_DR7_DEF               0x400UL
++#define GTP_HWB_DR7_DEF               (0x400UL)
++#define GTP_HWB_DR6_MASK      (0xe00fUL)
 +
 +/* This part is for all the arch.  */
 +struct gtp_hwb_s {
@@ -4285,16 +4506,16 @@
 +{
 +      switch(reg) {
 +      case 0:
-+              set_debugreg(val, 0);
++              gtp_set_debugreg(val, 0);
 +              break;
 +      case 1:
-+              set_debugreg(val, 1);
++              gtp_set_debugreg(val, 1);
 +              break;
 +      case 2:
-+              set_debugreg(val, 2);
++              gtp_set_debugreg(val, 2);
 +              break;
 +      case 3:
-+              set_debugreg(val, 3);
++              gtp_set_debugreg(val, 3);
 +              break;
 +      }
 +}
@@ -4305,11 +4526,11 @@
 +{
 +      read_lock(&gtp_hwb_lock);
 +      __get_cpu_var(gtp_hwb_sync_count_local) = gtp_hwb_sync_count;
-+      set_debugreg(0UL, 0);
-+      set_debugreg(0UL, 1);
-+      set_debugreg(0UL, 2);
-+      set_debugreg(0UL, 3);
-+      set_debugreg(GTP_HWB_DR7_DEF, 7);
++      gtp_set_debugreg(0UL, 0);
++      gtp_set_debugreg(0UL, 1);
++      gtp_set_debugreg(0UL, 2);
++      gtp_set_debugreg(0UL, 3);
++      gtp_set_debugreg(GTP_HWB_DR7_DEF, 7);
 +      read_unlock(&gtp_hwb_lock);
 +}
 +
@@ -4317,11 +4538,11 @@
 +gtp_hwb_sync_local(void)
 +{
 +      __get_cpu_var(gtp_hwb_sync_count_local) = gtp_hwb_sync_count;
-+      set_debugreg(gtp_hwb_drx[0], 0);
-+      set_debugreg(gtp_hwb_drx[1], 1);
-+      set_debugreg(gtp_hwb_drx[2], 2);
-+      set_debugreg(gtp_hwb_drx[3], 3);
-+      set_debugreg(gtp_hwb_dr7, 7);
++      gtp_set_debugreg(gtp_hwb_drx[0], 0);
++      gtp_set_debugreg(gtp_hwb_drx[1], 1);
++      gtp_set_debugreg(gtp_hwb_drx[2], 2);
++      gtp_set_debugreg(gtp_hwb_drx[3], 3);
++      gtp_set_debugreg(gtp_hwb_dr7, 7);
 +}
 +
 +static void
@@ -4476,7 +4697,7 @@
 +      GTP_VAR_PRINTK_LEVEL_ID                 = 11,
 +      GTP_VAR_PRINTK_FORMAT_ID                = 12,
 +      GTP_VAR_DUMP_STACK_ID                   = 13,
-+      GTP_VAR_NO_SELF_TRACE_ID                = 14,
++      GTP_VAR_SELF_TRACE_ID                   = 14,
 +      GTP_VAR_CPU_NUMBER_ID                   = 15,
 +      GTP_VAR_PC_PE_EN_ID                     = 16,
 +      GTP_VAR_KRET_ID                         = 17,
@@ -4509,8 +4730,11 @@
 +      GTP_WATCH_VAL_ID                        = 42,
 +      GTP_WATCH_COUNT_ID                      = 43,
 +
++      GTP_STEP_COUNT_ID                       = 44,
++      GTP_STEP_ID_ID                          = 45,
++
 +      GTP_VAR_SPECIAL_MIN                     = GTP_VAR_VERSION_ID,
-+      GTP_VAR_SPECIAL_MAX                     = GTP_WATCH_COUNT_ID,
++      GTP_VAR_SPECIAL_MAX                     = GTP_STEP_ID_ID,
 +};
 +
 +enum pe_tv_id {
@@ -5519,6 +5743,44 @@
 +};
 +#endif
 +
++#ifdef GTP_RB
++static int
++gtp_step_count_hooks_get_val(struct gtp_trace_s *gts, struct gtp_var *gtv,
++                           int64_t *val)
++{
++      if (gts->step)
++              *val = gts->tpe->step - gts->step + 1;
++      else
++              *val = 0;
++
++      return 0;
++}
++
++static struct gtp_var_hooks   gtp_step_count_hooks = {
++      .agent_get_val = gtp_step_count_hooks_get_val,
++};
++
++static DEFINE_PER_CPU(int64_t, gtp_step_id);
++
++static int
++gtp_step_id_hooks_get_val(struct gtp_trace_s *gts, struct gtp_var *gtv,
++                        int64_t *val)
++{
++      if (!gts->step) {
++              if (++ __get_cpu_var(gtp_step_id) == 0)
++                      __get_cpu_var(gtp_step_id) = 1;
++      }
++
++      *val = __get_cpu_var(gtp_step_id);
++
++      return 0;
++}
++
++static struct gtp_var_hooks   gtp_step_id_hooks = {
++      .agent_get_val = gtp_step_id_hooks_get_val,
++};
++#endif
++
 +static int
 +gtp_var_special_add_all(void)
 +{
@@ -5611,8 +5873,8 @@
 +      if (IS_ERR(var))
 +              return PTR_ERR(var);
 +
-+      var = gtp_var_special_add(GTP_VAR_NO_SELF_TRACE_ID, 0, 0,
-+                                "no_self_trace", NULL);
++      var = gtp_var_special_add(GTP_VAR_SELF_TRACE_ID, 0, 0,
++                                "self_trace", NULL);
 +      if (IS_ERR(var))
 +              return PTR_ERR(var);
 +
@@ -5738,6 +6000,16 @@
 +      if (IS_ERR(var))
 +              return PTR_ERR(var);
 +#endif
++      var = gtp_var_special_add(GTP_STEP_COUNT_ID, 0, 0,
++                                "step_count", &gtp_step_count_hooks);
++      if (IS_ERR(var))
++              return PTR_ERR(var);
++#ifdef GTP_RB
++      var = gtp_var_special_add(GTP_STEP_ID_ID, 0, 0,
++                                "step_id", &gtp_step_id_hooks);
++      if (IS_ERR(var))
++              return PTR_ERR(var);
++#endif
 +
 +      return 0;
 +}
@@ -7310,6 +7582,11 @@
 +      } while (0)
 +#endif
 +
++static int    gtp_collect_var(struct gtp_trace_s *gts, int num);
++#ifdef GTP_RB
++static int    gtp_var_array_step_id_id = 0;
++#endif
++
 +static int
 +gtp_action_head(struct gtp_trace_s *gts)
 +{
@@ -7358,6 +7635,13 @@
 +
 +      trace_nump = (ULONGEST *)tmp;
 +      *trace_nump = gts->tpe->num;
++      tmp += sizeof(ULONGEST);
++
++#ifdef GTP_RB
++      *(void **)tmp = gtp_rb_prev_frame_get(gts->next);
++      gtp_rb_prev_frame_set(gts->next, (void *)(tmp + sizeof(void *)
++                                                - GTP_FRAME_HEAD_SIZE));
++#endif
 +
 +#ifdef GTP_FTRACE_RING_BUFFER
 +      ring_buffer_unlock_commit(gtp_frame, rbe);
@@ -7366,6 +7650,14 @@
 +
 +      atomic_inc(&gtp_frame_create);
 +
++#ifdef GTP_RB
++      /* Auto collect $step_id.  */
++      if (gts->tpe->step) {
++              if (gtp_collect_var(gts, gtp_var_array_step_id_id))
++                      return -1;
++      }
++#endif
++
 +      return 0;
 +}
 +
@@ -7808,6 +8100,8 @@
 +
 +      return ret;
 +}
++
++/* The number is not the ID of tvar, it is the ID of gtp_var_array. */
 +
 +static int
 +gtp_collect_var(struct gtp_trace_s *gts, int num)
@@ -8463,6 +8757,30 @@
 +}
 +#endif
 +
++#ifdef CONFIG_X86
++/* while-stepping stop.  */
++
++static void
++gtp_step_stop(struct pt_regs *regs)
++{
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24))
++      regs->flags &= ~(X86_EFLAGS_TF);
++#else
++      regs->eflags &= ~(X86_EFLAGS_TF);
++#endif
++      if (__get_cpu_var(gtp_step).irq_need_open) {
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24))
++              regs->flags |= X86_EFLAGS_IF;
++#else
++              regs->eflags |= X86_EFLAGS_IF;
++#endif
++      }
++      __get_cpu_var(gtp_step).step = 0;
++      __get_cpu_var(gtp_step).tpe = NULL;
++      __get_cpu_var(gtp_step).irq_need_open = 0;
++}
++#endif
++
 +static void
 +gtp_handler(struct gtp_trace_s *gts)
 +{
@@ -8472,6 +8790,10 @@
 +      printk(GTP_DEBUG_V "gtp_handler: tracepoint %d %p\n",
 +             (int)gts->tpe->num, (void *)(CORE_ADDR)gts->tpe->addr);
 +#endif
++#ifdef CONFIG_X86
++      if (gts->step == 0 && __get_cpu_var(gtp_step).step)
++              gtp_step_stop(gts->regs);
++#endif
 +
 +      gts->read_memory = (void *)probe_kernel_read;
 +      if (gts->tpe->flags & GTP_ENTRY_FLAGS_CURRENT_TASK) {
@@ -8488,7 +8810,7 @@
 +              return;
 +#endif
 +
-+      if ((gts->tpe->flags & GTP_ENTRY_FLAGS_NO_SELF_TRACE)
++      if ((gts->tpe->flags & GTP_ENTRY_FLAGS_SELF_TRACE) == 0
 +          && (get_current()->pid == gtp_gtp_pid
 +              || get_current()->pid == gtp_gtpframe_pid)) {
 +                      return;
@@ -8513,7 +8835,7 @@
 +      gts->run = NULL;
 +
 +      /* Pass.  */
-+      if (gts->tpe->flags & GTP_ENTRY_FLAGS_HAVE_PASS) {
++      if (gts->step == 0 && gts->tpe->flags & GTP_ENTRY_FLAGS_HAVE_PASS) {
 +              if (atomic_dec_return(&gts->tpe->current_pass) < 0)
 +                      goto tpe_stop;
 +      }
@@ -8673,18 +8995,47 @@
 +      struct kretprobe        *kpret;
 +      struct gtp_kp           *gkp;
 +      union gtp_entry_u       *u;
++      struct gtp_entry                *tpe;
 +      struct gtp_trace_s      gts;
 +
-+      memset(&gts, 0, sizeof(struct gtp_trace_s));
-+
 +      kpret = container_of(p, struct kretprobe, kp);
 +      gkp = container_of(kpret, struct gtp_kp, kpret);
 +      u = container_of(gkp, union gtp_entry_u, kp);
-+      gts.tpe = container_of(u, struct gtp_entry, u);
-+      gts.regs = regs;
-+      gts.step = 1;
++      tpe = container_of(u, struct gtp_entry, u);
++
++      if (tpe->step == 1) {
++              memset(&gts, 0, sizeof(struct gtp_trace_s));
++
++              gts.tpe = tpe;
++              gts.regs = regs;
++              gts.step = tpe->step;
++
++              gtp_handler(&gts);
++      }
 +
-+      gtp_handler(&gts);
++#ifdef CONFIG_X86
++      if (tpe->step > 1) {
++              /* Let while-stepping begin.  */
++ /*XXX if there a another one, maybe we need add end frame to let reader know that this while step stop. */
++              __get_cpu_var(gtp_step).step = tpe->step;
++              __get_cpu_var(gtp_step).tpe = tpe;
++              #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24))
++              if (regs->flags & X86_EFLAGS_IF)
++              #else
++              if (regs->eflags & X86_EFLAGS_IF)
++              #endif
++                      __get_cpu_var(gtp_step).irq_need_open = 1;
++              else
++                      __get_cpu_var(gtp_step).irq_need_open = 0;
++              #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24))
++              regs->flags |= X86_EFLAGS_TF;
++              regs->flags &= ~(X86_EFLAGS_IF);
++              #else
++              regs->eflags |= X86_EFLAGS_TF;
++              regs->eflags &= ~(X86_EFLAGS_IF);
++              #endif
++      }
++#endif
 +}
 +
 +static inline void
@@ -8965,6 +9316,7 @@
 +              gtp_list = gtp_list->next;
 +              gtp_action_release(tpe->cond);
 +              gtp_action_release(tpe->action_list);
++              gtp_action_release(tpe->step_action_list);
 +              gtp_src_release(tpe->src);
 +              gtp_src_release(tpe->action_cmd);
 +              gtp_src_release(tpe->printk_str);
@@ -9205,6 +9557,238 @@
 +
 +      return 0;
 +}
++
++#ifdef CONFIG_X86
++#define ADDR_PREFIX_OPCODE 0x67
++#define DATA_PREFIX_OPCODE 0x66
++#define LOCK_PREFIX_OPCODE 0xf0
++#define CS_PREFIX_OPCODE 0x2e
++#define DS_PREFIX_OPCODE 0x3e
++#define ES_PREFIX_OPCODE 0x26
++#define FS_PREFIX_OPCODE 0x64
++#define GS_PREFIX_OPCODE 0x65
++#define SS_PREFIX_OPCODE 0x36
++#define REPNE_PREFIX_OPCODE 0xf2
++#define REPE_PREFIX_OPCODE  0xf3
++
++static int
++gtp_step_check_insn(struct pt_regs *regs)
++{
++      uint32_t        opcode;
++      uint8_t         opcode8;
++      unsigned long   pc = GTP_REGS_PC(regs);
++
++      /* prefixes */
++      while (1) {
++              if (probe_kernel_read(&opcode8, (void *)pc, 1))
++                      return -1;
++              pc++;
++              switch (opcode8) {
++              case REPE_PREFIX_OPCODE:
++              case REPNE_PREFIX_OPCODE:
++              case LOCK_PREFIX_OPCODE:
++              case CS_PREFIX_OPCODE:
++              case SS_PREFIX_OPCODE:
++              case DS_PREFIX_OPCODE:
++              case ES_PREFIX_OPCODE:
++              case FS_PREFIX_OPCODE:
++              case GS_PREFIX_OPCODE:
++              case DATA_PREFIX_OPCODE:
++              case ADDR_PREFIX_OPCODE:
++#ifndef CONFIG_X86_32
++              case 0x40 ... 0x4f:
++#endif
++                      break;
++              default:
++                      goto out_prefixes;
++              }
++      }
++out_prefixes:
++
++      opcode = (uint32_t)opcode8;
++reswitch:
++      switch (opcode) {
++      case 0x0f:
++              if (probe_kernel_read(&opcode8, (void *)pc, 1))
++                      return -1;
++              opcode = (uint32_t) opcode8 | 0x0f00;
++              goto reswitch;
++              break;
++      case 0xfb:
++              /* sti */
++              __get_cpu_var(gtp_step).irq_need_open = 1;
***The diff for this file has been truncated for email.***
=======================================
--- /trunk/howto.txt    Wed May  8 00:45:30 2013
+++ /trunk/howto.txt    Wed May  8 02:15:45 2013
@@ -1234,6 +1234,8 @@
Define a normal tracepoint that stop the tracepoint that watch file->f_pos and file->f_op.

 Use while-stepping let Linux kernel do single step
+Please note that while-stepping is just support by X86 and X86_64 now.
+
 Howto use while-stepping
while-stepping is a special tracepoint action that include some actions with it. When tracepoints that its actions include "while-stepping n" execute, it will do n times single steps and executes the actions of while-stepping. For example:
=======================================
--- /trunk/howtocn.txt  Wed May  8 00:45:30 2013
+++ /trunk/howtocn.txt  Wed May  8 02:15:45 2013
@@ -1230,6 +1230,8 @@
在函数file_sb_list_del中定义一个普通tracepoint,其将停止监视file->f_pos和 file->f_op。

 使用while-stepping让Linux内核做单步
+请 注意 while-stepping现在只有X86和X86_64支持。
+
 如何使用 while-stepping
 while-stepping 是一种可以包含actions的特殊tracepoint action。
当一个actions中包含了“while-stepping n”的tracepoint执行的时候,其将做n次单 步并执行while-stepping的actions。例如:

Other related posts:

  • » [kgtp] r1561 committed - Update patches - kgtp