如何禁止Linux内核的-O2编译选项【转】
轉(zhuǎn)自:http://blog.csdn.net/larryliuqing/article/details/8674274
http://lenky.info/2013/03/10/%E5%A6%82%E4%BD%95%E7%A6%81%E6%AD%A2linux%E5%86%85%E6%A0%B8%E7%9A%84-o2%E7%BC%96%E8%AF%91%E9%80%89%E9%A1%B9/
已有各種工具可以幫助我們調(diào)試內(nèi)核,比如UML、kgdb、qemu等,但比較麻煩的是gdb經(jīng)常給我一個(gè)“value optimized out”的提示,而且執(zhí)行的路徑與gdb的顯示也不對(duì)應(yīng),最近我在利用UML調(diào)試ext3文件系統(tǒng)的邏輯時(shí)就為此而感到非常麻煩(2.6.30.8的內(nèi)核):
| 1 2 3 4 5 | Breakpoint 1, journal_invalidatepage (journal=0x6c4bd800, page=0x61918b28, offset=0) at fs/jbd/transaction.c:2036 2036??? { (gdb) p bh $2 = <value optimized out> (gdb) |
這應(yīng)該是因?yàn)長(zhǎng)inux內(nèi)核打開(kāi)gcc的-O2選項(xiàng)優(yōu)化導(dǎo)致,于是我嘗試修改內(nèi)核Makefile文件(/usr/src/uml/linux-2.6.30.8/Makefile):
將
| 1 2 3 4 5 | ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS?? += -Os else KBUILD_CFLAGS?? += -O2 endif |
改為這樣(CONFIG_CC_OPTIMIZE_FOR_SIZE可以通過(guò)內(nèi)核選項(xiàng):General setup —> [ ] Optimize for size,進(jìn)行開(kāi)啟/關(guān)閉,這里不管該選項(xiàng)而也就統(tǒng)一改了):
| 1 2 3 4 5 | ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS?? += -O0 else KBUILD_CFLAGS?? += -O0 endif |
執(zhí)行編譯,gcc給了我一個(gè)華麗的錯(cuò)誤:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [root@lenky linux-2.6.30.8]# make ARCH=um -B V=1 ... mm/built-in.o: In function `index_of': /usr/src/uml/linux-2.6.30.8/mm/slab.c:341: undefined reference to `__bad_size' /usr/src/uml/linux-2.6.30.8/mm/slab.c:341: undefined reference to `__bad_size' /usr/src/uml/linux-2.6.30.8/mm/slab.c:341: undefined reference to `__bad_size' /usr/src/uml/linux-2.6.30.8/mm/slab.c:341: undefined reference to `__bad_size' /usr/src/uml/linux-2.6.30.8/mm/slab.c:341: undefined reference to `__bad_size' mm/built-in.o:/usr/src/uml/linux-2.6.30.8/mm/slab.c:341: more undefined references to `__bad_size' follow collect2: ld returned 1 exit status ??KSYM??? .tmp_kallsyms1.S nm: '.tmp_vmlinux1': No such file No valid symbol. make: *** [.tmp_kallsyms1.S] Error 1 |
根據(jù)上面的提示信息,我嘗試把文件slab.c的編譯選項(xiàng)調(diào)為-O2,即編輯mm/Makefile文件,在最后加上如下一行:
| 1 2 3 4 5 6 7 | [root@lenky linux-2.6.30.8]# vi mm/Makefile [root@lenky linux-2.6.30.8]# tail -n 5 mm/Makefile endif obj-$(CONFIG_QUICKLIST) += quicklist.o obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o CFLAGS_slab.o = -O2 |
格式是:
CFLAGS_對(duì)應(yīng)源文件[要去除通常意義上擴(kuò)展名].o = gcc選項(xiàng)
所以上面加的是:
CFLAGS_slab.o = -O2
重新編譯:
| 1 | [root@lenky linux-2.6.30.8]# make ARCH=um -B V=1 |
選項(xiàng)-B:以強(qiáng)制所有內(nèi)核源文件全部重新編譯(因?yàn)槲仪懊婢幾g過(guò)一次了,為了保險(xiǎn)起見(jiàn),就讓目標(biāo)文件全部重新生成吧)
選項(xiàng)V=1:顯示詳細(xì)的編譯信息,而不再是簡(jiǎn)單的“CC init/main.o”。
編譯出來(lái)的可執(zhí)行程序linux比-O2的情況還小幾M,一啟動(dòng)UML沒(méi)多久,果然奔潰。
看來(lái)內(nèi)核里有大量的底層代碼在書(shū)寫(xiě)時(shí)只兼容了-O2選項(xiàng),所以如果以-O0的形式強(qiáng)制編譯會(huì)導(dǎo)致出錯(cuò),這即便不在編譯時(shí)報(bào)錯(cuò),也有極大可能會(huì)在實(shí)際執(zhí)行時(shí)候出錯(cuò),完全關(guān)閉所有內(nèi)核源文件的-O2編譯選項(xiàng)的風(fēng)險(xiǎn)太大。
退而求次,我是為了調(diào)試journal_invalidatepage()函數(shù),那么可以?xún)H把對(duì)應(yīng)源文件transaction.c的優(yōu)化選項(xiàng)關(guān)閉即可,這個(gè)源文件的實(shí)現(xiàn)在比較高的層次,關(guān)閉優(yōu)化選項(xiàng)應(yīng)該不會(huì)出錯(cuò)。
編輯文件fs/jbd/Makefile,再其最后加上一行:
CFLAGS_transaction.o = -O0
重新編譯(之前的其它改動(dòng)需回滾)后啟動(dòng)UML,一切OK。
試試最開(kāi)始的示例,用gdb綁定到UML主進(jìn)程,調(diào)試函數(shù)journal_invalidatepage(),打印變量bh:
| 1 2 3 4 5 6 7 8 9 | Breakpoint 1, journal_invalidatepage (journal=0x6c06e800, page=0x61502e30, offset=0) at fs/jbd/transaction.c:2038 2038??????? unsigned int curr_off = 0; (gdb) p bh $1 = (struct buffer_head *) 0x6bd5f0c8 (gdb) p *bh $2 = {b_state = 3211305, b_this_page = 0x6bd5f268, b_page = 0x61501fc0, b_blocknr = 263, b_size = 1024, b_data = 0x6a648c00 "", ??b_bdev = 0x6bc02380, b_end_io = 0x600aa760 <end_buffer_async_write>, b_private = 0x6bdc46d8, b_assoc_buffers = { ????next = 0x6bd5f110, prev = 0x6bd5f110}, b_assoc_map = 0x0, b_count = {counter = 2}} (gdb) |
嗯,效果不錯(cuò)。
另外Google到由teawater提供了對(duì)應(yīng)的補(bǔ)丁對(duì)整個(gè)內(nèi)核進(jìn)行關(guān)閉-O2優(yōu)化,有沒(méi)有問(wèn)題不知道,我暫沒(méi)有測(cè)試:
http://sourceware.org/ml/gdb/2010-12/msg00009.html
PS:
錯(cuò)誤:
arch/um/os-Linux/mem.c: In function ‘create_tmp_file’:
arch/um/os-Linux/mem.c:216: error: implicit declaration of function ‘fchmod’
make[1]: *** [arch/um/os-Linux/mem.o] Error 1
make: *** [arch/um/os-Linux] Error 2
編輯文件arch/um/os-Linux/mem.c,加入頭文件:
| 1 | #include <sys/stat.h> |
即可。
轉(zhuǎn)載請(qǐng)保留地址:http://lenky.info/2013/03/10/%e5%a6%82%e4%bd%95%e7%a6%81%e6%ad%a2linux%e5%86%85%e6%a0%b8%e7%9a%84-o2%e7%bc%96%e8%af%91%e9%80%89%e9%a1%b9/?或?http://lenky.info/?p=2238
總結(jié)
以上是生活随笔為你收集整理的如何禁止Linux内核的-O2编译选项【转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 8Manage项目管理:嵌入人工智能的项
- 下一篇: solidity mapping of