来自 open() 的 return 结果代码之间的区别:25 与 3?

Difference between return result code from open(): 25 vs 3?

我正在使用 strace 调试 Qt 程序,open() 函数显示:

open("../libPlayCtrl.so", O_RDONLY|O_CLOEXEC)

在 returns 3 的情况下它似乎可以工作,但是当它 returns 25 时却没有,并且 libPlayCtrl.so 没有加载.

有什么区别?我该如何解决?

.so 文件是第 3 方库。不仅是这个,我还使用其他第三个库,它们来自同一供应商。其他一些 lib 文件获得了它们的 open(...) = 3,它们似乎工作正常。

编辑:

以下是 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

并且程序显示来自库(可能是其他)的错误:“无法加载播放器 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`

转到 open() 系统调用的手册页,您会发现 open() 的 return 值是新打开的文件描述符的编号的解释。

在 Google 中投入更多时间后,您一定会找到一个解释,即当打开一个新文件时,内核会为打开的文件分配最低可用的、未使用的文件描述符。就这些了。

综上所述,open() returned 3 or 25 or 17 or 8 都没有关系,都说明文件打开成功,你怀疑是其他非-零值表示某种问题不正确。

您的应用程序肯定会遇到某种问题,但它与来自 open() 的特定 return 值没有任何直接关系。

现在,事实本身有时您会看到 open() returning 3,有时是 25——这表明有几种方法可以在您的应用程序执行中达到这个特定点:打开的文件,标准输入、输出和错误除外;或者已经打开了至少 22 个某种类型的附加文件。完全合理的是,在后一种情况下,您的应用程序做了更多明显的工作,涉及在加载此库之前打开 22 个或更多文件,并遇到了某种问题。但实际问题本身与这个特定的系统调用完全无关。