__xstat 64 位动态符号解析错误

Posted

技术标签:

【中文标题】__xstat 64 位动态符号解析错误【英文标题】:__xstat dynamic symbol resolving error on 64bit 【发布时间】:2019-02-04 16:14:32 【问题描述】:

我正在尝试使用 dlopen 和 dlsym 动态加载 stat 函数。 来自 stat 系列的函数被封装在相应的函数 __xstat__xstat64 itp 中。

截取代码后,在 32 位模式下编译并运行(包括sys/stat.h 以获取 stat 结构以作为示例)

#include <iostream>
#include <dlfcn.h>
#include <sys/stat.h>

typedef int (*xstat_f) (int __ver, const char *__filename, struct stat *__stat_buf);

int main()

    auto* h = dlopen("libc.so.6", RTLD_LAZY);
    if(!h)
    
        return 1; // invalid handle
    

    auto f = (xstat_f)dlsym(h, "__xstat");
    if(!f)
    
        return 1; // invalid handle
    

    struct stat s = ;

    const auto r = f(3, "/tmp", &s);

    if (r != 0)
    
        perror("stat");
        return errno;
    

    return 0;

g++ main.cpp -o main -ldl -m32

在 64 位机器上不使用-m32 开关编译的可执行文件返回 EINVAL(无效参数)。

是什么原因?

我也做了一个最小的测试

#include <iostream>
#include <sys/stat.h>

int main()
    struct stat s;
    const auto x = stat("/tmp", &s);
    if(x != 0) return errno;
    return 0;

并在 32 位和 64 位可执行文件上使用 objdump -T,表明 stat 被解析为 __xstat,因此我使用了正确的符号。我还尝试了__xstat/__xstat64struct stat/stat64 的组合,结果相同。

【问题讨论】:

使用dlerror 代替perror。此外,您不应尝试使用未记录的/特定于平台的功能。 @LorinczyZsigmond 我同意这些不是用户函数,但它们记录为标准系统接口函数:refspecs.linuxfoundation.org/LSB_2.0.1/LSB-generic/… 根据这个接受的答案,这是解析stat函数***.com/questions/48994135/…的符号 您可以直接调用这些方法,但需要添加版本第一个参数为_STAT_VER。尝试直接从 main() 调用它 在我的具体情况下,必须通过dlopen来完成。 【参考方案1】:

__xstat 声明如下:

int __xstat(int ver, const char *path, (struct stat *stat_buf))

在文档中参数ver被描述为ver shall be 3 or the behavior of these functions is undefined,这并不完全正确,因为在源代码中,_STAT_VER_LINUX的定义如下:

#ifndef __x86_64__
# define _STAT_VER_LINUX    3
#else
# define _STAT_VER_LINUX    1
#endif

这就是为什么__xstat 在 64 位上调用失败的原因,参数 ver 应该设置为 1,而在 32 位编译上应该设置为 3。

【讨论】:

以上是关于__xstat 64 位动态符号解析错误的主要内容,如果未能解决你的问题,请参考以下文章

无法解析的外部符号 _WinMain@16

解析和 Paypal 链接器错误

错误 LNK2001:未解析的外部符号 LIBID_

未解析的外部符号_stricoll

如何修复 MSVC 2005 错误:未解析的外部符号 __environ

vc ++ MFC应用程序,错误LNK2019:未解析的外部符号