我有一个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上运行gdbdtestfunc1
gdb没有加载libdtest2.so的符号。由于这个原因,我无法进入gdb libdtest1.so
,如果我按下s,该功能就会执行并退出。
如果我创建一个在共享库上调用dlopen的驱动程序,gdb在执行dlopen后正确加载符号并且一切正常。
注意:这是一个玩具示例,它反映了我对更大的共享库的问题。我的所有二进制文件和库都使用-ggdb3标志进行编译。
编辑:我的共享库是可运行的。我在源代码中使用extern定义添加了正确的解释器路径。我用dtestfunc1
编译了它。
我可以运行它并且它完美地执行。在这里运行共享库不是问题。
答案 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
(链接行上的源和库的顺序很重要,你的错误。)
已添加奖励:您的主管会收到正确的argc
和argv[]
,而不是您现在获得的虚假值。
答案 1 :(得分:0)
轻松修复....使用(for gcc)重新编译库'-ggdb'然后它将拥有gdb可用的所有符号。