2015-12-22 70 views
1

我正在尝试track downissue,其中Valgrind无法解析通过某些库的函数的符号。我得到的输出是这样的:为什么GDB只有在碰到`main`时才能解析这个符号?为什么valgrind不能解决它?

==83597== 920 bytes in 1 blocks are possibly lost in loss record 750 of 864 
==83597== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==83597== by 0x548EF93: myproject_malloc (mysourcefile.c:48) 
==83597== by 0x4F13FD5: ??? (in /path/to/project/library-version.so) 
==83597== by 0x54542FF: ??? (in /path/to/project/library-version.so) 
==83597== by 0x4F536CA: ??? (in /path/to/project/library-version.so) 
==83597== by 0x54542FF: ??? (in /path/to/project/library-version.so) 

功能之一内library-version.sodo_init()library-version.so通过LD_PRELOAD加载。我发现当我在gdb下运行我的程序时,如果我在启动程序时尝试在do_init处设置断点,它会抱怨找不到该符号,但如果我在main处放置断点并等到它达到那个时间,然后它就起作用了。

例如:

(gdb) break do_init 
Function "do_init" not defined. 
Make breakpoint pending on future shared library load? (y or [n]) n 
(gdb) break main 
Breakpoint 1 at 0x400b50: file runner.c, line 13. 
(gdb) run 
... a bunch of output from the stuff in LD_PRELOAD ... 
Breakpoint 1, main (argc=1, argv=0x7fffffffe028) at myprogram.c:13 
13  return do_some_stuff(); 
(gdb) break do_init 
Breakpoint 2 at 0x7ffff7658de0: file my/library/initializer.c, line 25. 

因此,这导致我两个问题:

  1. 它似乎do_init是越来越由动态链接拉入。我怎样才能找出发生的初始化过程的哪个步骤?这个项目中使用了许多库,它们用__attribute__((constructor))定义函数,并且它们通过链接器脚本粘在一起。

  2. 为什么Valgrind看不到动态链接器加载的符号像GDB那样?我99%确定没有任何东西是dlclose'd,我认为任何在LD_PRELOAD之下的东西都会对Valgrind保持可见,无论如何。

+0

@iharob其中?共享库或二进制文件? –

+0

你是如何构建'library-version.so'的?它有调试符号吗? –

+0

所有这些,是否有一个Makefile? –

回答

0

原来因为一大堆正巧存在同时奇怪的配置选项,即包含在.text部的library-version.so程序节头用rwx权限,而不是RX权限标记。 Valgrind认为.text部分不能在amd64机器上拥有rwx权限,因此它会在尝试加载调试符号时忽略它们。

我相信这是Valgrind中的一个错误,因为.text部分的rwx权限根据相关标准完全有效;原来报告已经filed here,我已经扩大了。

相关问题