linux内核源码Documentation目录下存在kprobe介绍文档如下
Kprobes allows multiple probes at the same address. Currently,
however, there cannot be multiple jprobes on the same function at
the same time.
If you install a probe in an inline-able function, Kprobes makes
no attempt to chase down all inline instances of the function and
install probes there. gcc may inline a function without being asked,
so keep this in mind if you're not seeing the probe hits you expect.
A probe handler can modify the environment of the probed function
-- e.g., by modifying kernel data structures, or by modifying the
contents of the pt_regs struct (which are restored to the registers
upon return from the breakpoint). So Kprobes can be used, for example,
to install a bug fix or to inject faults for testing. Kprobes, of
course, has no way to distinguish the deliberately injected faults
from the accidental ones. Don't drink and probe.
Kprobes makes no attempt to prevent probe handlers from stepping on
each other -- e.g., probing printk() and then calling printk() from a
probe handler. If a probe handler hits a probe, that second probe's
handlers won't be run in that instance, and the kprobe.nmissed member
of the second probe will be incremented.
Kprobes does not use mutexes or allocate memory except during
registration and unregistration.
/sys/kernel/debug/kprobes
crash> gdb disass /r tcp_v4_rcv #加载了tcp_debug模块 jprobe
Dump of assembler code forfunction tcp_v4_rcv:
0xffffffff81782980<+0>: e8 7b c6 893e callq 0xffffffffc001f000
0xffffffff81782985<+5>: 55 push %rbp
0xffffffff81782986<+6>: 4889 e5 mov %rsp,%rbp
0xffffffff81782989<+9>: 4157 push %r15
0xffffffff8178298b<+11>: 4156 push %r14
0xffffffff8178298d<+13>: 4155 push %r13
0xffffffff8178298f<+15>: 4154 push %r12
0xffffffff81782991<+17>: 53 push %rbx
0xffffffff81782992<+18>: 4889 fb mov %rdi,%rbx
0xffffffff81782995<+21>: 4883 ec 60 sub $0x60,%rsp
crash>
crash> gdb disass /r tcp_v4_rcv #卸载tcp_debug模块 jprobe
Dump of assembler code forfunction tcp_v4_rcv:
0xffffffff81782980<+0>: 6666666690 data32 data32 data32 xchg %ax,%ax
0xffffffff81782985<+5>: 55 push %rbp
0xffffffff81782986<+6>: 4889 e5 mov %rsp,%rbp
0xffffffff81782989<+9>: 4157 push %r15
0xffffffff8178298b<+11>: 4156 push %r14
0xffffffff8178298d<+13>: 4155 push %r13
0xffffffff8178298f<+15>: 4154 push %r12
0xffffffff81782991<+17>: 53 push %rbx
0xffffffff81782992<+18>: 4889 fb mov %rdi,%rbx
0xffffffff81782995<+21>: 4883 ec 60 sub $0x60,%rsp
crash>
(gdb) disass /r tcp_v4_rcv #vmlinux中原始文件反汇编
Dump of assembler code forfunction tcp_v4_rcv:
0xffffffff81782980<+0>: e8 ab 9f0a00 callq 0xffffffff8182c930<__fentry__>
0xffffffff81782985<+5>:55 push %rbp
0xffffffff81782986<+6>:4889 e5 mov %rsp,%rbp
0xffffffff81782989<+9>:4157 push %r15
0xffffffff8178298b<+11>:4156 push %r14
0xffffffff8178298d<+13>:4155 push %r13
0xffffffff8178298f<+15>:4154 push %r12
0xffffffff81782991<+17>:53 push %rbx
0xffffffff81782992<+18>:4889 fb mov %rdi,%rbx
0xffffffff81782995<+21>:4883 ec 60 sub $0x60,%rsp
0xffffffff81782999<+25>: f6 879000000007 testb $0x7,0x90(%rdi)
0xffffffff817829a0<+32>:7556 jne 0xffffffff817829f8<tcp_v4_rcv+120>
crash> gdb disass /r jprobe_return
Dump of assembler code forfunction jprobe_return:
0xffffffff8105dcc0<+0>: 6666666690 data32 data32 data32 xchg %ax,%ax
0xffffffff8105dcc5<+5>: 55 push %rbp
0xffffffff8105dcc6<+6>: 48 c7 c0 a0 d7 0000 mov $0xd7a0,%rax
0xffffffff8105dccd<+13>: 4889 e5 mov %rsp,%rbp
0xffffffff8105dcd0<+16>: 53 push %rbx
0xffffffff8105dcd1<+17>: 65480305 af c4 fa 7e add %gs:0x7efac4af(%rip),%rax # 0xa188
0xffffffff8105dcd9<+25>: 488b5818 mov 0x18(%rax),%rbx
0xffffffff8105dcdd<+29>: 4887 dc xchg %rbx,%rsp
0xffffffff8105dce0<+32>: cc int3
0xffffffff8105dce1<+33>: 90 nop
0xffffffff8105dce2<+34>: 5b pop %rbx
0xffffffff8105dce3<+35>: 5d pop %rbp
0xffffffff8105dce4<+36>: c3 retq
End of assembler dump.
对tcp_ack中0xffffffff817748bf位置进行kprobe前后对比
通过/proc/kallsyms查看的文件类型对应如下(./scripts/mksysmap):
# The second row specify the type of the symbol:
# A = Absolute
# B = Uninitialised data (.bss)
# C = Common symbol
# D = Initialised data
# G = Initialised data for small objects
# I = Indirect reference to another symbol
# N = Debugging symbol
# R = Read only
# S = Uninitialised data for small objects
# T = Text code symbol
# U = Undefined symbol
# V = Weak symbol
# W = Weak symbol
# Corresponding small letters are local symbols
# For System.map filter away:
# a - local absolute symbols
# U - undefined global symbols
# N - debugging symbols
# w - local weak symbols
__kstrtab节(保存符号名)、__ksymtab节(所有模块可使用的符号地址)和__ksymtab_gpl节(GPL兼容许可证下发布的模块可以使用的符号地址,其他的未找到
cat /proc/kallsyms | cut -d " "-f 2| sort -u //查看文件类型
cat /proc/kallsyms | awk '$2=="a" {print $2 " " $3}' //查看某个文件类型对应的符号