作者:朱辉
开源网址:https://github.com/teawater
http://teawater.github.io/kgtp/ 有中文版说明
内核编绎:
General setup --->
[ * ] Prompt
for
development and/or incomplete code/drivers
[ * ] Kprobe
Kernel hacking --->
[ * ] Compile the kernel with debug info
[ * ] Compile the kernel with frame pointers
KGTP_INSTALL_GDB = "gdb-7.7"
1.编绎
tar -zxvf kgtp-20140510.tar.gz
[root@localhost kgtp-20140510]# ls add-ons gtp_2.6.20_to_2.6.32.patch gtp_rb.c plugin_example.c dkms.conf gtp_2.6.33_to_2.6.38.patch kgtpcn.odt putgtprsp.c dkms_others_install.sh gtp_2.6.39.patch kgtpcn.pdf README.md dkms_others_uninstall.sh gtp_3.0_to_3.6.patch kgtp.odt ring_buffer.c getframe.c gtp_3.7_to_upstream.patch kgtp.pdf ring_buffer.h getgtprsp.pl gtp.c kgtp.py UPDATE getmod.c gtp.h Makefile getmod.py gtp_older_to_2.6.19.patch perf_event.c
[root@localhost kgtp-20140510]# make make CROSS_COMPILE= -C /lib/modules/2.6.32/build/ M=/root/kgtp-20140510 modules make[1]: Entering directory `/usr/src/kernels/linux-2.6.32' CC [M] /root/kgtp-20140510/gtp.o /root/kgtp-20140510/gtp.c:132:2: warning: #warning "Current Kernel is too old. Function of performance counters is not available." /root/kgtp-20140510/gtp.c:168:2: warning: #warning "Cannot trace user program because the Linux Kernel that older than 3.9 doesn't support UPROBES." /root/kgtp-20140510/gtp_rb.c: In function ‘gtp_rb_walk’: /root/kgtp-20140510/gtp_rb.c:337: warning: ‘step’ may be used uninitialized in this function /root/kgtp-20140510/gtp.c:132:2: warning: #warning "Current Kernel is too old. Function of performance counters is not available." /root/kgtp-20140510/gtp.c:168:2: warning: #warning "Cannot trace user program because the Linux Kernel that older than 3.9 doesn't support UPROBES." Building modules, stage 2. MODPOST 1 modules CC /root/kgtp-20140510/gtp.mod.o LD [M] /root/kgtp-20140510/gtp.ko make[1]: Leaving directory `/usr/src/kernels/linux-2.6.32' gcc -O2 -static -o getmod getmod.c gcc -O2 -static -o getframe getframe.c gcc -O2 -static -o putgtprsp putgtprsp.c
2.insmod gtp.ko
3. mount -t sysfs none /sys/
mount -t debugfs none /sys/kernel/debug/
4. cd /usr/src/kernels/linux-2.6.32 进入源代码目录
5.gdb vmlinux
6.(gdb) target remote /sys/kernel/debug/gtp
7. 调试内核
(gdb) trace vfs_readdir 跟踪涵数名 Tracepoint 1 at 0xffffffff810d751f: file fs/readdir.c, line 23.
-------------------------------------------------------------------- (gdb) actions 设轩预到跟踪点进行收集信息
Enter actions for tracepoint 1, one per line. End with a line saying just "end".
> collect jiffies_64 > collect file->f_path.dentry->d_iname > end
------------------------------------------------------------------------------------------- (gdb) tstart 开始跟踪
-------------------------------------------------------------------------------------------- (gdb) shell ls :跟踪ls arch Documentation init MAINTAINERS net security virt block drivers ipc Makefile README sound vmlinux COPYING firmware Kbuild mm REPORTING-BUGS System.map vmlinux.o CREDITS fs kernel modules.order samples tools crypto include lib Module.symvers scripts usr
---------------------------------------------------------------------------------------------- (gdb) tstop 停止跟踪
------------------------------------------------------------------------------------------------- (gdb) tfind #0 vfs_readdir (file=0xffff88003c087480, filler=0xffffffff810d7468 <filldir>, buf=0xffff88004884df38) at fs/readdir.c:23 23 { (gdb) p jiffies_64 $1 = 4297940608 (gdb) p file->f_path.dentry->d_iname $2 = "/\000r", '\000' <repeats 28 times>
(gdb) list vfs_readdir 18 #include <linux/unistd.h> 19 20 #include <asm/uaccess.h> 21 22 int vfs_readdir(struct file *file, filldir_t filler, void *buf) 23 { 24 struct inode *inode = file->f_path.dentry->d_inode; 25 int res = -ENOTDIR; 26 if (!file->f_op || !file->f_op->readdir) 27 goto out;
(gdb) disassemble /m vfs_readdir Dump of assembler code for function vfs_readdir: 23 { 0xffffffff810d751f <vfs_readdir+0>: push %r15 0xffffffff810d7521 <vfs_readdir+2>: mov %rdx,%r15 0xffffffff810d7524 <vfs_readdir+5>: push %r14 0xffffffff810d7526 <vfs_readdir+7>: mov %rsi,%r14 0xffffffff810d7529 <vfs_readdir+10>: push %r13 0xffffffff810d752b <vfs_readdir+12>: push %r12 0xffffffff810d752d <vfs_readdir+14>: push %rbp 0xffffffff810d752e <vfs_readdir+15>: mov %rdi,%rbp 0xffffffff810d7531 <vfs_readdir+18>: push %rbx 0xffffffff810d7532 <vfs_readdir+19>: sub $0x8,%rsp 24 struct inode *inode = file->f_path.dentry->d_inode; 0xffffffff810d7536 <vfs_readdir+23>: mov 0x18(%rdi),%rax 0xffffffff810d753a <vfs_readdir+27>: mov 0x10(%rax),%r12 25 int res = -ENOTDIR; 26 if (!file->f_op || !file->f_op->readdir) 0xffffffff810d753e <vfs_readdir+31>: mov 0x20(%rdi),%rax ---Type <return> to continue, or q <return> to quit--- 0xffffffff810d7542 <vfs_readdir+35>: test %rax,%rax 0xffffffff810d7545 <vfs_readdir+38>: je 0xffffffff810d75b3 <vfs_readdir+148> 0xffffffff810d7547 <vfs_readdir+40>: cmpq $0x0,0x30(%rax) 0xffffffff810d754c <vfs_readdir+45>: je 0xffffffff810d75b3 <vfs_readdir+148> 27 goto out; 28 29 res = security_file_permission(file, MAY_READ); 0xffffffff810d754e <vfs_readdir+47>: mov $0x4,%esi 0xffffffff810d7553 <vfs_readdir+52>: callq 0xffffffff8113848d <security_file_permission> 0xffffffff810d755a <vfs_readdir+59>: mov %eax,%ebx 30 if (res) 0xffffffff810d7558 <vfs_readdir+57>: test %eax,%eax 0xffffffff810d755c <vfs_readdir+61>: jne 0xffffffff810d75b8 <vfs_readdir+153> 31 goto out; 32 33 res = mutex_lock_killable(&inode->i_mutex); 0xffffffff810d755e <vfs_readdir+63>: lea 0xb8(%r12),%r13 ---Type <return> to continue, or q <return> to quit--- 0xffffffff810d7566 <vfs_readdir+71>: mov %r13,%rdi 0xffffffff810d7569 <vfs_readdir+74>: callq 0xffffffff812f4bff <mutex_lock_killable> 0xffffffff810d7570 <vfs_readdir+81>: mov %eax,%ebx 34 if (res) 0xffffffff810d756e <vfs_readdir+79>: test %eax,%eax 0xffffffff810d7572 <vfs_readdir+83>: jne 0xffffffff810d75b8 <vfs_readdir+153> 35 goto out; 36 37 res = -ENOENT; 38 if (!IS_DEADDIR(inode)) { 0xffffffff810d7574 <vfs_readdir+85>: testb $0x10,0x220(%r12) 0xffffffff810d757d <vfs_readdir+94>: mov $0xfffffffe,%ebx 0xffffffff810d7582 <vfs_readdir+99>: jne 0xffffffff810d75a9 <vfs_readdir+138> 39 res = file->f_op->readdir(file, buf, filler); 0xffffffff810d7584 <vfs_readdir+101>: mov 0x20(%rbp),%rax 0xffffffff810d7588 <vfs_readdir+105>: mov %r14,%rdx 0xffffffff810d758b <vfs_readdir+108>: mov %r15,%rsi ---Type <return> to continue, or q <return> to quit--- 0xffffffff810d758e <vfs_readdir+111>: mov %rbp,%rdi 0xffffffff810d7591 <vfs_readdir+114>: callq *0x30(%rax) 0xffffffff810d7598 <vfs_readdir+121>: mov %eax,%ebx 40 file_accessed(file); 41 } 42 mutex_unlock(&inode->i_mutex); 0xffffffff810d75a9 <vfs_readdir+138>: mov %r13,%rdi 0xffffffff810d75ac <vfs_readdir+141>: callq 0xffffffff812f4a35 <mutex_unlock> 0xffffffff810d75b1 <vfs_readdir+146>: jmp 0xffffffff810d75b8 <vfs_readdir+153> 43 out: 0xffffffff810d75b3 <vfs_readdir+148>: mov $0xffffffec,%ebx 44 return res; 45 } 0xffffffff810d75b8 <vfs_readdir+153>: pop %rcx 0xffffffff810d75b9 <vfs_readdir+154>: mov %ebx,%eax 0xffffffff810d75bb <vfs_readdir+156>: pop %rbx 0xffffffff810d75bc <vfs_readdir+157>: pop %rbp ---Type <return> to continue, or q <return> to quit--- 0xffffffff810d75bd <vfs_readdir+158>: pop %r12 0xffffffff810d75bf <vfs_readdir+160>: pop %r13 0xffffffff810d75c1 <vfs_readdir+162>: pop %r14 0xffffffff810d75c3 <vfs_readdir+164>: pop %r15 0xffffffff810d75c5 <vfs_readdir+166>: retq