4

我有一个应用程序在启动时将 .so 文件加载为插件,使用dlopen()

构建环境在 x86 硬件上运行,但应用程序正在针对另一个平台进行交叉编译。

如果我可以(作为自动构建过程的一部分)进行检查以确保 .so 文件和应用程序的组合中没有任何未解析的符号,而无需实际部署应用程序,那就太好了。

在我编写脚本来使用 的输出测试符号之前nm,我想知道是否有人知道已经这样做的实用程序?


编辑1:稍微改变了描述——我不只是试图测试.so中的符号,而是结合几个.so和应用程序本身——即。在应用程序加载所有 .so 之后,是否还会有未解析的符号。

正如答案中所建议的那样(感谢 Martin v. Löwis 和 tgamblin),nm将很容易识别单个文件中丢失的符号,但不容易识别在其他加载的模块之一中已解决哪些符号。

4

3 回答 3

2

理想情况下,cross-nm 工具是您的交叉编译器套件的一部分。例如,如果您构建 GNU binutils 用于交叉编译,则还将提供一个 cross-nm(以及一个 cross-objdump)。

于 2008-11-06T22:37:05.507 回答
1

您可以为此使用递归版本的 ldd 吗?似乎有人写了一个可能有帮助的脚本。这至少告诉您所有依赖库都可以解析,如果它们首先在 .so 中正确指定。您可以使用链接器选项保证在 .so 中引用所有依赖项,并且这个加上递归 ldd 将保证您没有未解析的符号。

链接器通常可以选择使共享库中未解析的符号成为错误,您可以使用它来完全避免检查。对于 GNU ld,您可以只传递 --no-allow-shlib-undefined 并且保证如果它生成 .so,它不会有未解析的符号。来自 GNU ld 文档:

   --no-undefined
       Report  unresolved  symbol  references  from regular object files.
       This is done even if the linker is creating a non-symbolic shared 
       library.  The switch --[no-]allow-shlib-undefined controls the 
       behaviour for reporting  unresolved references found in shared
       libraries being linked in.

   --allow-shlib-undefined
   --no-allow-shlib-undefined
       Allows (the default) or disallows undefined symbols in shared 
       libraries.  This switch is  similar  to  --no-undefined  except
       that  it determines the behaviour when the undefined symbols are
       in a shared library rather than a regular object file.  It does 
       not affect how undefined symbols in regular object files are 
       handled.

       The reason that --allow-shlib-undefined is the default is that the 
       shared library being specified  at  link  time may  not  be  the  
       same as the one that is available at load time, so the symbols might 
       actually be resolvable at load time.  Plus there are some systems, 
       (eg BeOS) where undefined symbols in shared libraries is  normal.   
       (The kernel patches them at load time to select which function is most
       appropriate for the current architecture.  This is used for example to
       dynamically select an appropriate memset function).  Apparently it is 
       also normal for HPPA shared libraries to have undefined symbols.

如果您要进行链接后检查,我同意 Martin 的观点,nm 可能是您最好的选择。我通常只是在输出中用 grep 搜索“U”来检查未解析的符号,所以我认为这将是一个非常简单的脚本。

于 2008-11-06T22:45:07.953 回答
1

事实证明,这些限制nm意味着无法用于全面的符号检查器。特别是,nm只会列出导出的符号。

但是,readelf将生成一个完整的列表,以及所有库依赖项。

使用readelf它可以构建一个脚本,它将:创建所有使用的库的列表,在可执行文件(或 .so)中构建符号列表 构建未解析符号列表 - 如果有任何未解析符号此时,加载时会出现错误。

然后重复此操作,直到找不到新库。

如果对可执行文件和所有dlopen()ed .so 文件执行此操作,它将很好地检查运行时遇到的未解决的依赖关系。

于 2009-03-27T00:45:19.843 回答