测来测去21:在ftrace中拿到event的user-space stack trace

问题

在开启了ftrace中的一些事件之后,可以用function_graph的trace拿到在内核态的callstack。但有些时候我们希望能拿到用户态程序的callstack,这样我们就能知道是那些方法触发了某一事件,或者我们直接希望uprobe的事件发生时,能够看到该事件对应的callstack,也会是一个很有价值的信息。

阅读文档

本来的计划是,搞一个什么ftrace callback的内核模块,模块里面调用一些save_stack_trace_user()这类的方法,但是感觉虽然理论上行得通,但是实际上系统里敢让你塞一个内核模块进去的企业太少,所以暂时先放弃这个方案。

然后自然是网上搜索了一下,结果就在ftrace的官方文档里发现了这个:

userstacktrace
This option changes the trace. It records a stacktrace of the current user space thread after each trace event.

并且只需要echo userstacktrace > trace_options一下就好了,写一个简单的用户态程序测试一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

static void
inner_func_2(void)
{
printf("This is inner func 2\n");
}

static void
inner_func(void)
{
printf("This is inner func\n");
inner_func_2();
}

static void
print_curr_state_one(void)
{
printf("This is the print current state one function\n");
inner_func();
}

static void
print_curr_state_two(void)
{
printf("This is the print current state two function\n");
}


int main() {
while(1) {
print_curr_state_one();
sleep(1);
print_curr_state_two();
}
}

加个uprobe,看看效果:

echo 'p:inner2 /root/test/uprobe/uprobe:0x55d' >> /sys/kernel/debug/tracing/uprobe_events

1
2
3
4
5
6
7
8
9
10
11
12

[root@server-P1 tracing]# cat trace | tail
=> <00000000004005b0>
=> <00007f30b84dd445>
<...>-173862 [021] d... 4769407.922362: inner2: (0x40055d)
<...>-173862 [021] d... 4769407.922367: <stack trace>
=> retint_signal
<...>-173862 [021] d... 4769407.922367: <user stack trace>
=> <000000000040055d>
=> <0000000000400595>
=> <00000000004005b0>
=> <00007f30b84dd445>

摔,只能看到hex地址嘛。

继续搜一下,在这篇狗哥的文章里有提到:

The output has the raw hex addresses. If this is too much of a nuisance, then try tracing this using perf_events which should automate the translation.

然而他并没有说怎么用perf_event

自己用perf probe的形式定义了这个uprobe:

perf probe -x ./uprobe 'inner_func_2'

Record一下:

perf record -e probe_uprobe:inner_func_2 -aR -g sleep 10

最后看一下结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

[root@server-P1 uprobe]# perf script
uprobe 178595 [021] 4771386.748810: probe_uprobe:inner_func_2: (40055d)
55d inner_func_2 (/root/test/uprobe/uprobe)
595 print_curr_state_one (/root/test/uprobe/uprobe)
5b0 main (/root/test/uprobe/uprobe)
22445 __libc_start_main (/usr/lib64/libc-2.17.so)

uprobe 178595 [021] 4771387.748964: probe_uprobe:inner_func_2: (40055d)
55d inner_func_2 (/root/test/uprobe/uprobe)
595 print_curr_state_one (/root/test/uprobe/uprobe)
5b0 main (/root/test/uprobe/uprobe)
22445 __libc_start_main (/usr/lib64/libc-2.17.so)

uprobe 178595 [021] 4771388.749118: probe_uprobe:inner_func_2: (40055d)
55d inner_func_2 (/root/test/uprobe/uprobe)
595 print_curr_state_one (/root/test/uprobe/uprobe)
5b0 main (/root/test/uprobe/uprobe)
22445 __libc_start_main (/usr/lib64/libc-2.17.so)

但是我后来又去关闭了userstacktrace选项,结果还是能用,呃。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero