简体   繁体   English

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

[英]gdb not loading symbols when running standalone shared library

I have a PIC shared library which also has a main function 我有一个PIC共享库,它也有一个主要功能

#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);
}

This library is linked to another shared library libdtest2 which has the implementation of dtestfunc2 called from dtestfunc1 . 这个库链接到另一个共享库libdtest2具有实施dtestfunc2从名为dtestfunc1

If i run gdb directly on dtestfunc1 using 如果我直接在dtestfunc1上运行gdb使用

gdb libdtest1.so

the symbols for libdtest2.so are not loaded by gdb. libdtest2.so的符号未被gdb加载。 I cannot step into dtestfunc1 because of this and if i press s, the function just executes and gets out. 因为这个我无法进入dtestfunc1 ,如果我按下s,该函数只执行并退出。

If i create a driver program which calls dlopen on the shared library, gdb loads the symbols properly after dlopen is executed and everything works fine. 如果我创建一个在共享库上调用dlopen的驱动程序,gdb在执行dlopen后正确加载符号并且一切正常。

  1. Why is gdb behaving differently in both these cases? 为什么gdb在这两种情况下表现不同?
  2. How can i manually point gdb to the shared library if i am running gdb directly on the shared library? 如果我直接在共享库上运行gdb,如何手动将gdb指向共享库?

Note: This is a toy example that mirrors my problem for a much larger shared library. 注意:这是一个玩具示例,它反映了我对更大的共享库的问题。 All my binaries and libraries are compiled with the -ggdb3 flag. 我的所有二进制文件和库都使用-ggdb3标志进行编译。

Edit: My shared library is runnable. 编辑:我的共享库是可运行的。 I added the proper interpreter path using the extern definition in the source code. 我在源代码中使用extern定义添加了正确的解释器路径。 I compiled it with gcc -ggdb3 -O0 -shared -Wl,-soname,libdtest1.so.1 -ldtest2 -L/usr/lib -Wl,-e,main -o libdtest1.so.1.0 dtest1.o . 我用gcc -ggdb3 -O0 -shared -Wl,-soname,libdtest1.so.1 -ldtest2 -L/usr/lib -Wl,-e,main -o libdtest1.so.1.0 dtest1.o I can run it and it executes perfectly.Running the shared library is not the issue here. 我可以运行它并且它执行得很完美。在这里运行共享库不是问题。

Why is gdb behaving differently in both these cases? 为什么gdb在这两种情况下表现不同?

Because you didn't build libdtest1.so correctly for GDB to work with it. 因为您没有正确构建libdtest1.so以便GDB使用它。

In particular, your libdtest1.so is lacking DT_DEBUG entry in its dynamic section, which you can confirm like so: 特别是,你的libdtest1.so在其动态部分缺少DT_DEBUG条目,你可以这样确认:

readelf -d libdtest1.so | grep DEBUG

You should see nothing. 你应该什么也看不见。 In a correctly built runnable libdtest1.so (which you can build using -pie flag), the output should look like this: 在正确构建的可运行的libdtest1.so (可以使用-pie标志构建)中,输出应如下所示:

 0x00000015 (DEBUG)                      0x0

The runtime loader updates DT_DEBUG to point to its r_debug structure, which then allows GDB to find other loaded shared libraries. 运行时加载程序更新DT_DEBUG以指向其r_debug结构,然后允许GDB查找其他加载的共享库。 Without DT_DEBUG , GDB can't find them. 没有DT_DEBUG ,GDB找不到它们。

Update: 更新:

After adding the pie flag my build command is 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. 添加pie标志后,我的构建命令是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. The DEBUG section is still missing DEBUG部分仍然缺失

Terminology: it's not a DEBUG section. 术语:它不是DEBUG部分。 It's a DT_DEBUG entry in the .dynamic section. 它是.dynamic部分中的DT_DEBUG条目。

It is still missing because -shared overrides -pie . 它仍然缺失,因为-shared覆盖-pie Remove -shared from the link line. 从链接行中删除-shared

You would also not need -Wl,-e,main , nor would you need to specify the .interp -- GCC will do that for you. 您也不需要-Wl,-e,main ,也不需要指定.interp - GCC会为您执行此操作。

The correct link command: 正确的链接命令:

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

(Order of sources and libraries on the link line matters, yours is wrong.) (链接线上的源和库的顺序很重要,你的错了。)

Added bonus: your main will receive correct argc and argv[] , instead of bogus values you are getting now. 额外奖励:你的argc将收到正确的argcargv[] ,而不是你现在得到的伪造价值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM