nginx 开发时 off_t 大小不一致问题

来源:互联网 发布:ubuntu home 改成英文 编辑:程序博客网 时间:2024/06/13 11:18

    C语言的包含关系是非常考验人的问题,大多数C,C++程序员应该都遇到过包含顺序问题导致的编译问题,而本文的问题则更隐蔽,是包含顺序问题引起的运行时问题。
主要表现是,由于宏定义的先后顺序,影响了数据结构,导致不同的文件中,相同的数据结构大小却不一样。


    最近在写一个Nginx敏感词过滤模块时,出现一个奇怪的现象:

在方法内创始一个对象,对其赋值后,返回,在调用的地方值变成了。对象本身的地址并没有变。只是结构体里面的大部分属性值改变了。

经过一系列的打日志,调试,发现同一个结构体ngx_buf_t 在不同的文件里面,大小是不同的。这让我想起来以前写一个Nginx的TCP模块时,也遇到同样的问题,一个结构体在不同的文件中,大小不一样,后面追踪到主要是数据结构中的off_t类型在两个文件中大小不一致。当时由于时间关系,并没有详查原因,只是很简单的把数据结构中的off_t 改变成了uint64_t。


    这次调试后发现:

在ngx_buf.c中 sizeof(off_t)为8字节。
在自己写的模块代码里面sizeof(off_t)为4字节。

后来在网上搜索相关信息,发现有一个宏_FILE_OFFSET_BITS可以控制off_t结构的大小。当定义这个宏之后off_t就使用的是64位的:

/usr/include/features.h 

#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
# define __USE_FILE_OFFSET64    1
#endif


而nginx中刚好定义了这个宏:

./src/os/unix/ngx_linux_config.h:16:#define _FILE_OFFSET_BITS  64


    这样问题就比较清楚了,应该是在我的源代码中,先包含linux下的头文件,而此时还没有定义_FILE_OFFSET_BITS。所以在我自己写的源代码中sizeof(off_t)是4字节,而nginx代码中,由于已经定义了这个宏,sizeof(off_t)就是8字节了。


    就这样,我把我的源代码中的包含顺序调换了下,把nginx相应的头文件先包含,然后再包含系统的头文件。(这样在系统的头文件中就能感知到__USE_FILE_OFFSET64宏的存在)。



1 0