@@ -164,6 +164,7 @@ Usage:
164164 --monitor enable 'monitor' mode
165165 --drop-stack print the kernel function call stack of kfree_skb
166166 --min-latency the minial time to live of the skb
167+ --trace-stack print call stack for traces or group
167168
168169 -v show log information
169170 --debug show debug information
@@ -187,8 +188,9 @@ Usage:
187188- ` monitor` :启用监控模式。一种轻量化的实时监控系统中网络异常的模式(对内核版本有一定要求)。
188189- ` hooks` :结合netfilter做的适配,详见下文
189190- ` drop` :进行系统丢包监控,取代原先的` droptrace`
190- - ` drop-stack` : 打印kfree_skb内核函数的调用堆栈
191+ - ` drop-stack` : 打印kfree_skb内核函数的调用堆栈,等价于 ` --trace-stack kfree_skb `
191192- ` min-latency` :根据报文的寿命进行过滤,仅打印处理时长超过该值的报文,单位为ms。该参数仅在默认和` diag` 模式下可用。
193+ - ` trace-stack` :指定需要进行堆栈打印的内核函数,可以指定多个,用“,”分隔。出于性能考虑,启用堆栈打印的内核函数不能超过16个。
192194
193195下面我们首先来看一下默认模式下的工具使用方法。
194196
@@ -351,6 +353,76 @@ begin trace...
351353[66.740110] [consume_skb ] ICMP: 192.168.122.8 -> 192.168.122.1 ping reply, seq: 1, id: 32535
352354` ` `
353355
356+ # ### 3.1.6 堆栈打印
357+
358+ 可以通过` --trace-stack` 来指定需要进行内核堆栈打印的` traces` ,使用方式与` --trace` 完全一致。出于性能的考虑,目前启用堆栈打印的内核函数不能超过16个。基本用法:
359+
360+ ` ` ` shell
361+ $ sudo ./nettrace -p icmp --trace-stack consume_skb,icmp_rcv
362+ begin trace...
363+ ***************** ffff88882cafd200,ffff88882cafdc00 ***************
364+ [2846531.810609] [nf_hook_slow ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956 *ipv4 in chain: OUTPUT*
365+ [2846531.810612] [ip_output ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
366+ [2846531.810613] [nf_hook_slow ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956 *ipv4 in chain: POST_ROUTING*
367+ [2846531.810615] [ip_finish_output ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
368+ [2846531.810617] [ip_finish_output2 ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
369+ [2846531.810619] [__dev_queue_xmit ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
370+ [2846531.810621] [dev_hard_start_xmit ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956 *skb is successfully sent to the NIC driver*
371+ [2846531.810623] [enqueue_to_backlog ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
372+ [2846531.810630] [__netif_receive_skb_core.constprop.0] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
373+ [2846531.810632] [ip_rcv ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
374+ [2846531.810634] [ip_rcv_core ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
375+ [2846531.810635] [nf_hook_slow ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956 *ipv4 in chain: PRE_ROUTING*
376+ [2846531.810637] [ip_local_deliver ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
377+ [2846531.810639] [nf_hook_slow ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956 *ipv4 in chain: INPUT*
378+ [2846531.810640] [nft_do_chain ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956 *iptables table:filter, chain:INPUT*
379+ [2846531.810642] [ip_local_deliver_finish] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
380+ [2846531.810644] [skb_clone ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
381+ [2846531.810649] [icmp_rcv ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
382+ Call Stack:
383+ -> icmp_rcv+0x1
384+ -> ip_local_deliver_finish+0x7f
385+ -> ip_local_deliver+0xea
386+ -> ip_rcv+0x16d
387+ -> __netif_receive_skb_one_core+0x89
388+ -> process_backlog+0xa9
389+ -> __napi_poll+0x2e
390+ -> net_rx_action+0x28f
391+ -> __do_softirq+0xfb
392+ -> do_softirq+0xa7
393+ -> __local_bh_enable_ip+0x79
394+ -> ip_finish_output2+0x170
395+ -> __ip_finish_output+0xae
396+ -> ip_finish_output+0x36
397+ -> ip_output+0x73
398+ -> ip_push_pending_frames+0xab
399+ -> raw_sendmsg+0x651
400+ -> inet_sendmsg+0x6e
401+ -> sock_sendmsg+0x60
402+ -> __sys_sendto+0x10a
403+ -> __x64_sys_sendto+0x24
404+ -> do_syscall_64+0x3f
405+ -> entry_SYSCALL_64_after_hwframe+0x72
406+
407+ [2846531.810651] [ping_rcv ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
408+ [2846531.810653] [ping_lookup.isra.0 ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
409+ [2846531.810654] [kfree_skb ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
410+ [2846531.810659] [consume_skb ] ICMP: 127.0.0.1 -> 127.0.0.1 ping reply, seq: 3, id: 51956
411+ Call Stack:
412+ -> consume_skb+0xb8
413+ -> consume_skb+0xb8
414+ -> skb_free_datagram+0x11
415+ -> raw_recvmsg+0xb2
416+ -> inet_recvmsg+0x11d
417+ -> sock_recvmsg+0x6e
418+ -> ____sys_recvmsg+0x90
419+ -> ___sys_recvmsg+0x7c
420+ -> __sys_recvmsg+0x60
421+ -> __x64_sys_recvmsg+0x1d
422+ -> do_syscall_64+0x3f
423+ -> entry_SYSCALL_64_after_hwframe+0x72
424+ ` ` `
425+
354426# ## 3.2 诊断模式
355427
356428使用方式与上面的一致,加个` diag` 参数即可使用诊断模式。上文的生命周期模式对于使用者的要求比较高,需要了解内核协议栈各个函数的用法、返回值的意义等,易用性较差。诊断模式是在生命周期模式的基础上,提供了更加丰富的信息,使得没有网络开发经验的人也可进行复杂网络问题的定位和分析。
0 commit comments