linux跟踪命令工具 linux 连接跟踪( 二 )


读取跟踪文件以查看输出:
# cat /sys/kernel/debug/tracing/trac\n# tracer: no\n\n# entries-in-buffer/entries-written: 8/8\n#P:\n\n# _-----= irqs-of\n# / _----= need-resche\n# | / _---= hardirq/softir\n# || / _--= preempt-dept\n# ||| / dela\n# TASK-PID CP\n# |||| TIMESTAMP FUNCTION# | | | |||| | |
我们可以看到哪个CPU完成了什么任务 , 什么时候执行了探测指令 。
返回探针也可以插入指令 。当返回该指令的函数时,将记录一个条目:
# echo 0/sys/kernel/debug/tracing/events/uprobes/enabl\n# echo 'r:func_2_exit test:0x620'/sys/kernel/debug/tracing/uprobe_event\n# echo 'r:func_1_exit test:0x644'/sys/kernel/debug/tracing/uprobe_event\n# echo 1/sys/kernel/debug/tracing/events/uprobes/enable
这里我们使用r而不是p,所有其他参数是相同的 。请注意,如果要插入新的探测点,需要禁用uprobe事件:
test-3009 [002] .... 4813.852674: func_1_entry: (0x400644)
上面的日志表明 , func_1返回到地址0x4006b0,时间戳为4813.852691 。
# echo 0/sys/kernel/debug/tracing/events/uprobes/enabl\n# echo 'p:func_2_entry test:0x630'/sys/kernel/debug/tracing/uprobe_events count=%x\n# echo 1/sys/kernel/debug/tracing/events/uprobes/enabl\n# echo/sys/kernel/debug/tracing/trace# ./test
当执行偏移量0x630的指令时,将打印ARM64 x1寄存器的值作为count = 。
输出如下所示:
test-3095 [003] .... 7918.629728: func_2_entry: (0x400630) count=0x1
使用perf插入uprobe
找到需要插入探针的指令或功能的偏移量很麻烦 , 而且需要知道分配给局部变量的CPU寄存器的名称更为复杂 。perf是一个有用的工具 , 用于帮助引导探针插入源代码中 。
除了perf,还有一些其他工具 , 如SystemTap,DTrace和LTTng,可用于内核和用户空间跟踪;然而,perf与内核配合完美,所以它受到内核程序员的青睐 。
# gcc -g -o test test.c# perf probe -x ./test func_2_entry=func_\n# perf probe -x ./test func_2_exit=func_2%retur\n# perf probe -x ./test test_15=test.c:1\n# perf probe -x ./test test_25=test.c:25 numbe\n# perf record -e probe_test:func_2_entry -e\nprobe_test:func_2_exit -e probe_test:test_15\n-e probe_test:test_25 ./test
如上所示,程序员可以将探针点直接插入函数start和return,源文件的特定行号等 。可以获取打印的局部变量,并拥有许多其他选项,例如调用函数的所有实例 。perf探针用于创建探针点事件,那么在执行./testexecutable时,可以使用perf记录来探测这些事件 。当创建一个perf探测点时,可以使用其他录音选项,例如perf stat,可以拥有许多后期分析选项,如perf脚本或perf报告 。
使用perf脚本,上面的例子输出如下:
# perf script
使用kprobe跟踪内核空间
与uprobe一样 , 可以使用sysfs接口或perf工具将kprobe跟踪点插入到内核代码中 。
使用sysfs接口插入kprobe
程序员可以在/proc/kallsyms中的大多数符号中插入kprobe;其他符号已被列入内核的黑名单 。还有一些与kprobe插入不兼容的符号,比如kprobe_events文件中的kprobe插入将导致写入错误 。也可以在符号基础的某个偏移处插入探针 , 像uprobe一样,可以使用kretprobe跟踪函数的返回,局部变量的值也可以打印在跟踪输出中 。
以下是如何做:
; disable all events, just to insure that we see only kprobe output in trace\n# echo 0/sys/kernel/debug/tracing/events/enable; disable kprobe events until probe points are inseted\n# echo 0/sys/kernel/debug/tracing/events/kprobes/enable; clear out all the events from kprobe_events\n to insure that we see output for; only those for which we have enabled
[root@pratyush ~\n# more /sys/kernel/debug/tracing/trace# tracer: no\n\n# entries-in-buffer/entries-written: 9037/9037\n#P:8\n# _-----= irqs-of\n# / _----= need-resche\n# | / _---= hardirq/softirq#\n|| / _--= preempt-depth#\n ||| / delay# TASK-PID CPU#\n |||| TIMESTAMP FUNCTION#\n | | | |||| | |

推荐阅读