2017-11-25 351 views
2

我有一个共享库(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”构建的。

+0

是否知道核心转储是否由您正在用于调试的库的_exact_相同版本生成? – duskwuff

+0

@duskwuff,是的。它与我们发布给客户的hlapi.so版本相同。 –

回答

0

我调查了一段时间的问题,在我看来,我相信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就可以映射这些变量。