与动态库链接导致的可执行运行时崩溃

Posted

技术标签:

【中文标题】与动态库链接导致的可执行运行时崩溃【英文标题】:Executable runtime crash caused by linking with dynamic library 【发布时间】:2013-12-20 16:28:02 【问题描述】:

堆栈:MIPS、Linux、C、C++ 使用 GNU 工具编译和链接(基于 x86 构建 MIPS)

公平警告:我是 C、C++ 新手,请随意提出任何可能显而易见的建议,因为我可能还没有尝试过。

我能够构建一个动态链接到库 (live555) 的可执行文件,如果我静态链接到它一切正常,但是当我尝试在运行时动态链接可执行文件时崩溃。为了确认我正在正确构建 .so 文件,我还尝试构建其他可执行文件(live555 附带的测试工具)以动态链接这些 .so 库,并且这些工具工作正常。

链接/构建似乎工作正常,构建过程中没有抛出错误或警告。我可以使用 readelf -d 检查崩溃的可执行文件并清楚地看到 .so 引用。我还可以在 MIPS 系统上的可执行文件上运行 ldd,并且库似乎加载正常,strace 输出也显示这些库正在加载。不幸的是,strace 输出并没有真正为我提供任何现场,我已经与熟悉该系统的其他人交谈,他们不确定问题是什么。

只是寻找想法和工具来尝试,如果有人有任何想法,我会适当的!

感谢阅读

【问题讨论】:

你的live555 库(里面的所有对象)是用-fPIC 编译的吗?这可能是一个可重定位的代码问题。 您是否使用符号 (-g) 编译并使用 gdb 运行程序?这样做你应该得到一个很好的回溯,指向崩溃发生的地方。 还可以链接同一库的 2 个版本 - 静态和动态。 启用故障转储生成 $> ulimit -c unlimited ;使用调试符号 -g 重新编译您的程序,然后运行 ​​gdb 或 DDD,加载故障转储并检查您的环境。 【参考方案1】:

这里没有足够的信息来开始深入故障排除。开始调试的一些想法,从最耗时到最耗时:

    在您的可执行文件上运行ldd 后,检查加载该库的路径,确保该库是您编译/链接的版本。简单的方法是在目标和主机上获取 MD5 哈希,确保它们相同。 还要检查以确保您没有安装多个库实例 仔细检查库的别名,确保它们指向同一个地方 尝试启用故障转储生成 $> ulimit -c unlimited,运行 gdb 或 DDD,加载故障转储并检查您的环境。 检查您的 CFLAGS,可能就像@YannRamin 所说的那样,您需要 -fPIC 用于 MIPS。您可以运行 make -n 来查看您的二进制文件是如何生成的。 检查目标上的LDPATH env 并确保它是合理的;顺便说一句,空的很好。 在编译/链接期间检查您的LDFLAGS。您可能必须运行make -n,查找gcc 命令或collect 命令,然后复制粘贴整行并将--verbose 添加到末尾,这样您就可以确切地看到链接器在做什么。您可能需要修复源文件/目标文件的路径,具体取决于构建系统的设置方式。

我们的想法是尝试消除潜在问题,例如:

错误的库版本:安装 vs 编译 多个位置/错误的别名 编译/链接时符号污染 许多其他人

你很幸运,你安装了 Linux,所以应该很容易,只是可能很耗时。

【讨论】:

以上是关于与动态库链接导致的可执行运行时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

动态链接库(转载)

Linux之静态库与动态库20160706

Linux学习——动态链接库和静态链接库

Linux动态和静态链接

常用动态链接库的DLL都有哪些?

动态链接库与静态链接库的区别