【发布时间】:2016-02-24 01:42:07
【问题描述】:
我正在使用 strace 调试 Qt 程序,open() 函数显示:
open("../libPlayCtrl.so", O_RDONLY|O_CLOEXEC)
在它返回 3 的情况下,它似乎可以工作,但是当它返回 25 时它不会,并且 libPlayCtrl.so 没有加载。
有什么区别?我该如何解决?
.so 文件是第 3 方库。不仅是这个,我还使用其他第三个库,它们来自同一个供应商。其他一些 lib 文件获得了它们的 open(...) = 3,它们似乎工作正常。
- 平台:Ubuntu 12.04,32 位。
- Qt4.8
- QtCreator 2.4.1
- 编译器:GCC
编辑:
下面是 strace 输出的一部分, 由于我更改了配置,.so 文件的位置不同。成功的 .so 文件是来自供应商的较新版本的 lib。
成功案例: 总共15个子句才最终找到.so文件。
open("../lib/tls/i686/sse2/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/tls/i686/sse2/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/tls/i686/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/tls/i686/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/tls/sse2/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/tls/sse2/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/tls/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/tls/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/i686/sse2/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/i686/sse2/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/i686/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/i686/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/sse2/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/sse2/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("../lib/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = 3
失败案例:
省略号表示大约有 95 个open() 子句都等于-1(未找到)。正如你所看到的,这次它终于找到了 .so 文件时变成了30。
程序显示来自库的错误(可能是其他错误):“Failed to load player SDK”。
.....
21:02:33 open("./sse2/cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
21:02:33 open("./sse2/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
21:02:33 open("./cmov/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
21:02:33 open("./libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
21:02:33 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 30
21:02:33 open("/.../.../.../RemoteClient/lib/libPlayCtrl.so", O_RDONLY|O_CLOEXEC) = 30`
【问题讨论】:
-
我认为您应该发布您的源代码,否则很难推测。当你得到
3时,这意味着open在程序启动后不久就完成了。当您收到25时,这意味着 fds 0-2 和 3-24 已被占用。在后一种情况下,这些单元上正在打开什么 [以及为什么]?此外,针对这两种情况发布一些strace输出可能也会有所帮助。 -
correlation does not imply causation。如果open() 的返回结果是-1,那么这意味着你有一个错误(你得到了
errno)。但是如果你得到一个正整数,调用成功并且它是一个“文件句柄”......基本上被视为一个黑匣子。操作系统理论上可以给你它想要的任何数字。将您的问题简化为MVCE,其他人可以编译并查看相同的问题。 -
"由于我更改了配置,.so文件的位置不同。成功的.so文件是来自供应商的较新版本的lib。"嗯...好吧,那么您为什么会怀疑 30 与 3 与问题的关系比可能包含可能完全不同的代码更多? strace 不是解决此类问题的有效调试工具,您需要真正使用调试器,而且不同的 lib 版本经常(或实际上,通常)不能一起工作。
-
@HostileFork 所以原因是旧的 .so 文件用于在另一个类似的示例程序中工作(在这个特定部分几乎相同的代码)。在我的程序中,我使用它。但是在对这两个程序进行了一些更改之后(ubuntu 也进行了一些更新),而不是库,它没有工作。另外,我查看了新 SDK 和旧 SDK 的手册,没有发现对这个 lib 文件的更改。所以我猜这个旧的 .so 文件应该可以工作。
-
@HostileFork 我完全忘记了我对这两个程序所做的事情,可能是对配置左右(但不是代码)。所以简单来说,旧的.so文件失败的原因,可能是我改变了程序的配置,而不是代码。 (并且新的代码使用相同的代码)。