我有很多想寫的程式,大部分的idea我都真的有用程式寫過了,雖然鳥鳥的.
例如我想要寫一個flickr app,語音命令程式, 紀錄工作日誌的application.
有一個程式我構思了很久,一個可以看到自己內部結構的程式.想像程式可以
像汽車一樣打開它的引擎蓋,打開後你可以看到程式是由哪些零件組成的,
並且可以看到零件之間的相互關係.
然後你可以像改車一樣,把某個零件拔下來,換上一個新的零件,
而蓋上引擎蓋後,程式一樣可以正常運作.
這讓不懂你程式的人,可以藉由打開引擎蓋,換上他從某個管道取得的零件,
達到他要的修改.
如果是我,我就會想要像這樣把程式的引擎蓋打開,享受這種類似改機的樂趣.
2013年11月27日 星期三
2012年5月10日 星期四
[git] set up the local branch to track another remote branch
At first, I have a local code base "A", which I git-clone it from a repo server.
For some reasons, I would like to have another local code base "B", which contains the same things as "A".
I think it would be faster if I clones "A" to "B".
so I do it as follow:
git clone <path_of_A>/.git <path_of_B>
Then I got a code base B which tracks A insteads of tracking the repo sever.
It means that, if I want to sync code base "B" with the repo sever, I have to sync "A" with remote repo first,then sync "B" with "A".
Since I only cares about changes in the repo server, I don't care about changes in "A".
I removed the remote track of "A" and add a remote track of the repo server:
git remote add repo-server git@<IP_of_repo_server>:xxxx/xxx.git
git remote rm origin (origin is correspoing to "A")
Then I makes the local maser branch in "B" to track the repo server.
git branch --ser-upstream master remotes/repo-server/<the_remote_branch_name>
2012年3月19日 星期一
dump_stack()
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.c
int wifi_set_carddetect(int on)
{
printk("%s = %d\n", __FUNCTION__, on);
dump_stack();
#ifdef CONFIG_WIFI_CONTROL_FUNC
if (wifi_control_data && wifi_control_data->set_carddetect) {
wifi_control_data->set_carddetect(on);
}
#endif
return 0;
}
{
printk("%s = %d\n", __FUNCTION__, on);
dump_stack();
#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)
<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
[3] ARM Register introduction
[4] armregister.jpg
[5] unwind.c in kernel
訂閱:
文章 (Atom)