[小技巧] dump_stack()
来源:互联网 发布:狸窝视频编辑软件 编辑:程序博客网 时间:2024/06/05 15:24
本文转载至:http://jason-work-note.blogspot.jp/2012/03/dumpstack.html
How can it works for you
當你想知道在kernel裡面某個function是如何一層一層的被呼叫到的,你只要在該funciton裡加上一行 "dump_stack()",
當程式跑到那一行,就會把整個code stack印出來
How to use
以下為使用的範例,例如我想知道wifi driver裡面的wifi_set_cardetect是怎樣被呼叫的,就可以在該funciton內加一行dump_stack()。
----------------------------------------------------------kernel/drivers/net/wireless/bcm4329/dhd_linux.cint wifi_set_carddetect(int on){ printk("%s = %d\n", __FUNCTION__, on);<span style="color:#ff0000;"><span style="white-space:pre"></span>dump_stack();</span>#ifdef CONFIG_WIFI_CONTROL_FUNC if (wifi_control_data && wifi_control_data->set_carddetect) { wifi_control_data->set_carddetect(on); }#endif return 0;}----------------------------------------------------------
執行結果如下:
------------------------------------------------------------------------------------<4>[ 861.317167] wifi_set_carddetect = 1<4>[ 861.320835] [<c0047a04>] (unwind_backtrace+0x0/0xf0) from [<bf003b68>] (wifi_set_carddetect+0x1c/0x54 [bcm4329])<4>[ 861.331281] [<bf003b68>] (wifi_set_carddetect+0x1c/0x54 [bcm4329]) from [<bf003c10>] (wifi_probe+0x34/0x50 [bcm4329])<4>[ 861.342126] [<bf003c10>] (wifi_probe+0x34/0x50 [bcm4329]) from [<c027ac68>] (platform_drv_probe+0x18/0x1c)<4>[ 861.351949] [<c027ac68>] (platform_drv_probe+0x18/0x1c) from [<c0279ac8>] (driver_probe_device+0xc8/0x184)<4>[ 861.361767] [<c0279ac8>] (driver_probe_device+0xc8/0x184) from [<c0279be4>] (__driver_attach+0x60/0x84)<4>[ 861.371318] [<c0279be4>] (__driver_attach+0x60/0x84) from [<c02792fc>] (bus_for_each_dev+0x48/0x84)<4>[ 861.380523] [<c02792fc>] (bus_for_each_dev+0x48/0x84) from [<c0278c50>] (bus_add_driver+0x9c/0x20c)<4>[ 861.389655] [<c0278c50>] (bus_add_driver+0x9c/0x20c) from [<c027a1dc>] (driver_register+0xa8/0x138)<4>[ 861.398851] [<c027a1dc>] (driver_register+0xa8/0x138) from [<bf03408c>] (dhd_module_init+0x8c/0x1cc [bcm4329])<4>[ 861.409092] [<bf03408c>] (dhd_module_init+0x8c/0x1cc [bcm4329]) from [<c003c588>] (do_one_initcall+0x94/0x164)<4>[ 861.419271] [<c003c588>] (do_one_initcall+0x94/0x164) from [<c00ac7d4>] (sys_init_module+0x90/0x1ac)<4>[ 861.428567] [<c00ac7d4>] (sys_init_module+0x90/0x1ac) from [<c0041ca0>] (ret_fast_syscall+0x0/0x30)-------------------------------------------------------------------------------------
How dump_stack works
dump_stack定義在kernel/arch/arm/kernel/traps.c,程式流程為
dump_stack() --> dump_backtrace() -->unwind_backtrace() --> dump_backtrace_entry()
其中在 unwind_backtrace() 中會有一個 while loop,裡面透過 unwind_frame() 靠著當下的 program counter (r15) 和 link register (r14) 一層一層的往上找,每往上找一層就呼叫
dump_backtrace_entry() 把目前的位置印出來,打印出來的 message 就像這樣:
[<c0047a04>] (unwind_backtrace+0x0/0xf0) from [<bf003b68>] (wifi_set_carddetect+0x1c/0x54 [bcm4329])
PS:
1. link register : 當function A的某一行呼叫funciton B時,ARM會利用這個register紀錄funciton A下一行的位址,當funciton B跑完時,CPU就知道接下來要跳回哪裡繼續執行下去。
reference [3] [4]有ARM register的簡介。
2. unwind_frame() 裡面具體的作法可以參考[5][6] ,Stack unwinding 似乎是ARM support的一種功能,詳細請參考[6]中的pdf
Reference
[1] 簡單實現 dump_stack
[2] Enabling Stack Dumping in Linux Kernel
[3] ARM Register introduction
[4] armregister.jpg
[5] unwind.c in kernel
[6] Exception Handling ABI for the ARM Architecture
0 0
- [小技巧] dump_stack()
- linux内核调试技巧 dump_stack()
- dump_stack()
- dump_stack
- dump_stack( )
- linux内核调试技巧之一 dump_stack
- linux内核调试技巧之一 dump_stack
- linux内核调试技巧之一 dump_stack
- linux内核调试技巧之一 dump_stack
- linux内核调试技巧二:dump_stack
- dump_stack()使用方法
- linux dump_stack
- 小技巧
- 小技巧
- 小技巧
- 小技巧
- 小技巧
- 小技巧
- java关键字Transient
- 聚类算法实践——PCCA、SOM、Affinity Propagation
- 善变的“范围”
- Eclipse自动补全功能轻松设置
- Java UDP网络编程 - 最简单示例
- [小技巧] dump_stack()
- bytebuffer 与 byte数组 转化
- NetworkInterface的使用
- jqGrid学习笔记
- 关于在Makefile文件中使用awk/sed需注意的
- js中验证用的一些正则表达式的积累
- sql之行列转换备份
- 南昌精神病
- 一个帖子学会Android开发四大组件