GDB可以从xx.so中解析全局数据,而无需执行



我在Linux系统上有一个共享库(hlapi.so)。此hlapi.o有许多模块(我的意思是.c文件)。其中一个被称为hlapi.c,它定义了两个这样的全局数据:

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.的文件夹,以便GDB可以从hlapi.so中加载符号。然后我使用:

print hlapiInitialized
print app_sp

在我们的模块中解析全局数据。但是输出值非常异常。

我的问题是,如果我可以通过GDB在没有可执行文件的情况下通过GDB解析全局数据?如果我通过GDB获得的输出可信吗?我感谢任何评论。

btw,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-Search-Path之前,我得到:

(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和Core文件的输出后,我们知道一旦将共享库加载到该过程中,将重新分配全局变量的地址,并且全局变量的地址清晰。因此,一旦拥有共享库的符号信息,GDB可以映射变量。

最新更新