要使用KGTP,你需要打开下面这些内核选项:
General setup ---> [*] Kprobes [*] Enable loadable module support ---> Kernel hacking ---> [*] Debug Filesystem [*] Compile the kernel with debug info
你需要安装一些Linux内核软件包。
1) 增加调试源到Ubuntu源列表。
echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse" | \ sudo tee -a /etc/apt/sources.list.d/ddebs.list
echo "deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse deb http://ddebs.ubuntu.com $(lsb_release -cs)-security main restricted universe multiverse deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \ sudo tee -a /etc/apt/sources.list.d/ddebs.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 428D7C01
sudo apt-get update
2) 安装Linux内核调试镜像。
sudo apt-get install linux-image-$(uname -r)-dbgsym
于是你可以在"/usr/lib/debug/boot/vmlinux-$(uname -r)"找到内核调试镜像。
请 注意 当内核更新的时候这一步需要再做一次。
sudo apt-get install linux-headers-generic
sudo apt-get install linux-source
sudo mkdir -p /build/buildd/ sudo tar vxjf /usr/src/linux-source-$(uname -r | sed 's/-.*//').tar.bz2 -C /build/buildd/ sudo rm -rf /build/buildd/linux-$(uname -r | sed 's/-.*//') sudo mv /build/buildd/linux-source-$(uname -r | sed 's/-.*//') /build/buildd/linux-$(uname -r | sed 's/-.*//')
请 注意 当内核更新的时候这一步需要再做一次。
其他系统
需要安装Linux内核调试镜像和Linux内核源码包。
因为GDB从Linux内核调试镜像里取得地址信息和调试信息,所以使用正确的Linux内核调试镜像是非常重要的。所以在使用KGTP前,请先做检查。
有2个方法进行检查,我建议2个方法都做一次来确保Linux内核调试镜像是正确的。
请 注意 如果你确定使用了正确的Linux内核调试镜像但是不能通过这个两个方法。请看 http://code.google.com/p/kgtp/wiki/HOWTOCN#处理Linux内核调试镜像地址信息和Linux内核执行时 。
在运行着要trace的内核的系统上,用下面的命令取得sys_read和sys_write的地址:
sudo cat /proc/kallsyms | grep sys_read ffffffff8117a520 T sys_read sudo cat /proc/kallsyms | grep sys_write ffffffff8117a5b0 T sys_write
于是我们就可以得到sys_read的地址是0xffffffff8117a520,sys_write的地址是0xffffffff8117a5b0。
之后我们用GDB从Linux内核调试镜像中取得sys_read和sys_write的地址:
gdb ./vmlinux //目前我在“安装Linux内核调试镜像”这步之前,试了不行。会提示不认识的文件 (gdb) p sys_read $1 = {long int (unsigned int, char *, size_t)} 0xffffffff8117a520 <sys_read> (gdb) p sys_write $2 = {long int (unsigned int, const char *, size_t)} 0xffffffff8117a5b0 <sys_write>
sys_read和sys_write的地址一样,所以Linux内核调试镜像是正确的。
sudo gdb ./vmlinux (gdb) p linux_banner $1 = "Linux version 3.4.0-rc4+ (teawater@teawater-Precision-M4600) (gcc version 4.6.3 (GCC) ) #3 SMP Tue Apr 24 13:29:05 CST 2012\n"
linux_banner是Linux内核调试镜像里的内核信息。
之后,根据 http://code.google.com/p/kgtp/wiki/HOWTOCN#让GDB连接到KGTP 里的方法连接到KGTP上并再次打印linux_banner。
(gdb) target remote /sys/kernel/debug/gtp Remote debugging using /sys/kernel/debug/gtp 0x0000000000000000 in irq_stack_union () (gdb) p linux_banner $2 = "Linux version 3.4.0-rc4+ (teawater@teawater-Precision-M4600) (gcc version 4.6.3 (GCC) ) #3 SMP Tue Apr 24 13:29:05 CST 2012\n"
这个linux_banner是KGTP正在trace的内核的内核信息,如果相同,则Linux内核调试镜像是正确的。
在X86_32上,用 http://code.google.com/p/kgtp/wiki/HOWTOCN#确定Linux内核调试镜像是正确的 介绍的方法发现Linux内核调试镜像地址信息和Linux内核执行时不同,而且确定使用的Linux内核调试镜像是正确的。
这个问题是因为:
Processor type and features ---> (0x1000000) Physical address where the kernel is loaded (0x100000) Alignment value to which kernel should be aligned
这个两个参数的值不同。请 注意 "Physical address where the kernel is loaded" 有时不会在配置的时候显示,你可以通过搜索 "PHYSICAL_START" 取得它的值。
你可以通过修改 "Alignment value to which kernel should be aligned" 的值和 "Physical address where the kernel is loaded" 来处理这个问题。
这个问题不影响X86_64。
请到 http://code.google.com/p/kgtp/downloads/list 或者 UPDATE 去下载源码包。
有些人访问KGTP站点有问题,你可以通过svn访问KGTP。
svn checkout http://kgtp.googlecode.com/svn/ kgtp-read-only
kgtp-read-only/tags/ 这里是KGTP每个发布的版本。
kgtp-read-only/trunk/ 这里是KGTP的主干。
下面这部分是在KGTP Makefile里的配置。用这个配置,KGTP将自动和当前系统的内核一起编译。
KERNELDIR := /lib/modules/`uname -r`/build CROSS_COMPILE :=
KERELDIR 设置了你要一起编译的内核,默认情况下,KGTP会和当前的内核一起编译。
请 注意 这个目录应该是内核编译目录或者linux-headers目录,而不是内核源码目录。内核编译目录只有在编译成功后才能使用。
CROSS_COMPILE 设置编译KGTP的编译器前缀名。留空则使用默认编译器。
ARCH 是体系结构。
或者你可以通过修改KGTP目录里的Makefile选择你要和哪个内核一起编译以及你用什么编译器编译KGTP。
例如:
KERNELDIR := /home/teawater/kernel/bamd64 CROSS_COMPILE :=x86_64-glibc_std- ARCH := x86_64
KERNELDIR 设置为 /home/teawater/kernel/bamd64。 Compiler 设置为 x86_64-glibc_std-gcc。
cd kgtp/ make
在一些编译环境中(例如Android)将出现一些编译应用程序getmod或者getframe的错误。请忽略这些错误并使用目录中的gtp.ko。
大部分时候,KGTP可以自动选择正确的参数和和各种版本的Linux内核一起编译。
但是如果你想配置一些特殊选项,可以按照下面的介绍来做:
用这个选项,KGTP将不自动选择任何编译选项。
make AUTO=0
用这个选项,KGTP将使用简单frame替代KGTP ring buffer。
简单frame不支持gtpframe_pipe,它现在只用来调试KGTP。
make AUTO=0 FRAME_SIMPLE=1
用这个选项,$clock将返回rdtsc的值而不是local_clock。
make AUTO=0 CLOCK_CYCLE=1
用这个选项,KGTP可以用procfs替代debugfs。
make AUTO=0 USE_PROC=1
这些选线可以一起使用,例如:
make AUTO=0 FRAME_SIMPLE=1 CLOCK_CYCLE=1
因为KGTP可以直接在编译目录里insmod,所以不编译后不安装也可以直接使用(见 http://code.google.com/p/kgtp/wiki/HOWTOCN#执行)。但是如果需要也可以将其安装到系统中。 安装:
cd kgtp/ sudo make install
卸载:
cd kgtp/ sudo make uninstall
如果你需要的话,你还可以让DKMS来使用KGTP。
下面的命令将拷贝KGTP的文件到DKMS需要的目录中。
cd kgtp/ sudo make dkms
于是你可以用DKMS命令控制KGTP。请到 http://linux.dell.com/dkms/manpage.html 去看如何使用DKMS。
大多数时候,你不需要KGTP patch,因为KGTP以一个LKM的形式编译安装更为方便。但是为了帮助人们集成KGTP到他们自己的内核树,KGTP也提供了patch. 在KGTP目录中:
早于7.3版本的GDB的tracepoint功能有一些bug,而且还有一些功能做的不是很好。
所以如果你的GDB小于7.3请到 https://code.google.com/p/gdbt/ 去安装可以和KGTP一起使用的GDB。 如果你有GDB的问题,请根据这里的信息http://code.google.com/p/kgtp/wiki/HOWTOCN#需要帮助或者汇报问题取得帮助。