【问题标题】:Difference between return result code from open(): 25 vs 3?open() 的返回结果代码之间的区别:25 与 3?
【发布时间】: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文件失败的原因,可能是我改变了程序的配置,而不是代码。 (并且新的代码使用相同的代码)。

标签: c++ qt strace


【解决方案1】:

去open()系统调用的手册页,你会发现open()的返回值是新打开的文件描述符的编号。

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

总之,open() 返回 3 或 25,或 17,或 8 都没有关系。它们都表明文件已成功打开,而您怀疑不同的非零值表明存在问题有些是不正确的。

您的应用程序肯定有某种问题,但它与 open() 的这个特定返回值没有任何直接关系。

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

【讨论】:

    猜你喜欢
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 2015-12-18
    • 1970-01-01
    相关资源
    最近更新 更多