与动态库链接导致的可执行运行时崩溃
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,所以应该很容易,只是可能很耗时。
【讨论】:
以上是关于与动态库链接导致的可执行运行时崩溃的主要内容,如果未能解决你的问题,请参考以下文章