gdb在运行独立共享库时不加载符号

时间:2015-06-19 20:27:18

标签: c linux gdb shared-libraries

我有一个PIC共享库,它也有一个主要功能

getView()

此库已链接到另一个共享库#include <dtest2.h> #include <stdio.h> extern const char elf_interpreter[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2"; int dtestfunc1(int x,int y) { int i=0; int sum = 0; for(i=0;i<=x;i++) { sum+=y; sum+=dtestfunc2(x,y); } return sum; } int main (int argc, char const* argv[]) { printf("starting sharedlib main\n"); int val = dtestfunc1(4,5); printf("val = %d\n",val); _exit(0); } ,该库具有从libdtest2调用的dtestfunc2的实现。

如果我使用

直接在dtestfunc1上运行gdb
dtestfunc1

gdb没有加载libdtest2.so的符号。由于这个原因,我无法进入gdb libdtest1.so ,如果我按下s,该功能就会执行并退出。

如果我创建一个在共享库上调用dlopen的驱动程序,gdb在执行dlopen后正确加载符号并且一切正常。

  1. 为什么gdb在这两种情况下表现不同?
  2. 如果我直接在共享库上运行gdb,如何手动将gdb指向共享库?
  3. 注意:这是一个玩具示例,它反映了我对更大的共享库的问题。我的所有二进制文件和库都使用-ggdb3标志进行编译。

    编辑:我的共享库是可运行的。我在源代码中使用extern定义添加了正确的解释器路径。我用dtestfunc1编译了它。 我可以运行它并且它完美地执行。在这里运行共享库不是问题。

2 个答案:

答案 0 :(得分:4)

  

为什么gdb在这两种情况下表现不同?

因为您没有正确构建libdtest1.so以便GDB使用它。

特别是,您的libdtest1.so在其动态部分中缺少DT_DEBUG条目,您可以这样确认:

readelf -d libdtest1.so | grep DEBUG

你什么也看不见。在正确构建的可运行libdtest1.so(可以使用-pie标志构建)中,输出应如下所示:

 0x00000015 (DEBUG)                      0x0

运行时加载程序更新DT_DEBUG以指向其r_debug结构,然后允许GDB查找其他加载的共享库。没有DT_DEBUG,GDB找不到它们。

更新

  

添加饼形标志后,我的构建命令为gcc -ggdb3 -O0 -pie -shared -Wl,-soname,libdtest1.so.1 -ldtest2 -L/usr/lib -Wl,-e,main -o libdtest1.so.1.0 dtest1.c -I. DEBUG部分仍然缺失

术语:它不是DEBUG部分。这是DT_DEBUG部分中的.dynamic条目。

它仍然缺失,因为-shared会覆盖-pie。从链接行中删除-shared

您也不需要-Wl,-e,main,也不需要指定.interp - GCC会为您执行此操作。

正确的链接命令:

gcc -ggdb3 -O0 -pie -rdynamic dtest1.c -I. -Wl,-soname,libdtest1.so.1 \
  -L/usr/lib -ldtest2 -o libdtest1.so.1.0

(链接行上的源和库的顺序很重要,你的错误。)

已添加奖励:您的主管会收到正确的argcargv[],而不是您现在获得的虚假值。

答案 1 :(得分:0)

轻松修复....使用(for gcc)重新编译库'-ggdb'然后它将拥有gdb可用的所有符号。