GDB能否从xx.so解析全局数据而不执行?
我有一个共享库(hlapi.so)在Linux系统上运行。这hlapi.so有很多模块(我的意思是.c文件)。其中一个被命名为hlapi.c定义这样的两个全球DATAS:GDB能否从xx.so解析全局数据而不执行?
static int hlapiInitialized = FALSE;
static struct hlapi_data app_sp;
当然也有这个hlapi.c模块在其他许多代码。 hlapi.so发布给基于我们的hlapi.so构建自己的应用程序(名为appbasehlapi)的客户。
现在我得到了一个核心转储,其客户解析的回溯显示核心位于我们的代码中。但客户只能向我们提供核心转储文件。 appbasehlapi可执行文件不会与我们共享。所以在我的手中,我只有核心转储文件+ hlapi.so。
为了调试这个核心,由我指挥
gdb --core=mycoredumpfile
装入核心转储文件,然后在gdb,我用
set solib-search-path .
指定包含hlapi.so这样的文件夹gdb可以从hlapi.so加载符号。然后我使用:
print hlapiInitialized
print app_sp
解析模块中的全局数据。但是输出值非常不正常。
我在这里的问题是,如果我可以解析全局数据通过gdb中定义的hlapi.so没有可执行文件?如果我通过gdb获得的输出是可信的? 我很欣赏任何评论。
顺便说一句,hlapi.so是用gcc选项“-g -fPIC”构建的。
我调查了一段时间的问题,在我看来,我相信GDB可以在没有可执行文件的情况下解析全局变量。
在测试中,将以下代码在hlapi.cpp:
static int hlapiInitialized = 0;
void hlapiInit()
{
if (hlapiInitialized == 0)
{
// do something else
}
hlapiInitialized = 1;
}
的objdump显示组件的代码,它是:
00000000000009a2 <_Z9hlapiInitv>:
9a2: 55 push %rbp
9a3: 48 89 e5 mov %rsp,%rbp
9a6: c7 05 98 06 20 00 01 movl $0x1,0x200698(%rip) # 201048 <_ZL16hlapiInitialized>
9ad: 00 00 00
9b0: 90 nop
9b1: 5d pop %rbp
9b2: c3 retq
在运行的应用程序,我生成核心倾倒它。在GDB,指定solib搜索路径之前,我得到:
(gdb) disas hlapiInit
No symbol table is loaded. Use the "file" command.
一旦指定的搜索路径,输出是:
(gdb) disas hlapiInit
Dump of assembler code for function hlapiInit():
0x00007ffff7bd59a2 <+0>: push %rbp
0x00007ffff7bd59a3 <+1>: mov %rsp,%rbp
0x00007ffff7bd59a6 <+4>: movl $0x1,0x200698(%rip) # 0x7ffff7dd6048 <_ZL16hlapiInitialized>
0x00007ffff7bd59b0 <+14>: nop
0x00007ffff7bd59b1 <+15>: pop %rbp
0x00007ffff7bd59b2 <+16>: retq
End of assembler dump.
输出从hlapi.so和比较后,核心文件,我们知道一旦共享库已经加载到进程中,全局变量的地址将被重新分配,并且全局变量的地址是清楚的。因此,一旦拥有共享库的符号信息,gdb就可以映射这些变量。
是否知道核心转储是否由您正在用于调试的库的_exact_相同版本生成? – duskwuff
@duskwuff,是的。它与我们发布给客户的hlapi.so版本相同。 –