我正在使用 ftrace 跟蹤內核 5.4.20 中的 ip_local_out()。
我確定 ip_local_out() 可用于跟蹤:
/sys/kernel/debug/tracing # cat available_filter_functions |grep ip_local_out
__ip_local_out
ip_local_out
于是我設定了ftrace并開始跟蹤如下:
/sys/kernel/debug/tracing # echo ip_local_out > set_graph_function
/sys/kernel/debug/tracing # echo function_graph > current_tracer
/sys/kernel/debug/tracing # echo 3 > max_graph_depth
/sys/kernel/debug/tracing # cat trace_pipe
然后我用 ICMP ping 與這個內核通信。但是,ftrace 沒有輸出。
我懷疑 ip_local_out() 根本沒有被呼叫,所以我在 ip_local_out() 中添加 printk() 并重新編譯:
int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
{
int err;
//crezov debug
printk("<%s:%d> crezov debug: ip_local_out() is called!\n", __FUNCTION__, __LINE__);
err = __ip_local_out(net, sk, skb);
if (likely(err == 1))
err = dst_output(net, sk, skb);
return err;
}
EXPORT_SYMBOL_GPL(ip_local_out);
同樣的配置,同樣的ICMP ping,重新編譯的內核可以輸出如下,可以看出呼叫了ip_local_out(),另外還可以追蹤到ip_local_out!
[ 43.219817] <ip_local_out:127> crezov debug: ip_local_out() is called!
0) | ip_local_out() {
0) ==========> |
0) | smp_irq_work_interrupt() {
0) 44.167 us | irq_enter();
0) 98.824 us | __wake_up();
0) 11.717 us | irq_exit();
0) ! 567.096 us | }
0) <========== |
0) | printk() {
0) # 9894.629 us | vprintk_func();
0) # 9941.234 us | }
0) | __ip_local_out() {
0) 52.389 us | ip_send_check();
0) ! 135.433 us | }
0) | ip_output() {
0) ! 649.046 us | ip_finish_output();
0) ! 716.535 us | }
0) * 12446.31 us | }
但是,一旦我從 ip_local_out 中洗掉 printk() 并重新編譯,就無法再次跟蹤 ip_local_out()。
我錯過了什么?請幫忙。
uj5u.com熱心網友回復:
經過一周的實驗,我終于找到了原因:ip_local_out() 被自動行內了!當我像這樣使用 noinline 屬性時:
noinline int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
{
int err;
err = __ip_local_out(net, sk, skb);
if (likely(err == 1))
err = dst_output(net, sk, skb);
return err;
}
EXPORT_SYMBOL_GPL(ip_local_out);
ftrace 可以捕獲 ip_local_out()。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/476987.html
