加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – string3.h中__warn_memset_zero_len的定义在哪里

发布时间:2020-12-16 07:20:47 所属栏目:百科 来源:网络整理
导读:最近我将我的项目从ubuntu 14.04移到了ubuntu 16.04.当我使用从os存储库安装的 gcc 4.8.5编译我的项目时,我遇到了一个错误,“undefined __warn_memset_zero_len”.我从来没有在使用gcc 4.8.4的ubuntu 14.04上看到这个错误. __warn_memset_zero_len,在string3
最近我将我的项目从ubuntu 14.04移到了ubuntu 16.04.当我使用从os存储库安装的 gcc 4.8.5编译我的项目时,我遇到了一个错误,“undefined __warn_memset_zero_len”.我从来没有在使用gcc 4.8.4的ubuntu 14.04上看到这个错误.

__warn_memset_zero_len,在string3.h中声明,从memset中调用,以警告程序员的错误.为了重现错误,我制作了以下示例代码并使用gcc编译–save-temps test_mem.c -D_FORTIFY_SOURCE = 1 -Wall -O1 -v -Wl,-v

#include <stdio.h>
#include <string.h>

int main ()
{
     char str[] = "almost every programmer should know memset!";
     memset (str,1,0);
     puts (str);
     return 0;
}

此代码也仅在ubuntu 14.04中使用gcc 4.8.4编译.所以,首先,我假设新的libc可能缺少__warn_memset_zero_len的定义.为了找出定义,我将ubuntu 14.04的旧libc与ubuntu 16.04的旧libc进行了比较.这两个版本都没有它,只有string3.h中的函数声明.我错了. :其中

作为下一步,我假设gcc可能会在编译期间删除对函数的引用,因为它是一个特殊的警告函数.但是,两个系统创建的目标文件仍然具有引用,由nm检查.然后,源代码仍然需要__warn_memset_zero_len的定义.我的想法转移到与测试代码链接的共享对象上.

/usr/bin/ld --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 
--hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 
-z relro /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o 
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o 
/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o 
-L/usr/lib/gcc/x86_64-linux-gnu/4.8 
-L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu 
-L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib 
-L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu 
-L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. 
test_mem.o -v -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc 
--as-needed -lgcc_s --no-as-needed 
/usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o 
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o

这是链接命令gcc用于链接ubuntu 14.04上的测试代码.我查找了链接对象和库的所有符号,但找不到__warn_memset_zero_len.神秘感越来越严重.

作为最后的尝试,我假设属性“warning”__warn_memset_zero_len的声明使用可能允许旧的gcc编译没有定义的代码.所以我做了以下测试代码.

extern void __warning_test (void) __attribute__((__warning__ ("test_warning")));

int main(){
   __warning_test();
   return 0;
}

现在,我可以在两个系统上获得未定义的符号错误.

/tmp/ccN1UbZh.o: In function `main':
test.c:(.text+0x5): undefined reference to `__warning_test'
collect2: error: ld returned 1 exit status

我不知道为什么编译在没有__warn_memset_zero_len定义的旧系统中成功以及为什么它在新系统中失败.另外,为什么与__warn_memset_zero_len看起来完全相同的自定义函数甚至在旧系统上都会失败?你对这个问题有什么想法吗?

解决方法

__warn_memset_zero_len()在/usr/lib/x86_64-linux-gnu/libc.a中声明,它是gcc的隐式库.你可以使用nm命令来确认它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读