运行 独立共享库时 gdb 不加载符号
gdb not loading symbols when running standalone shared library
我有一个 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);
}
此库链接到另一个共享库 libdtest2
,该库具有从 dtestfunc1
调用的 dtestfunc2
的实现。
如果我 运行 gdb 直接在 dtestfunc1 上使用
gdb libdtest1.so
libdtest2.so 的符号未由 gdb 加载。因此,我无法进入 dtestfunc1
,如果我按 s,函数就会执行并退出。
如果我创建一个在共享库上调用 dlopen 的驱动程序,gdb 会在执行 dlopen 后正确加载符号并且一切正常。
- 为什么 gdb 在这两种情况下的行为不同?
- 如果我直接在共享库上 运行ning gdb,如何手动将 gdb 指向共享库?
注意:这是一个玩具示例,反映了我在更大的共享库中遇到的问题。我所有的二进制文件和库都是使用 -ggdb3 标志编译的。
编辑:我的共享库 运行 可用。我使用源代码中的外部定义添加了正确的解释器路径。我用 gcc -ggdb3 -O0 -shared -Wl,-soname,libdtest1.so.1 -ldtest2 -L/usr/lib -Wl,-e,main -o libdtest1.so.1.0 dtest1.o
编译了它。
我可以 运行 它并执行 perfectly.Running 共享库不是这里的问题。
简单的修复....使用(对于 gcc)参数“-ggdb”重新编译库然后它将具有 gdb 可用的所有符号。
Why is gdb behaving differently in both these cases?
因为您没有为 GDB 正确构建 libdtest1.so
。
特别是,您的 libdtest1.so
在其动态部分缺少 DT_DEBUG
条目,您可以这样确认:
readelf -d libdtest1.so | grep DEBUG
你应该什么也看不到。在正确构建的可运行 libdtest1.so
(您可以使用 -pie
标志构建)中,输出应如下所示:
0x00000015 (DEBUG) 0x0
运行时加载程序更新 DT_DEBUG
以指向它的 r_debug
结构,然后允许 GDB 找到其他加载的共享库。没有 DT_DEBUG
,GDB 找不到它们。
更新:
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.
The DEBUG section is still missing
术语:它不是 DEBUG
部分。这是 .dynamic
部分中的 DT_DEBUG
条目。
它仍然缺失,因为 -shared
覆盖了 -pie
。从 link 行中删除 -shared
。
您也不需要 -Wl,-e,main
,也不需要指定 .interp
-- GCC 会为您完成。
正确的link命令:
gcc -ggdb3 -O0 -pie -rdynamic dtest1.c -I. -Wl,-soname,libdtest1.so.1 \
-L/usr/lib -ldtest2 -o libdtest1.so.1.0
(link 行中源和库的顺序很重要,你的错了。)
额外奖励:您的主将获得正确的 argc
和 argv[]
,而不是您现在获得的虚假值。
我有一个 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);
}
此库链接到另一个共享库 libdtest2
,该库具有从 dtestfunc1
调用的 dtestfunc2
的实现。
如果我 运行 gdb 直接在 dtestfunc1 上使用
gdb libdtest1.so
libdtest2.so 的符号未由 gdb 加载。因此,我无法进入 dtestfunc1
,如果我按 s,函数就会执行并退出。
如果我创建一个在共享库上调用 dlopen 的驱动程序,gdb 会在执行 dlopen 后正确加载符号并且一切正常。
- 为什么 gdb 在这两种情况下的行为不同?
- 如果我直接在共享库上 运行ning gdb,如何手动将 gdb 指向共享库?
注意:这是一个玩具示例,反映了我在更大的共享库中遇到的问题。我所有的二进制文件和库都是使用 -ggdb3 标志编译的。
编辑:我的共享库 运行 可用。我使用源代码中的外部定义添加了正确的解释器路径。我用 gcc -ggdb3 -O0 -shared -Wl,-soname,libdtest1.so.1 -ldtest2 -L/usr/lib -Wl,-e,main -o libdtest1.so.1.0 dtest1.o
编译了它。
我可以 运行 它并执行 perfectly.Running 共享库不是这里的问题。
简单的修复....使用(对于 gcc)参数“-ggdb”重新编译库然后它将具有 gdb 可用的所有符号。
Why is gdb behaving differently in both these cases?
因为您没有为 GDB 正确构建 libdtest1.so
。
特别是,您的 libdtest1.so
在其动态部分缺少 DT_DEBUG
条目,您可以这样确认:
readelf -d libdtest1.so | grep DEBUG
你应该什么也看不到。在正确构建的可运行 libdtest1.so
(您可以使用 -pie
标志构建)中,输出应如下所示:
0x00000015 (DEBUG) 0x0
运行时加载程序更新 DT_DEBUG
以指向它的 r_debug
结构,然后允许 GDB 找到其他加载的共享库。没有 DT_DEBUG
,GDB 找不到它们。
更新:
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.
The DEBUG section is still missing
术语:它不是 DEBUG
部分。这是 .dynamic
部分中的 DT_DEBUG
条目。
它仍然缺失,因为 -shared
覆盖了 -pie
。从 link 行中删除 -shared
。
您也不需要 -Wl,-e,main
,也不需要指定 .interp
-- GCC 会为您完成。
正确的link命令:
gcc -ggdb3 -O0 -pie -rdynamic dtest1.c -I. -Wl,-soname,libdtest1.so.1 \
-L/usr/lib -ldtest2 -o libdtest1.so.1.0
(link 行中源和库的顺序很重要,你的错了。)
额外奖励:您的主将获得正确的 argc
和 argv[]
,而不是您现在获得的虚假值。