轻松检查共享库中未解析的符号?

我正在编写一个相当大的C ++共享对象库,并且遇到了一个小问题,使得调试变得非常痛苦:

如果我在头文件中定义一个函数/方法,并忘记为它创建一个存根(在开发过程中),由于我正在构建为共享对象库而不是可执行文件,所以在编译时没有错误显示我有忘记执行该功能。 我发现某件事情的唯一方法是错误的,那就是在运行时,最终一个链接到这个库的应用程序会因为'未定义符号'错误而崩溃。

我正在寻找一种简单的方法来检查编译时是否有所需的所有符号,也许我可以将其添加到我的Makefile中。

我提出的一个解决方案是通过nm -C -U运行编译的库,以获取所有未定义引用的demangled列表。 问题是这也出现在其他库中的所有引用列表中,例如GLibC,当最终应用程序放在一起时,这些链接当然会与此库链接。 有可能使用nm的输出grep通过我所有的头文件,并查看是否有任何名称对应..但这似乎是疯了。 这当然不是一个不常见的问题,有更好的解决方法吗?


查看链接器选项-z defs / --no-undefined 。 创建共享对象时,如果有未解析的符号,将导致链接失败。

如果您使用gcc调用链接器,那么您将使用编译器-Wl选项将该选项传递给链接器:

gcc -shared ... -Wl,-z,defs

作为一个例子,考虑下面的文件:

#include <stdio.h>

void forgot_to_define(FILE *fp);

void doit(const char *filename)
{
    FILE *fp = fopen(filename, "r");
    if (fp != NULL)
    {
        forgot_to_define(fp);
        fclose(fp);
    }
}

现在,如果将其构建到共享对象中,它将会成功:

> gcc -shared -fPIC -o libsilly.so silly.c && echo succeeded || echo failed
succeeded

但是如果你添加-z defs ,链接将会失败并告诉你关于你丢失的符号:

> gcc -shared -fPIC -o libsilly.so silly.c -Wl,-z,defs && echo succeeded || echo failed
/tmp/cccIwwbn.o: In function `doit':
silly.c:(.text+0x2c): undefined reference to `forgot_to_define'
collect2: ld returned 1 exit status
failed

在Linux上(你似乎正在使用) ldd -r a.out应该给你准确的答案你正在寻找。

更新:一个简单的方法来创建a.out来检查:

 echo "int main() { return 0; }" | g++ -xc++ - ./libMySharedLib.so
 ldd -r ./a.out

那么测试套件呢? 您创建链接到您需要的符号的模拟可执行文件。 如果链接失败,则意味着您的库接口不完整。

链接地址: http://www.djcxy.com/p/42611.html

上一篇: Easy check for unresolved symbols in shared libraries?

下一篇: C++ shared library shows internal symbols