为什么gcc不产生stringop溢出警告

xe55xuns  于 2022-11-13  发布在  Go
关注(0)|答案(1)|浏览(220)

为什么下面的代码不产生一个gcc警告?

#include <string.h>

int main() {
  char d[1], s[4] = {0, 1, 2, 3};
  memcpy(d, s, 8);
}

gcc文档中指出:

  • W字符串操作溢出
  • Wstringop溢出=类型
    对字符串操作函数(如memcpy和strcpy)的调用发出警告,这些函数被确定为会使目标缓冲区溢出。
    ...
    选项-Wstringop-overflow=2在默认情况下处于启用状态。
    所以我会期待一个stringop-overflow警告。但是根本没有警告。当试图运行程序时它会崩溃,这是有道理的。
gcc -Wall -Wextra -pedantic test.c -o test_app
./test_app
*** stack smashing detected ***: terminated
Aborted

我用的是gcc 11.2,但也试过gcc 9.4。两种情况下都没有警告。

s5a0g9ez

s5a0g9ez1#

在未进行最佳化的情况下编译时,会产生您预期的警告:

gcc -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -fno-common -c str83.c
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/string.h:194,
                 from str83.c:1:
str83.c: In function ‘main’:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h:63:17: error: ‘__builtin___memcpy_chk’ writing 8 bytes into a region of size 1 overflows the destination [-Werror=stringop-overflow=]
   63 |                 __builtin___memcpy_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest))
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
str83.c:6:3: note: in expansion of macro ‘memcpy’
    6 |   memcpy(d, s, 8);
      |   ^~~~~~
cc1: all warnings being treated as errors

当使用-O3编译时,不会产生警告,这可能是因为它变成了死代码(没有可见的副作用),程序体被缩减为return(0);
这是一个真实的的GCC,而不是苹果的clang端口伪装成GCC:

$ gcc --version
gcc (GCC) 11.2.0
Copyright (C) 2021 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.

$

然而,它是在Mac上运行的,因此使用XCode头文件,因此<string.h>的路径很难处理。

相关问题