我认为您可能需要阅读更多有关动态链接的信息。让我们以有点特殊strlen
的符号为例printf
(防御工事)。
您的问题是(我认为)您想要获取符号的地址并将其转换回地址。您正在尝试通过解析您正在调试的程序的 ELF 文件来执行此操作。这适用于程序中的符号,但不适用于动态链接的符号,例如strlen
. 你想知道如何解决这个问题。
原因是诸如符号的地址strlen
不在您的 ELF 程序中。相反,它们是在程序加载时动态解析的未解析引用。事实上,现代 Linux 将(我相信)以随机顺序和随机地址加载动态库(其中包含可重定位的又名位置无关代码),因此在程序加载之前不会知道这些符号的位置。
对于您打开的库dlopen()
(即您自己在程序中加载的位置),您可以使用dlsym()
;检索此类符号的地址 如果它们在编译/链接时链接到程序中,那并不是很好。
在 gcc 上,一般要解析符号的位置,请使用 gcc 扩展名dladdr()
。从手册页:
The function dladdr() takes a function pointer and tries to
resolve name and file where it is located. Information is
stored in the Dl_info structure:
typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Address at which shared object
is loaded */
const char *dli_sname; /* Name of nearest symbol with address
lower than addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;
If no symbol matching addr could be found, then dli_sname and
dli_saddr are set to NULL.
dladdr() returns 0 on error, and nonzero on success.
我相信这对你有用。
有关更多信息,我建议您查看跟踪库调用的来源,ltrace
以及backtrace_symbols
(以及此处)如何工作;请注意,特别是对于非全局符号,这将是不可靠的,并注意重新添加-r dynamic
到链接行的注释。
您可能还想查看addr2line及其源代码。