在用kgdb調(diào)試內(nèi)核時(shí),使用s 或n單步執(zhí)行程序時(shí),發(fā)現(xiàn)程序不是按順序運(yùn)行的,有時(shí)莫名其妙的執(zhí)行到前面的語句去了,有時(shí)又執(zhí)行到后面的語句,有時(shí)一次執(zhí)行幾條語句。后來查了下資料。原來這是編譯時(shí)的優(yōu)化問題所導(dǎo)致的。
因?yàn)閮?nèi)核的編譯是使用make命令的,所以要更改優(yōu)化等級(jí)的話,只能修改makefile文件了。
在makefile中,找到CFLAGS 然后在這加上-O0選項(xiàng)即可。
當(dāng)然這個(gè)makefile不好改,子目錄太多。
我發(fā)帖問了一下,呵呵
有說:make CFLAGS="-g -o"
http://topic.csdn.net/u/20110921/20/8043fd93-cbda-4c84-89ad-8f33d4e1e34c.html?seed=594869313&r=75653531#r_75653531
當(dāng)然在gdb中調(diào)試程序時(shí),n或者s單步執(zhí)行時(shí),也可以發(fā)現(xiàn)類似現(xiàn)象。
比如自己可以寫一個(gè)程序,進(jìn)行測試,如:
long.c
#include<stdio.h>
int main(void)
{
int long1();
int i;
for(i=0;i<10;i++)
{
printf("%d\n",i);
long1();
}
return 0;
}
int long1()
{
int *p;
static int a=3;
int b=2;
p=&a;
printf("&p is %d\n",p);
printf("ok\n");
printf("*p is %d\n",*p);
printf("&b is %d\n",&b);
return 1;
}
gcc編譯器下的截圖
gcc long.c -o long -g -O0
然后gdb調(diào)試程序,n或s單步執(zhí)行程序,發(fā)現(xiàn)這時(shí)程序是按順序執(zhí)行的。
然后,改變優(yōu)化等級(jí),即-O0改為-O3:
gcc long.c -o long -g -O3
gdb調(diào)試程序,n或s單步執(zhí)行程序,發(fā)現(xiàn)這時(shí)程序不是按順序執(zhí)行的。有事莫名其妙的執(zhí)行到前面的語句去了。
下面是我從網(wǎng)上找到的。關(guān)于優(yōu)化等級(jí)的說明:
這個(gè)選項(xiàng)控制所有的優(yōu)化等級(jí)。使用優(yōu)化選項(xiàng)會(huì)使編譯過程耗費(fèi)更多的時(shí)間,并且占用更多的內(nèi)存,尤其是在提高優(yōu)化等級(jí)的時(shí)候。
-O設(shè)置一共有五種:-O0、-O1、-O2、-O3和-Os。你只能在/etc/make.conf里面設(shè)置其中的一種。
除了-O0以外,每一個(gè)-O設(shè)置都會(huì)多啟用幾個(gè)選項(xiàng),請查閱gcc手冊的優(yōu)化選項(xiàng)章節(jié),以便了解每個(gè)-O等級(jí)啟用了哪些選項(xiàng)及它們有何作用。
讓我們來逐一考察各個(gè)優(yōu)化等級(jí):
-O0:這個(gè)等級(jí)(字母“O”后面跟個(gè)零)關(guān)閉所有優(yōu)化選項(xiàng),也是CFLAGS或CXXFLAGS中沒有設(shè)置-O等級(jí)時(shí)的默認(rèn)等級(jí)。這樣就不會(huì)優(yōu)化代碼,這通常不是我們想要的。
-O1:這是最基本的優(yōu)化等級(jí)。編譯器會(huì)在不花費(fèi)太多編譯時(shí)間的同時(shí)試圖生成更快更小的代碼。這些優(yōu)化是非常基礎(chǔ)的,但一般這些任務(wù)肯定能順利完成。
-O2:-O1的進(jìn)階。這是推薦的優(yōu)化等級(jí),除非你有特殊的需求。-O2會(huì)比-O1啟用多一些標(biāo)記。設(shè)置了-O2后,編譯器會(huì)試圖提高代碼性能而不會(huì)增大體積和大量占用的編譯時(shí)間。
-O3:這是最高最危險(xiǎn)的優(yōu)化等級(jí)。用這個(gè)選項(xiàng)會(huì)延長編譯代碼的時(shí)間,并且在使用gcc4.x的系統(tǒng)里不應(yīng)全局啟用。自從3.x版本以來gcc的行為已經(jīng)有了極大地改變。在3.x,-O3生成的代碼也只是比-O2快一點(diǎn)點(diǎn)而已,而gcc4.x中還未必更快。用-O3來編譯所有的軟件包將產(chǎn)生更大體積更耗內(nèi)存的二進(jìn)制文件,大大增加編譯失敗的機(jī)會(huì)或不可預(yù)知的程序行為(包括錯(cuò)誤)。這樣做將得不償失,記住過猶不及。在gcc 4.x.中使用-O3是不推薦的。
-Os:這個(gè)等級(jí)用來優(yōu)化代碼尺寸。其中啟用了-O2中不會(huì)增加磁盤空間占用的代碼生成選項(xiàng)。這對(duì)于磁盤空間極其緊張或者CPU緩存較小的機(jī)器非常有用。但也可能產(chǎn)生些許問題,因此軟件樹中的大部分ebuild都過濾掉這個(gè)等級(jí)的優(yōu)化。使用-Os是不推薦的。
正如前面所提到的,-O2是推薦的優(yōu)化等級(jí)。如果編譯軟件出現(xiàn)錯(cuò)誤,請先檢查是否啟用了-O3。再試試把CFLAGS和CXXFLAGS倒回到較低的等級(jí),如-O1甚或-O0 -g2 -ggdb(用來報(bào)告錯(cuò)誤和檢查可能存在的問題),再重新編譯。
-O0 不進(jìn)行優(yōu)化處理。
-O 或 -O1 優(yōu)化生成代碼。
-O2 進(jìn)一步優(yōu)化。
-O3 比 -O2 更進(jìn)一步優(yōu)化,包括 inline 函數(shù)。
可以直接man gcc 查看相關(guān)選項(xiàng)信息。
http://linux./techdoc/develop/2008/12/27/1055484.shtml
如果編譯時(shí)沒有抱怨"segmentation fault, core dumped",那么你設(shè)定的"-O"優(yōu)化參數(shù)一般就沒什么問題。
否則請降低優(yōu)化級(jí)別("-O3" -> "-O2" -> "-O1" -> 取消)。
個(gè)人意見:服務(wù)器使用"-O2"就可以了,它是最安全的優(yōu)化參數(shù)(集合);桌面可以使用"-O3" ;
不鼓勵(lì)使用過多的自定義優(yōu)化選項(xiàng),其實(shí)他們之間沒什么明顯的速度差異(有時(shí)"-O3"反而更慢)。
編譯器對(duì)硬件非常敏感,特別是在使用較高的優(yōu)化級(jí)別的時(shí)候,一丁點(diǎn)的內(nèi)存錯(cuò)誤都可能導(dǎo)致致命的失敗。
所以在編譯時(shí)請千萬不要超頻你的電腦(我編譯關(guān)鍵程序時(shí)總是先降頻然的)。
注意:選項(xiàng)的順序很重要,如果有兩個(gè)選項(xiàng)互相沖突,則以后一個(gè)為準(zhǔn)。
比如"-O3"將打開-finline-functions選項(xiàng),但是可以用"-O3 -fno-inline-functions"既使用-O3的功能又關(guān)閉函數(shù)內(nèi)嵌功能。
更多的優(yōu)化選項(xiàng)請參見:
http://gcc./onlinedocs/gcc-3....e-Options.html
http://gcc./onlinedocs/gcc-3....4-Options.html
http://gcc./onlinedocs/gcc-4....e-Options.html
http://gcc./onlinedocs/gcc-4....4-Options.html
所有GCC選項(xiàng)完整列表參見:
http://gcc./onlinedocs/gcc-3....n-Summary.html
http://gcc./onlinedocs/gcc-4....n-Summary.html
有兩個(gè)頁面值的參考:
(對(duì)于gentoo-1.4)比較安全的優(yōu)化選項(xiàng)
http://www./gentoo/gc...flag_gcc3.html
(對(duì)于gentoo-1.4)進(jìn)階優(yōu)化選項(xiàng)
http://www./gentoo/gc...g_gcc3opt.html
*******************************************************************
哦,忘了說一聲,"-O2"已經(jīng)啟用絕大多數(shù)安全的優(yōu)化選項(xiàng)了,所以其實(shí)你不必對(duì)那一堆選項(xiàng)發(fā)愁。
先說說"-O3"在"-O2"基礎(chǔ)上增加的幾項(xiàng),你可以按需添加(還算比較安全):
[gcc-3.4.4]
-finline-functions 允許編譯器選擇某些簡單的函數(shù)在其被調(diào)用處展開
-fweb 為每個(gè)web結(jié)構(gòu)體分配一個(gè)偽寄存器
-frename-registers 試圖驅(qū)除代碼中的假依賴關(guān)系,這個(gè)選項(xiàng)對(duì)具有大量寄存器的機(jī)器很有效。
[gcc-4.0.2]
-finline-functions 說明如上
-funswitch-loops 將循環(huán)體中不改變值的變量移動(dòng)到循環(huán)體之外
-fgcse-after-reload **不太明白它的含義**[哪位大峽知道給小弟講解一下]