如何禁止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
如何禁止Linux内核的-O2编译选项【转】相关推荐
- Linux内核RCU(Read Copy Update)锁简析
在非常早曾经,大概是2009年的时候.写过一篇关于Linux RCU锁的文章<RCU锁在linux内核的演变>,如今我承认.那个时候我尽管懂了RCU锁,可是我没有能力用一种非常easy的描 ...
- 【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )
文章目录 一.禁止 / 开启内核抢占 与 方法保护临界区 二.编译器优化屏障 三.preempt_disable 禁止内核抢占 源码 四.preempt_enable 开启内核抢占 源码 一.禁止 / ...
- Scratch 被禁止访问;Linux 内核历史报告2020 等开源之道每周评论2020 09 15
点击上方蓝字,关注开源之道 声明:本文所言论,仅代表适兕个人观点 论文阅读心得与体会 Linux 内核历史报告2020 原文链接:the 2020 Linux Kernel History Repor ...
- 美国能限制linux内核,因故意引入漏洞,美国一所大学被禁止为 Linux 内核做贡献...
出品|开源中国 文|Travis Linux 内核项目维护者 Greg Kroah-Hartman 决定禁止美国明尼苏达大学(UMN)为开源 Linux 项目做贡献.其原因是明尼苏达大学的研究人员被发 ...
- 因故意引入漏洞,整所大学被禁止为Linux内核做贡献,回应来了!
点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 Make the person mature is not the ...
- linux内核编译选项ccl,嵌入式Linux学习笔记(一)
注:所有内容基于友善之臂Mini2440开发板 一.嵌入式Linux开发环境的构建 嵌入式开发一般分为三个步骤: 1.编译bootloader,烧到开发板 2.编译嵌入式Linux内核,烧到开发板 3 ...
- LINUX内核编译选项-5
Device Drivers ---> 驱动程序 Generic Driver Options --->驱动程序通用选项 (/sbin/hotplug) path to uevent ...
- Linux内核调试方法总结【转】
转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...
- Linux内核调试方法总结
[转]Linux内核调试方法总结 目录[-] 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG ...
最新文章
- 爱创课堂每日一题101天-哪些操作会造成内存泄漏?
- 【bzoj2754】【scoi2012】喵星球上的点名
- python图片保存_python读取和保存图片5种方法对比
- java map大小_Java中HashMap的size()方法: HashMap.size() - Break易站
- 三国佚事——巴蜀之危【递推】
- PHP 多维数组搜索 PHP multi dimensional array search
- 关于将vrep和matlab或者python结合的两种方法的比较
- Netty工作笔记0039---Netty模型--详细版
- 【云周刊】第173期:直击数博|阿里胡晓明:用100亿的投入撬动1000亿的脱贫效应...
- fdisk 创建和维护磁盘分区命令(MBR分区方案)
- bat脚本变量赋值输出时提示”ECHO 处于关闭状态“
- Linux驱动——编译驱动的两种形式(内核目录外、内核目录中)
- java随机取名_中文名字随机生成器
- html表单颜色背景图片大全,css背景颜色、背景图片,以及列表的多种样式
- 分享一个matplotlib柱状图
- 下载到的电子书格式是Mobi,这种格式能否在WINDOWS电脑上打开?
- data单复数一样吗_data和datum谁是单数形式,谁是复数形式?
- 超级计算机大赛要学什么,超级计算机竞赛“七步成诗”仅三队完赛
- 缓冲、运放、跟随电路详解及区分
- Java毕设项目保险公司风险测评管理系统计算机(附源码+系统+数据库+LW)
热门文章
- 'keytool' 不是内部或外部命令,也不是可运行的程序
- Winform中设置ZedGraph的曲线为折线、点折线、散点图
- Jquery中使用ajax请求SSM后台时提示:org.springframework.http.converter.HttpMessageNotReadableException: Could no
- 用Python拼图发一个高逼格的朋友圈
- html菜单浮动,浮动菜单,可实现上下滚动的效果
- 深度干货 | 多维分析中的 UV 与 PV
- 【Android Studio安装部署系列】八、Android Studio主题皮肤更换
- SQL ALTER TABLE 语句
- Some notes for CLFS2017
- 全自动化建立SSH信任