从 linux 核心转储中检索已卸载共享库的加载地址

问题描述 投票:0回答:1

Linux 进程似乎使用

dlclose
卸载共享库,同时仍将其函数注册为回调。当回调被调用时它稍后崩溃,现在是无效内存,并且 gdb 无法因此展开堆栈。

缺少应用程序在加载时显式存储共享库列表,有没有办法从核心转储中获取已卸载库的加载地址(至少是通过

dlopen
加载的库)?

c++ linux shared-libraries glibc coredump
1个回答
0
投票

有没有办法从核心转储中获取已卸载库的加载地址

没有。

core
是崩溃时进程的内存图像,有关已卸载库的信息 不再存在——运行时加载程序没有理由保留该信息。

不过,你可以大概猜到。

假设您的代码如下所示:

  void *h = dlopen("somelib.so", ...);
  some_struct.callback = (int(*)(void)) dlsym(h, "some_func");
  dlclose(h);  // Oops. some_struct.callback is crash if called

core
转储/ GDB中,您应该知道
.callback
的值。假设它是
p == 0x7f...1234
.

你也知道

addr
some_func
的地址
libsomelib.so
(来自
nm libsomelib.so | grep some_func
)。

加载地址为

p - addr
,可以使用GDB
add-symbol-file load_address
.

但是请注意,

load_address
GDB 想要的是not
p - addr
;这是
p - addr + &.text-in-libsomelib.so
。您可以使用
.text
找到
readelf -WS libsomelib.so | grep '\.text'

的地址
© www.soinside.com 2019 - 2024. All rights reserved.