当前位置:网站首页>dump_stack ()
dump_stack ()
2022-08-11 00:49:00 【Li-Yongjun】
活动地址:CSDN21天学习挑战赛
函数调用关系
If you want to understand a function call in the engineering relationship,Can start from a program entrance analysis,Will call le clear layers.This way to deal with small engineering can work,Deal with Linux kernel This huge and complicated engineering,Is very hard.One of the most significant difficulty is,Conditional branch too much,Relationship between the function call is complex,Analysis to big.
那么,有没有一种工具,To help us automatic analysis function call relationship,Instead we personally one layer at a time.答案是有的,那就是 dump_stack().
dump_stack()
当你想知道 func_a() Function is how to be invoked by the superior themselves,就可以在 func_a() 中添加 dumo_stack().
For example, I want to analyze the kernel network protocol stack TX 方向的 flow,就可以在 __netdev_start_xmit() 函数(该函数是 TX The direction of the kernel network protocol stack and drive the join,参考这里)里面添加 dumo_stack().
注意,dump_stack() Can only be used for the kernel space.
示例
我将 dumo_stack() 添加在了 netdev_start_xmit(),效果一样,netdev_start_xmit() 紧接着就会调用 __netdev_start_xmit()
static inline netdev_tx_t netdev_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq, bool more)
{
const struct net_device_ops *ops = dev->netdev_ops;
int rc;
printk("[xxx-dump] in %s, line = %d, dump start\n", __func__, __LINE__);
dump_stack();
printk("[xxx-dump] in %s, line = %d, dump end\n", __func__, __LINE__);
rc = __netdev_start_xmit(ops, skb, dev, more);
if (rc == NETDEV_TX_OK)
txq_trans_update(txq);
return rc;
}
重新编译内核,运行
[xxx-dump] in netdev_start_xmit, line = 3623, dump start
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.1.15 #9
Hardware name: Freescale i.MX6 Ultralite (Device Tree)
[<80015ed4>] (unwind_backtrace) from [<80012794>] (show_stack+0x10/0x14)
[<80012794>] (show_stack) from [<8068ca34>] (dump_stack+0x80/0xc8)
[<8068ca34>] (dump_stack) from [<80549f74>] (dev_hard_start_xmit+0x228/0x35c)
[<80549f74>] (dev_hard_start_xmit) from [<80562fe4>] (sch_direct_xmit+0xc4/0x1f4)
[<80562fe4>] (sch_direct_xmit) from [<8054a2d8>] (__dev_queue_xmit+0x230/0x54c)
[<8054a2d8>] (__dev_queue_xmit) from [<805c92ac>] (ip6_finish_output2+0x164/0x608)
[<805c92ac>] (ip6_finish_output2) from [<805cd254>] (ip6_output+0xb4/0x198)
[<805cd254>] (ip6_output) from [<805e0e38>] (ndisc_send_skb+0x324/0x3a0)
[<805e0e38>] (ndisc_send_skb) from [<805e1a74>] (ndisc_send_ns+0xe0/0x158)
[<805e1a74>] (ndisc_send_ns) from [<805e1be8>] (ndisc_solicit+0xfc/0x124)
[<805e1be8>] (ndisc_solicit) from [<80551bb0>] (neigh_probe+0x4c/0x7c)
[<80551bb0>] (neigh_probe) from [<80553be8>] (neigh_timer_handler+0x204/0x28c)
[<80553be8>] (neigh_timer_handler) from [<8007d61c>] (call_timer_fn+0x24/0x9c)
[<8007d61c>] (call_timer_fn) from [<8007dbc8>] (run_timer_softirq+0x1b8/0x250)
[<8007dbc8>] (run_timer_softirq) from [<8003b3e4>] (__do_softirq+0xf0/0x228)
[<8003b3e4>] (__do_softirq) from [<8003b7ac>] (irq_exit+0xb0/0xfc)
[<8003b7ac>] (irq_exit) from [<8006f61c>] (__handle_domain_irq+0x70/0xe8)
[<8006f61c>] (__handle_domain_irq) from [<80009440>] (gic_handle_irq+0x20/0x60)
[<80009440>] (gic_handle_irq) from [<80013240>] (__irq_svc+0x40/0x74)
Exception stack(0x80975f30 to 0x80975f78)
5f20: 80975f78 00000009 0a73caeb 0000000b
5f40: 0a4c8d58 0000000b 00000002 97b91dd8 0a73caeb 0000000b 80971740 00000001
5f60: 00000017 80975f78 a6aaaaab 804a6e6c 20010013 ffffffff
[<80013240>] (__irq_svc) from [<804a6e6c>] (cpuidle_enter_state+0xcc/0x1f8)
[<804a6e6c>] (cpuidle_enter_state) from [<800671ac>] (cpu_startup_entry+0x1c0/0x324)
[<800671ac>] (cpu_startup_entry) from [<8090fbec>] (start_kernel+0x338/0x3a4)
[xxx-dump] in netdev_start_xmit, line = 3625, dump end
A function call relationship moments came out,从 start_kernel() 一直到 netdev_start_xmit(),And then according to the code in this call relations,就很顺畅了.If direct analysis code,It is easy to analyze fault,And the relationship between the call to do auxiliary,就非常顺利、The correct and efficient.
The above call relationship,The first half because of involving interruption,Is not normal function call,Analysis it still will be a little difficult.不过反过来想,如果没有 dump_stack() 加持,If we don't think cpuidle_enter_state() 和 __irq_svc() Actually related to,If only sat looking at the code to think,I'm afraid it will average computer-virus.
技巧
另外,The example above function call relationship second half,在分析时发现,ip6_output() 里面根本没有 ip6_finish_output2(),这是怎么回事呢?
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net_device *dev = skb_dst(skb)->dev;
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
if (unlikely(idev->cnf.disable_ipv6)) {
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
kfree_skb(skb);
return 0;
}
return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
net, sk, skb, NULL, dev,
ip6_finish_output,
!(IP6CB(skb)->flags & IP6SKB_REROUTED));
}
那是因为,The compiler to compile code is optimized to improve the operation efficiency and compact degree of,But that would not learn to debug the kernel friendly.因此,When we debug kernel,Suggest the closures optimization.
- Optimization level from O2 改为 O1
Makefile
# KBUILD_CFLAGS += -O2
KBUILD_CFLAGS += -O1
- Don't put only a called function automatically into place inline 函数
# CONFIG_DEBUG_SECTION_MISMATCH=n
CONFIG_DEBUG_SECTION_MISMATCH=y
# We trigger additional mismatches with less inlining
ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
- Manually remove part of the function of inline 修饰符
This compilation again、运行
[xxx-dump] in netdev_start_xmit, line = 3623, dump start
CPU: 0 PID: 541 Comm: connmand Not tainted 4.1.15 #10
Hardware name: Freescale i.MX6 Ultralite (Device Tree)
[<80016850>] (unwind_backtrace) from [<800130fc>] (show_stack+0x10/0x14)
[<800130fc>] (show_stack) from [<802bb7a0>] (__dump_stack+0x18/0x20)
[<802bb7a0>] (__dump_stack) from [<802bb810>] (dump_stack+0x68/0xb8)
[<802bb810>] (dump_stack) from [<80588830>] (netdev_start_xmit+0x30/0x9c)
[<80588830>] (netdev_start_xmit) from [<8058b67c>] (xmit_one+0x64/0x74)
[<8058b67c>] (xmit_one) from [<8058f2cc>] (dev_hard_start_xmit+0x40/0x90)
[<8058f2cc>] (dev_hard_start_xmit) from [<805aa0bc>] (sch_direct_xmit+0x94/0x208)
[<805aa0bc>] (sch_direct_xmit) from [<8058f540>] (__dev_queue_xmit+0x224/0x4bc)
[<8058f540>] (__dev_queue_xmit) from [<8058f7f8>] (dev_queue_xmit_sk+0x20/0x2c)
[<8058f7f8>] (dev_queue_xmit_sk) from [<806152c8>] (dev_queue_xmit+0x10/0x14)
[<806152c8>] (dev_queue_xmit) from [<80615374>] (neigh_hh_output+0xa8/0xac)
[<80615374>] (neigh_hh_output) from [<806153cc>] (dst_neigh_output+0x54/0x70)
[<806153cc>] (dst_neigh_output) from [<806157f8>] (ip6_finish_output2+0x410/0x540)
[<806157f8>] (ip6_finish_output2) from [<8061962c>] (ip6_finish_output+0x140/0x150)
[<8061962c>] (ip6_finish_output) from [<806197b4>] (ip6_output+0x178/0x194)
[<806197b4>] (ip6_output) from [<8064d2ec>] (ip6_local_out_sk+0x38/0x3c)
[<8064d2ec>] (ip6_local_out_sk) from [<8064d300>] (ip6_local_out+0x10/0x14)
[<8064d300>] (ip6_local_out) from [<80619d18>] (ip6_send_skb+0xc/0x108)
[<80619d18>] (ip6_send_skb) from [<806328ac>] (udp_v6_send_skb+0x280/0x298)
[<806328ac>] (udp_v6_send_skb) from [<80632fa4>] (udpv6_sendmsg+0x618/0xaa0)
[<80632fa4>] (udpv6_sendmsg) from [<805ef7b4>] (inet_sendmsg+0xac/0xc0)
[<805ef7b4>] (inet_sendmsg) from [<805750e8>] (sock_sendmsg+0x14/0x24)
[<805750e8>] (sock_sendmsg) from [<80576c20>] (SyS_sendto+0xb8/0xdc)
[<80576c20>] (SyS_sendto) from [<8000f5a0>] (ret_fast_syscall+0x0/0x3c)
[xxx-dump] in netdev_start_xmit, line = 3625, dump end
可以看到,ip6_output() 先是调用 ip6_finish_output(),Through the function call again ip6_finish_output2(),It's exactly and code.
不过由于 dump_stack() Show the amount of information co., LTD,Call relationship in detail later,The depth is not so deep,你看,This is not from start_kernel() 开始展示.
When we in the concrete debugging,Can not modify the compiler optimizations before,In order to protect the overall depth of the function call,Where analysis can't,To modify the compiler options,The relation between local show detailed call.
总之,有了 dump_stack(),We have more than a magic weapon of analysis code.
能力不行,A magic weapon to gather together.Just like in the journey to the west green cow blame,能力平平,But things are in his hand——Gold ring,Sun wukong's great it is to go to,It is ring artifact.With such a magic weapon,Got to work that is not like a duck to water.
边栏推荐
猜你喜欢
池化技术有多牛?来,告诉你阿里的Druid为啥如此牛逼!
91.(cesium之家)cesium火箭发射模拟
数据分析面试手册《统计篇》
异常:try catch finally throws throw
Shell Text Three Musketeers Sed
In 22 years, the salary of programmers nationwide in January was released, only to know that there are so many with annual salary of more than 400,000?
Lens filter---about day and night dual-pass filter
SAS data processing technology (1)
Why do programming languages have the concept of variable types?
Pagoda Test-Building PHP Online Mock Exam System
随机推荐
apache+PHP+MySQL+word press,安装word press时页面报错?
【pypdf2】合并PDF、旋转、缩放、裁剪、加密解密、添加水印
云原生-FRP内网穿透(详解)使用云服务器将内网集群服务暴露至公网(二)
力扣------用栈操作构建数组
时间戳转换为日期格式、获取当前时间戳
Use mysql statement to operate data table (table)
HW-常见攻击方式和漏洞原理(2)
22/8/9 贪心问题合集
双机热备综合实验(VRRP+OSPF+VTP+NAT+DHCP+PVSTP+单臂路由)
微信小程序自定义navigationBar
postgresql参数意义
数据分析面试手册《SQL篇》
YOLOv5的Tricks | 【Trick12】YOLOv5使用的数据增强方法汇总
编程技巧│selenium 更新 chromedriver 驱动
微信小程序获取当前页面的url和参数
线上突然查询变慢怎么核查
"NIO Cup" 2022 Nioke Summer Multi-School Training Camp 4 ADHK Problem Solving
【爬虫】scrapy创建运行爬虫、解析页面(嵌套url)、自定义中间件(设置UserAgent和代理IP)、自定义管道(保存到mysql)
【redis】发布和订阅消息
二维数组实战项目--------《扫雷游戏》