当前位置: 技术问答>linux和unix
gcc O2选项造成的错误
来源: 互联网 发布时间:2016-11-10
本文导语: 装apache结果出错,invalid argument debug了一下apache的代码,发现GCC编译时带上了O2的选项,造成了函数调用fstat()出错。 于是我试着自己写了一段测试代码,分别用默认不带优化和带O2优化两种编译,结果果然不带编译的...
装apache结果出错,invalid argument
debug了一下apache的代码,发现GCC编译时带上了O2的选项,造成了函数调用fstat()出错。
于是我试着自己写了一段测试代码,分别用默认不带优化和带O2优化两种编译,结果果然不带编译的没问题,带了O2选项的返回一个errno为22的“invalid argument”.
测试环境为:
ivan@Redhat101:/localhome/ivan> uname -a
Linux Redhat101 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
ivan@Redhat101:/localhome/ivan> gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
测试代码为:
#include
#include
#include
#include
#include
#include
#include
int main ( int argc, char *argv[] )
{
int fd1=-1;
struct stat info1;
fd1=open("/localhome/kana/lingc.txt", O_RDWR);
printf("fd1=%d",fd1);
if(fd1 > 0)
{
if(fstat(fd1,&info1)!=0)
printf("failed to open fd1:%d;errorno:%dn",fd1,errno);
else printf("sucess");
close(fd1);
}
return 0;
}
请各位指教一下。
或者手头刚好有32位的机器也帮忙验证下,是不是32位就没有这个问题。
debug了一下apache的代码,发现GCC编译时带上了O2的选项,造成了函数调用fstat()出错。
于是我试着自己写了一段测试代码,分别用默认不带优化和带O2优化两种编译,结果果然不带编译的没问题,带了O2选项的返回一个errno为22的“invalid argument”.
测试环境为:
ivan@Redhat101:/localhome/ivan> uname -a
Linux Redhat101 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
ivan@Redhat101:/localhome/ivan> gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
测试代码为:
#include
#include
#include
#include
#include
#include
#include
int main ( int argc, char *argv[] )
{
int fd1=-1;
struct stat info1;
fd1=open("/localhome/kana/lingc.txt", O_RDWR);
printf("fd1=%d",fd1);
if(fd1 > 0)
{
if(fstat(fd1,&info1)!=0)
printf("failed to open fd1:%d;errorno:%dn",fd1,errno);
else printf("sucess");
close(fd1);
}
return 0;
}
请各位指教一下。
或者手头刚好有32位的机器也帮忙验证下,是不是32位就没有这个问题。
|
这个有意思,呵呵,上网查了一下,
extern __inline__ int fstat (int __fd, struct stat *__statbuf) __THROW
{
return __fxstat (_STAT_VER, __fd, __statbuf);
}
// _STAT_VER这个宏是3,和“movl $3, %edi”这一句可以印证,
int __fxstat (int vers, int fd, struct stat *buf)
{
if (vers != _STAT_VER)
{
__set_errno (EINVAL); // 这就是“Invalid argument”
return -1;
}
是不是C库和头文件的版本不一致?
extern __inline__ int fstat (int __fd, struct stat *__statbuf) __THROW
{
return __fxstat (_STAT_VER, __fd, __statbuf);
}
// _STAT_VER这个宏是3,和“movl $3, %edi”这一句可以印证,
int __fxstat (int vers, int fd, struct stat *buf)
{
if (vers != _STAT_VER)
{
__set_errno (EINVAL); // 这就是“Invalid argument”
return -1;
}
是不是C库和头文件的版本不一致?
|
32位
i486-linux-gnu
gcc version 4.4.5
没有问题,加不加O2都正确执行。
i486-linux-gnu
gcc version 4.4.5
没有问题,加不加O2都正确执行。
|
虽然没法再现问题,但是我看看觉得应该是编译器错误,这问题很有趣,因为根据man page,fstat没道理给出invalid argument。把gcc -S和gcc -O2 -S产生的汇编文件发出来看看。
|
应该跟GCC的版本有关, 可能是GCC本身的BUG
我就遇到过GCC-4.1.2的BUG, 对于pch文件的支持有BUG (详见http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10591), 换个GCC版本就好了.
我试了一下你的代码, 加-O2, 和不加都一样的结果
gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)
我就遇到过GCC-4.1.2的BUG, 对于pch文件的支持有BUG (详见http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10591), 换个GCC版本就好了.
我试了一下你的代码, 加-O2, 和不加都一样的结果
gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)
|
有可能这个版本的GCC或libc库不支持o2的优化选项。你可以用O3可O4试试