【问题标题】:How to identify which file implicitly relies on linkage with a library?如何识别哪个文件隐式依赖于与库的链接?
【发布时间】:2019-08-16 15:02:06
【问题描述】:

我正在从事嵌入式项目。我已经在其中集成了开源子项目(即我没有编写的代码)。 编译很好,但我有链接错误:

gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc.a(lib_a-abort.o):
In function `abort': abort.c:(.text.abort+0xa): undefined reference to `_exit'
gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc.a(lib_a-signalr.o):
In function `_kill_r': signalr.c:(.text._kill_r+0x10): undefined reference to `_kill'
gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc.a(lib_a-signalr.o):
In function `_getpid_r': signalr.c:(.text._getpid_r+0x0): undefined reference to `_getpid' collect2: error: ld returned 1 exit status

我也有关于未定义引用 _exit 的错误,但我通过搜索和替换对 exit(1) 的调用修复了这些错误。

我尝试搜索和替换对abort() 的调用,但仍然出现这些错误。

我发现通过添加链接器选项-specs=nosys.specs 解决了一些类似的问题,但这不是我想要的。 我想修改代码,这样我就可以优雅地处理错误,而不会粗暴地退出整个程序,为此我必须找到哪个代码依赖于这个链接。

【问题讨论】:

  • 函数的文档应该包括定义它的头文件和实现/提供它的库。
  • 我将libc.a 解释为(打算成为)C 标准库的静态版本。高度怀疑此类库中的函数会依赖于该库之外的任何内容,并且某些细节看起来更加可疑。我认为该库可能没有正确构建。
  • 你不应该替换调用,你应该自己实现调用。如果你导入一个使用 getpid 和 kill 的库,那么你应该在你的目标系统上实现它们。您应该在目标上实现 _kill_getpid_exit 函数并决定它们应该做什么。 gcc-arm-none-eabi 是“裸机”,没有操作系统。值得注意的是,gcc(默认情况下)使用newlib 作为它的标准库实现。为什么nosys.specs 会让你的程序“野蛮退出”?
  • 您导入的代码假设环境不存在,例如。您可以在进程上调用 getpid 。如果您的裸机目标没有实现 posix 回调,您必须实现它们才能使用 posix 兼容代码。 nosys.specs 只是与“没有 posix 和 c 调用的系统实现”链接,即。大多数 posix 调用返回 -1 并将 errno 设置为 ENOSYS 或类似的。可以在here 找到实现。并非所有呼叫都被屏蔽。
  • I have integrated open source sub-projects - 哪些项目? I fixed these by searching & replacing calls to exit(1) - 你是如何修复它们的?你用什么代替了它们? -specs=nosys.specs but this is not what I want 为什么 nosys.specs 会让你“粗暴地退出整个程序”?

标签: c gcc linker arm


【解决方案1】:

我尝试搜索和替换对 abort() 的调用,但仍然出现这些错误。

认为您在问:“如何找到调用 abort 的代码(在替换所有可以找到的调用之后)?”

如果这确实是您的问题,请使用 -y 链接器选项。例如:

gcc main.o foo.o bar.o -Wl,-y,abort

/usr/bin/ld: bar.o: reference to abort
/usr/bin/ld: //lib/x86_64-linux-gnu/libc.so.6: definition of abort

附:您对.../v7e-m/fpv4-sp/hard/libc.a 的构建非常不寻常:通常,如果它定义了abortexit,它应该定义_exit

【讨论】:

  • 这正是我想要的。电话来自使用assert。现在我可以定义NDEBUG 或使用我自己的asser 实现。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多