inline的語意有時候有點模糊,其實主要因該是在最佳化的時候的解釋方式,compiler會試著將inline直接展開,也就是類似MACRO,好處是不會需要處理stack frame,這表示效能將會提升,同時大多數的書籍建議inline不宜過大,這樣才不會導致text區段太過肥大,聰明一點的compiler也會自行將肥大的inline變成function,所以這才導致了inline的語意有些模糊。同時,inline也可能因為展開的關係從symbol table移除,這樣一來在gdb不能使用b function_name,必須直接使用行號,這樣的小問題。
最佳化的技巧很多,有的compiler會將function的parameter直接放到register上面,這樣可以加速處理速度同時節省stack frame,當然會面臨到參數個數跟register個數的問題,其實有時候還會引發concurrency的問題,比方說,在平行處理的時候,最佳化有可能因為將變數對應到register,導致本來用來做critical section判斷的variable,但是兩個thread擁有不同的register,所以程式怎樣看都沒問題,但是執行起來就有問題,這樣的bug非常難以找到
2013年1月20日 星期日
2013年1月17日 星期四
C++的mangle與debug
其實稍微懂得loader的人都知道這個機制,也就是避免名稱空間碰撞的機制,用於C++也可以避免兩個不同class但是有相同的member function名稱碰撞的問題,但設這樣來說,在gdb內很喜歡用的b function_name如何使用?
先把namgle後的名稱找出來,使用之前nm可以列出,如果還不確定,可以使用c++filt轉出prototype,c++filt之所以可以反轉,乃是因為namgle是有規則的(好像有點廢話)
比方說code如下
class foo{
int a,b;
public:
void func(int x,int y);
};
void foo::func(int x,int y){
a=x;
b=y+2;
}
int main(void){
foo f1, f2;
printf("f1:%p, f2: %p\n",&f1,&f2);
f1.func(5,1);
f2.func(-4,2);
return 0;
}
找出foo這個function在被namgle之後的名稱可以用
nm name | grep foo | c++filt
或者
nm -C name | grep foo
可以看到名稱為_ZN3foo4funcEii
進入gdb,這下子就可以用b *_ZN3foo4funcEii來設定break point了,跟之執行run
停止後gdb很好心的印出了function call的prototype,會發現多了一個this,這也是C++的object pointer來源
先把namgle後的名稱找出來,使用之前nm可以列出,如果還不確定,可以使用c++filt轉出prototype,c++filt之所以可以反轉,乃是因為namgle是有規則的(好像有點廢話)
比方說code如下
class foo{
int a,b;
public:
void func(int x,int y);
};
void foo::func(int x,int y){
a=x;
b=y+2;
}
int main(void){
foo f1, f2;
printf("f1:%p, f2: %p\n",&f1,&f2);
f1.func(5,1);
f2.func(-4,2);
return 0;
}
找出foo這個function在被namgle之後的名稱可以用
nm name | grep foo | c++filt
或者
nm -C name | grep foo
可以看到名稱為_ZN3foo4funcEii
進入gdb,這下子就可以用b *_ZN3foo4funcEii來設定break point了,跟之執行run
停止後gdb很好心的印出了function call的prototype,會發現多了一個this,這也是C++的object pointer來源
2013年1月16日 星期三
GDB指令筆記
留一下備忘錄
commands #breakpoint
...
...
end
在中斷點中斷時執行的指令
define #command
...
...
end
document
...
...
end
可以用來設定指令,比方說
define li
x/10i $pc
end
document li
list machine instruction
end
help li則是印出指令說明
使用core file當作gdb的輸出的時候,必須加上-s exec_file或者在進入gdb後file exec_file,才可以載入symbol table
attach pid將某個process加入gdb模式,使用detach離開
參考資料:
http://www.study-area.org/cyril/opentools/opentools/debug.html
- break/b : 設定break point,break main, break 10, break test.C:10
- run/r : 執行
- backtrace/bt : 列印出stack frame, bt 10, bt full 10
- print/p : 列印出變數數值
- info register : 列印出regiseter內容
- next/n : step by step
- step/s : step into
- continue/c : 繼續執行
- watch expression : 監視變數
- delete # : 刪除break point或者 watch point
- set variable var=expression : 設定變數內容
- generate-core-file
- info proc : 印出在/proc內容
- break #breakpoint if condition : 設定中斷點條件
- condition #breakpoint condtion : 為中斷點設定條件
- condition #breakpoint : 取消中斷點的條件
- clear : 清除所有中斷點
- disable : 暫停使用所有中斷點
- enable : 啟用中斷點
- info b : 列出所有中斷點
- set history/show history : 顯示出使用過的指令
- set history save/show history save : 儲存使用過的指令
- source file_name : 載入設定檔案
commands #breakpoint
...
...
end
在中斷點中斷時執行的指令
define #command
...
...
end
document
...
...
end
可以用來設定指令,比方說
define li
x/10i $pc
end
document li
list machine instruction
end
help li則是印出指令說明
使用core file當作gdb的輸出的時候,必須加上-s exec_file或者在進入gdb後file exec_file,才可以載入symbol table
attach pid將某個process加入gdb模式,使用detach離開
參考資料:
http://www.study-area.org/cyril/opentools/opentools/debug.html
訂閱:
文章 (Atom)