最近同事的一个新feature+nginx+我的一个模块合并在一起的时候,发现运行1分钟左右的时候一直在core,而nginx+我的模块已经在线上运行了很长一段时间了。
虽然比较倾向于怀疑是新feature的问题,但是core的地方一直在我的那个模块,因此不得不“心虚”起来,于是拼命地review自己的模块,经过一段时间后,终于将目标锁定到a.c代码中的这一行(void *)peers = get_peers()(在b.c中定义声明),发现当get_peers()返回的地址超过4字节时,比如0x7de01020304,peers会将地址截断成0x01020304或者0xffffffff…。
最后发现是编译的时候忽略了一个warning: initialization makes pointer from integer without a cast 。。。。。。,编译器居然说我的函数返回的是一个 integer。后来增加一个b.h声明void *get_peers(),a.c中include b.h问题得以解决。
事后真的非常心虚,很后怕,很感慨一直有隐患的代码在线上运行了这么长时间,竟然没有造成交易下跌和故障,这件事给我的心得是不要忽略编译器的任何抱怨,否则会死的很惨,也让我重新审视了下自己的基础非常不扎实(nginx“非常友善”地帮我们包装了很多底层的调用,导致自己真正在实现底层功能的时候,发现已经不会使用了)。
第一步:进行预编译,使用-E参数可以让GCC在预处理结束后停止编译过程。
gcc -E hello.c -o hello.i
预处理的宏定义插入到hello.i中
typedef unsigned long int __dev_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef unsigned long int __ino_t;
typedef unsigned long int __ino64_t;
typedef unsigned int __mode_t;
typedef unsigned long int __nlink_t;
typedef long int __off_t;
typedef long int __off64_t;
typedef int __pid_t;
typedef struct { int __val[2]; } __fsid_t;
第二步:是将hello.i编译为目标代码,这可以通过使用-c参数来完成。
gcc -c hello.i -o hello.o
也可以通过源文件直接生成
gcc -c hello.c
第三步:是将生成的目标文件链接成可执行文件。
gcc hello.o -o hello
也可以通过源文件直接生成
gcc -o hello hello.c
1、-pedantic使用了扩展语法的地方将产生相应的警告信息;
2、-Wall能够使GCC产生尽可能多的警告信息;
3、-Werror要求GCC将所有的警告当成错误进行处理;
4、-O、-O2、-O3 将优化状态打开,该选项不能与-g选项联合使用;
5、-S 要求编译程序生成来自源代码的汇编程序输出;
6、-v 启动所有警报;
7、-w 禁止所有的报警。
1、Linux下的大多数函数都默认:
头文件放到/usr/include/目录下
库文件则放到/usr/lib/目录下
2、GCC在编译时必须有自己的办法来查找所需要的头文件和库文件。
-I选项可以向GCC的头文件搜索路径中添加新的目录。
例如,如果在/home/xiaowp/include/目录下有编译时所需要的头文件,为了让GCC能够顺利地找到它们,就可以使用-I选项:
gcc -o test test.c -I /home/xiaowp/include
-L选项向GCC的库文件搜索路径中添加新的目录
例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so,为了让GCC能够顺利地找到它,可以使用下面的命令
gcc -o test test.c -L /home/xiaowp/lib -lfoo
值得好好解释一下的是-l选项,它指示GCC去连接库文件libfoo.so。
Linux下的库文件在命名时有一个约定,那就是应该以lib三个字母开头,由于所有的库文件都遵循了同样的规范,因此在用-l选项指定链接的库文件名时可以省去lib三个字母,也就是说GCC在对-lfoo进行处理时,会自动去链接名为libfoo.so的文件。
-static选项,强制使用静态链接库
如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so和libfoo。a
为了让GCC在链接时只用到静态链接库,可以使用下面的命令:
gcc -o test test。c -L /home/xiaowp/lib -static -lfoo
使用管道代替编译中临时文件,
-pipe 加速编译
gcc -pipe foo.c -o foo