【问题标题】:Unable to resolve symbol无法解析符号
【发布时间】:2012-12-17 17:14:49
【问题描述】:

我正在为嵌入式系统交叉编译程序。该程序使用一个共享库,我像这样打开它。

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>      //needed for dynamic linking

void  *FunctionLib;     //Handle to shared lib file
int   (*Function)();    //Pointer to loaded routine
const char *dlError;    //Pointer to error string

int main( argc, argv )
{
    int   rc;               //return codes
    printf("start...\n");

    //Open Dynamic Loadable Libary with absolute path
    FunctionLib = dlopen("/lalabu/sharedLib.so",RTLD_LAZY | RTLD_GLOBAL);
    dlError = dlerror();
    printf("Open sharedLib.so returns: %s \n", dlError);
    if( dlError ) exit(1);

    //Find function
    Function = dlsym( FunctionLib, "getSomething");
    dlError = dlerror();
    printf("Find symbol getSomething returns: %s \n", dlError);
    if( dlError ) exit(1);
...

我正在使用以下命令编译代码

mips-linux-uclibc-gcc -Wall -ldl ./dynamic_linking.c -o /dynamic_linking

它可以在没有任何警告和东西的情况下工作。
如果我现在尝试在我的设备上执行此代码,我会收到以下错误:

# ./dynamic_linking
start...
Open sharedLib.so returns: (null)
Find symbol getSomething returns: Unable to resolve symbol
./dynamic_linking: can't resolv '_ZNSt8ios_base4InitD1Ev'

如果我使用 IDA 查看 sharedLib.so 想要导入的函数,我会看到函数(或符号?)“_ZNSt8ios_base4InitD1Ev”以及它应该在哪里 (libc.so.0)。
如果我再次使用 IDA 查看 libc.so.0,我看不到这样的函数。也不像 ios_base、ios 或 base。
我已经用 dlopen() 尝试了各种标志组合,这总是导致上述错误,除非我使用 RTLD_NOW 而不是 RTLD_LAZY 我得到

Segmentation fault (core dumped)

而不是

./dynamic_linking: can't resolv '_ZNSt8ios_base4InitD1Ev'

此外,我尝试了一些 gcc 链接选项,例如 rdynamic,总是得到相同的结果。
此外,我尝试使用不使用 _ZNSt8ios_base4InitD1Ev 的共享库,即“libc.so.0”来检查我的 c 代码是否正常工作。我只更改了名称和绝对路径,并删除了查找功能部分。它没有错误地工作。
正如您可能从我的帖子中看到的那样,我刚刚开始交叉编译和使用动态库,所以也许我的错在其他地方。此外,我不确定我是否明白问题出在哪里,所以欢迎任何提示。如果您需要更多信息,我很乐意将它们提供给您。
问候,平谷

【问题讨论】:

    标签: c shared-libraries


    【解决方案1】:

    _ZNSt8ios-base4InitD1Ev 不是 C 符号,而是 C++ 符号。

    $ echo _ZNSt8ios-base4InitD1Ev | c++filt
    

    不提供任何线索,但如果您将 - 替换为 _(可能是错字?):

    $ echo _ZNSt8ios_base4InitD1Ev | c++filt
    std::ios_base::Init::~Init()
    

    这就是 C++ STD 库内部类的析构函数。所以你应该检查libstdc++.so库而不是libc.so

    我的建议是只使用 G++ 编译您的程序,这样 C++ 库就可以正确初始化。它不打算动态加载,这就是分段错误的原因。

    【讨论】:

    • 感谢您的回答,我使用 mips-linux-uclibc-cpp -Wall ./dynamic_linking.c -o ./dynamic_linking 编译了该程序,并且编译时没有任何错误。我明天可以检查它是否可以在设备上运行,我会提供反馈。抱歉,- 而不是 _ 确实是一个错字。
    • @Pingu:但要小心! cpp 不是 GCC C++ 编译器的名称(应该是 g++c++。它是 C 预编译器的名称。如果 dynamic_linking 程序最终成为预编译器的输出会很有趣!
    • 我的设备没有 gcc c++ 编译器,但是阅读这篇文章,stackoverflow.com/questions/6626363/… 我认为可以使用 c++ std 库使用 gcc 编译代码。我会努力弄清楚的。
    • 终于让它与 gcc 和使用 libstdc++ 的大量标志一起工作。谢谢罗德里戈
    猜你喜欢
    • 2018-11-11
    • 1970-01-01
    • 2021-02-04
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多