如何判断进程地址空间中加载共享库的位置?

我正在尝试调试一个共享库,我有源代码和调试符号,以便使用gdb。
我没有实际使用这个共享库的进程的调试符号或代码(我自己编译它,所以我可以拥有所有内容,但是生成的二进制文件被剥离,以模拟我没有代码的情况)。
该进程打印我正在尝试调试的目标函数foo的地址,以测试gdb是否知道共享库中符号的正确位置。 foo存在我的共享库。 我的打印方法是将以下行添加到使用我的共享库的二进制文件中:

printf("%p\n", foo) 

…而且为了增加复杂性,这是一个我正在远程调试的Android系统。

我正在尝试的方案如下:
估计的正好:

 root@phone:/proc/23806 # gdbserver --attach :5555 23806 Attached; pid = 23806 Listening on port 5555 Remote debugging from host 127.0.0.1 

在主持人:

 [build@build-machine shared]$ /home/build/shared/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin/arm-eabi-gdb GNU gdb (GDB) 7.3.1-gg2 Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later  This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android". For bug reporting instructions, please see: (gdb) target remote :5555 Remote debugging using :5555 0xb6f17fa0 in ?? () (gdb) add-symbol-file out/target/product/armv7-a-neon/symbols/system/lib/libShared.so The address where out/target/product/armv7-a-neon/symbols/system/lib/libShared.so has been loaded is missing 

现在我知道我需要什么 – 进程地址空间中这个共享库的重定位.text部分,但我不知道如何找到它。 我试过/ proc / 23806 / smaps:

 root@phone:/proc/23806 # cat maps | grep Shared b6ea0000-b6edb000 r-xp 00000000 b3:10 3337 /system/lib/libShared.so b6edc000-b6ede000 r--p 0003b000 b3:10 3337 /system/lib/libShared.so b6ede000-b6edf000 rw-p 0003d000 b3:10 3337 /system/lib/libShared.so 

并且.text部分位于.so文件中的0x0003ff00:

 [build@build-machine shared]$ objdump -h out/target/product/armv7-a-neon/symbols/system/lib/libShared.so | grep text 7 .text 0002835c 00003ff0 00003ff0 00003ff0 2**3 

所以现在我应该有我的共享库所在的地址:0xb6ea0000 + 0x00003ff0 = 0xb6ea3ff0(从那里开始加载库+ .text偏移量)所以我做了:

 (gdb) add-symbol-file out/target/product/armv7-a-neon/symbols/system/lib/libShared.so 0xb6ea3ff0 add symbol table from file "out/target/product/armv7-a-neon/symbols/system/lib/libShared.so" at .text_addr = 0xb6ea3ff0 (y or n) y 

现在我尝试从我的共享库为foo函数设置断点:

 (gdb) b F10 Breakpoint 1 at 0xb6ea41de: file frameworks/native/test/shared/src/shared, line 122. 

它与我的二进制文件的值不匹配,即0xb6ea4217(打印在屏幕上)。

看来我没有为共享库提供正确的内存位置,但我无能为力。

任何帮助表示赞赏!

最好的办法是运行(gdb) x/10i 0xb6ea41de(gdb) x/10i 0xb6ea4217

我猜测GDB或你的程序打印PLT条目的地址,而不是foo的真实地址。

PS您调用add-symbol-file似乎是正确的。

好吧,所以在经常打开和关闭这个一段时间之后,我终于发现了什么问题。

解决方案来自不同的角度,我最近不得不调试一些我有部分源代码的代码,所以我做了混合源/汇编调试,并注意到在调试源时,事情开始出现偏差 – 我不能使用下一条指令作为它会崩溃 – 但是当我调试指令时,一切都很好!

然后我在AOSP树中添加并编译了以下短代码:

 int main(int argc, char** argv) { int first,second; first=1; second=2; return first+second; } 

并且,正如预期的那样,它无法正常调试(汇编调试工作,源调试没有)。

然后我注意到argc已被优化了!

所以……这里真正发生的是编译器优化,它阻止了源代码的调试,因为生成的指令与实际源之间没有1:1的关系。 由于我在AOSP构建脚本的手中保留了默认构建标志,因此我遇到了这些奇怪的调试问题……

谢谢@EmpyloyedRussian的帮助!