zoukankan      html  css  js  c++  java
  • 如何禁止Linux内核的-O2编译选项【转】

    转自: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/

    已有各种工具可以帮助我们调试内核,比如UML、kgdb、qemu等,但比较麻烦的是gdb经常给我一个“value optimized out”的提示,而且执行的路径与gdb的显示也不对应,最近我在利用UML调试ext3文件系统的逻辑时就为此而感到非常麻烦(2.6.30.8的内核):

    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)

    这应该是因为Linux内核打开gcc的-O2选项优化导致,于是我尝试修改内核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可以通过内核选项:General setup —> [ ] Optimize for size,进行开启/关闭,这里不管该选项而也就统一改了):

    1
    2
    3
    4
    5
    ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
    KBUILD_CFLAGS   += -O0
    else
    KBUILD_CFLAGS   += -O0
    endif

    执行编译,gcc给了我一个华丽的错误:

    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

    根据上面的提示信息,我尝试把文件slab.c的编译选项调为-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_对应源文件[要去除通常意义上扩展名].o = gcc选项
    所以上面加的是:
    CFLAGS_slab.o = -O2

    重新编译:

    1
    [root@lenky linux-2.6.30.8]# make ARCH=um -B V=1

    选项-B:以强制所有内核源文件全部重新编译(因为我前面编译过一次了,为了保险起见,就让目标文件全部重新生成吧)
    选项V=1:显示详细的编译信息,而不再是简单的“CC init/main.o”。

    编译出来的可执行程序linux比-O2的情况还小几M,一启动UML没多久,果然奔溃。

    看来内核里有大量的底层代码在书写时只兼容了-O2选项,所以如果以-O0的形式强制编译会导致出错,这即便不在编译时报错,也有极大可能会在实际执行时候出错,完全关闭所有内核源文件的-O2编译选项的风险太大。

    退而求次,我是为了调试journal_invalidatepage()函数,那么可以仅把对应源文件transaction.c的优化选项关闭即可,这个源文件的实现在比较高的层次,关闭优化选项应该不会出错。

    编辑文件fs/jbd/Makefile,再其最后加上一行:
    CFLAGS_transaction.o = -O0

    重新编译(之前的其它改动需回滚)后启动UML,一切OK。

    试试最开始的示例,用gdb绑定到UML主进程,调试函数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)

    嗯,效果不错。

    另外Google到由teawater提供了对应的补丁对整个内核进行关闭-O2优化,有没有问题不知道,我暂没有测试:
    http://sourceware.org/ml/gdb/2010-12/msg00009.html

    PS:
    错误:
    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>

    即可。

    转载请保留地址: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

  • 相关阅读:
    机器学习实战(六):利用AdaBoost元算法提高分类性能
    机器学习实战(五):支持向量机
    机器学习实战(四):Logistic回归
    机器学习实战(三):基于概率论的分类方法:朴素贝叶斯
    机器学习实战(一):k-近邻算法
    学习路线的思考
    非暴力沟通-读书笔记
    繁荣的悖论-读书笔记
    集体智慧编程-第四章 搜索与查询
    集体智慧编程-第三章-得到词汇在指定博客源出现的次数
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/8616518.html
Copyright © 2011-2022 走看看