最近项目需要使用最新的 Ubuntu 20.04.4,查看下 编译器版本居然是 9.4.0,自然项目迁移过程中会有很多编译问题需要解决,毕竟之前的 gcc 版本都是 4.8.5的,差距很大。

lm@lm:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
lm@lm:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
In function ‘char* strncpy(char*, const char*, size_t)’,
    inlined from ‘Agent::queryLocalData(std::string&, ResponseDataT&)’ at ./Agent/Agent.cc:715:14:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:34: error: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ specified bound 255 equals destination size [-Werror=stringop-truncation]
  106 |   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
      |          ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors

部分关键源码如下:

710 const unsigned int NAME_LENGTH = 255;
712 char logicName[NAME_LENGTH];
713 std::string localFileData;
714 ......
715 strncpy(logicName, localFileData.c_str(), NAME_LENGTH);
716 ......

从编译错误可以很清晰的看出就是 strncpy() 这一行有问题。可以原来的 gcc 4.8.3 没有问题啊,而且貌似在 gcc 8.3 也没报错。都是这么使用的。

查看/usr/include/x86_64-linux-gnu/bits/string_fortified.h 文件对应的内容如下:

102 __fortify_function char *
103 __NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
104 		size_t __len))
105 {
106   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
107 }

查看gcc官网的编译选项:3 GCC Command Options

在其中的 3.1 Option Summary 中可以搜索到 -Wno-stringop-truncation 编译选项。顺藤摸瓜,进一步我们可以在 3.8 Options to Request or Suppress Warnings 查看到下面的描述:

-Wno-stringop-truncation

Do not warn for calls to bounded string manipulation functions such
as strncat, strncpy, and stpncpy that may either truncate the copied
string or leave the destination unchanged.

In the following example, the call to strncpy specifies the size of
the destination buffer as the bound. If the length of the source
string is equal to or greater than this size the result of the copy
will not be NUL-terminated. Therefore, the call is also diagnosed. To
avoid the warning, specify sizeof buf - 1 as the bound and set the
last element of the buffer to NUL.

下面是其中举的例子

void copy (const char *s)
  char buf[80];
  strncpy (buf, s, sizeof buf);

其中关键字我这里已经做了加粗处理。即我们需要将最后一个字节做处理,手动给它赋值’\0’。

通过编译选项我们知道了问题所在,那么接下来解决起来就很简单了。从上面的描述我们可以有下面两种解决办法:

我们通过将 strncpy 中长度改为小于目标缓冲区边界值,即将 lenght 调整为 sizeof(buf) -1 。修改后代码如下:

710 const unsigned int NAME_LENGTH = 255;
712 char logicName[NAME_LENGTH];
713 std::string localFileData;
714 ......
715 strncpy(logicName, localFileData.c_str(), sizeof(logicName)-1);
716 ......

我们不改变原来的代码,而是直接再添加一行代码,即,将缓冲区的最后一个元素设置为 NUL。修改后代码如下:

710 const unsigned int NAME_LENGTH = 255;
712 char logicName[NAME_LENGTH];
713 std::string localFileData;
714 ......
715 strncpy(logicName, localFileData.c_str(), NAME_LENGTH);
716 logicName[sizeof(logicName)-1] = '\0';
717 ......

通过验证,上面两种办法都是可以的,任选一种即可。

也可以通过忽略编译告警的方式,即通过在编译选项中添加 -Wno-error=stringop-truncation
具体方式为:

  1. 找到引起告警的产品代码源文件所在的makefile文件(或者cmake);
  2. 查看编译选项(一般是makefile文件)xx_xx_CPPFLAGS(x_xx是最终会生成的 lib 库)
  3. 添加或者追加编译选项 xx_xx_CPPFLAGS := -Wno-error=stringop-truncation
  4. 重新编译产品代码

当然,使用此种方案,会在编译的 log 中看到下面的提示信息:

In function ‘char* strncpy(char*, const char*, size_t)’,
    inlined from ‘Agent::queryLocalData(std::string&, ResponseDataT&)’ at ./Agent/Agent.cc:715:14:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:34: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ specified bound 255 equals destination size [-Wstringop-truncation]
  106 |   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
      |          ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

综上几种解决方案,建议优先考虑方案一和方案二。最后考虑方案三。

c: ‘strncpy‘ specified bound depends on the length of the source argument [-Wstringop-overflow=]
[-Werror=stringop-truncation] 106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)) 在顶层的CMakeLists中两处-Werror 后添加-Wno-error=stringop-truncation
ubuntu20.04.2环境下openjdk12源码编译相关问题Werror=stringop-truncation环境其余组件安装命令编译前准备报错信息解决方案 按照《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》的编译openjdk步骤指示,出现了一些问题,导致无法完成编译。 Ubuntu 20.04.2 LTS 其余组件安装命令 sudo apt-get install build-essential bootstrap jdk: sudo apt-get install op
Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a nu... 最近项目需要使用 Ubuntu 20.04.4,查看下 编译器版本居然是 9.4.0,自然项目迁移过程中会有很多编译问题需要解决,毕竟之前的 gcc 版本都是 4.8.5的,差距很大。 使用 gcc(g++) 遇到编译问题,首选当然是浏览器直接搜索问题关键字即可,一般都是有解决办法的,但是碰到和高版本如:gcc 8.4、gcc 9.4版本的问题,很多时候就不太好找的。因此就需要自己去 GCC官网 针对具体问题具体查看了。 附 Ubuntu 下载直达链接:Ubuntu Server 20.04.4 LT
You fell straight into the trap. In C, C++, Objective-C, Objective-C++, a parameter with a declaration that looks like "array of T" actually has type T*. Your parameter charArray has a declaration t...
下午在编译 grpc时报错如下: utilities/blob_db/blob_log_reader.cc:74:18: error: this statement may fall through [-Werror=implicit-fallthrough=] next_byte_ += kb_size; ~~~~~~~~~~~^~~~~~~~~~ utilities...
github/basalt/thirdparty/Pangolin/src/image/image_io_lz4.cpp:42:12: error: ‘char* strncpy(char*, const char*, size_t)’ output truncated before terminating nul copying 3 bytes from a string of the same length [-Werror=stringop-truncation] cc1plus: all warni
1.fatal error curses.h no such file or directory sudo apt-get install libncurses5-dev libncursesw5-dev 2.gcc: error: unrecognized command line option ‘-mlittle-endian’ make时加上交叉编译器CROSS_COMPILE=/usr/bin/arm-linux-gnueab
In function ‘char* strncpy(char*, const char*, size_t)’, inlined from ‘Agent::queryLocalData(std::string&, ResponseDataT&)’ at ./Agent/Agent.cc:715:14: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:34: error: ‘char* __builtin_strncpy(char*,
In function ‘strncpy’, inlined from ‘splitName’ at ../../src/pyi_launch.c:83:5, inlined from ‘_extract_dependency’ at ../../src/pyi_launch.c:215:9: /usr/include/aarch64-linux-gnu [root@ft2000 ~]# lscpu Architecture: aarch64 CPU op-mode(s): 64-bit Byte Order: Little Endian CPU(s): 64 On-line CPU(s) list: 0-63 Thread(s) per core: In function ‘AllocString’, inlined from ‘SetData’ at /home/yeqiang/Downloads/openjdk-jdk-14-23/src/java.desktop/share/native/liblcms/cmscgats.c:1586:47, inlined from ‘cmsIT8SetDataRowC...
"-Werror=missing-braces" 是 GCC 编译器的一个选项,用于将缺少大括号的初始化视为错误而非警告。这个选项可以帮助你在编译过程中捕捉到可能的错误,并确保正确地初始化结构体或数组。 你可以将"-Werror=missing-braces"选项添加到编译命令中的编译选项部分。具体来说,你可以在使用 GCC 编译器进行编译时的命令行中加入该选项。 例如,在使用 GCC 编译编译一个 C 文件时,可以这样添加该选项: ```shell gcc -Werror=missing-braces file.c -o output 这会将"-Werror=missing-braces"选项传递给 GCC 编译器,告诉它将缺少大括号的初始化视为错误。 请注意,具体的操作方法取决于你所使用的编译器和开发环境。如果你使用的是其他编译器或 IDE,请查阅相关文档或在社区中寻求帮助,以了解如何在你的开发环境中添加该选项。
GCC9.4 memset() clearing an object of type with no trivial copy-assignment [-Werror=class-memaccess] 受教了,最近新项目遇到这个问题,是有人更新了gcc版本引发的。 Ubuntu 20.04.4 Server 图文安装[含磁盘分区] ^^^^327: 你好,为什么我的两个网络里面,显示第一个没联网,就是配置的时候没自动给ip,显示自动配置失败,最后安装重启之后检查也没ip GCC 9.4 编译 specified bound 255 equals destination size [-Werror=stringop-truncation] 失去理想的环: 太牛了!顺利解决 KVM调整虚拟机与CPU铆钉(绑定)关系 穷苦书生_万事愁: 博主的这篇关于“KVM调整虚概念模和串铃(绑定)关系”的文章真是让人受益匪浅。通过深入的介绍和细致的分析,我对这个主题有了全新的认识,感受到了博主的专业水平和深厚功底。文章内容详实且条理清晰,让我对如何调整虚拟机与CPU的关系有了更具体的操作方法。期待博主能够持续分享更多优质内容,也希望能够得到博主的指导和帮助,一起共同进步。真心感谢博主的辛苦付出和宝贵的分享! Ubuntu 20.04.4 Server 图文安装[含磁盘分区] lm_hao: 你好,这个没有统一的规划,需要看你的应用场景,但是建议:至少下面2个分区按照规划的来分配,可以基本满足大部分应用 swap分区 :3G /boot分区 :2G 其他的分区,如:/home 根据服务器被访问的用户数目,灵活分配。