【问题标题】:When does the value of file descriptor become "-1"?文件描述符的值何时变为“-1”?
【发布时间】:2015-01-19 06:42:43
【问题描述】:

我在 CPP 中有一个多线程程序,它具有用于整个代码的日志记录功能。使用 fopen() 在主函数中打开一个日志文件,该日志记录函数将传递给日志记录函数的字符串写入其中。该函数还检查文件大小。如果它大于某个值,它使用 fclose() 关闭文件并使用 fopen() 打开一个新文件。这里的问题是我在 valgrind 日志“系统调用 write() 中的无效文件描述符 -1”中看到了这个错误。我想知道文件描述符的值变为-1的可能原因是什么。我还观察到在对打开的文件描述符进行任何操作的行上出现“无效的读/写”错误。这让我觉得可能是文件描述符的这个值导致了这个错误。任何提示将不胜感激。

【问题讨论】:

  • 如果 open 返回 -1 它是一个错误指示符,可以在手册页等中看到...如果您使用此“文件描述符”进行读/写,则第一次没有检查错误地方,你应该做的。 open(...) 失败的原因可能有很多。如果它“突然”发生,即文件路径有效,则权限正常。并且磁盘上有足够的空间,很可能您的进程打开了太多文件。操作系统有每个进程的最大 opn 文件数。
  • 对不起,我忘了说我使用的是 fopen() 和 fclose() 而不是 open() 和 creat()。
  • 其他函数可能会在你背后使用 open/creat,也可能不会检查它们是否有有效的 fd。我的猜测仍然是您打开的文件太多...

标签: c++ linux valgrind file-handling


【解决方案1】:

查看打开的手册页

---从手册页中截取--------

RETURN VALUE
   open() and creat() return the new file descriptor, or -1 if an error occurred (in which     case, errno is set appropriately).

显然,您的代码没有检查文件描述符 (-1) 上的错误情况并继续进行读/写,因此您看到了错误。

编辑(解释 w.r.t fopen)

您打开的每个文件都与一个文件描述符相关联(无论您使用的是 fopen 的事实)。 Valgrind 正在跟踪您的系统调用跟踪(读/写)。 FILE* 只是文件描述符的包装器。因此,与“-1”fd 相关的错误语句仍然表明您正在读取/写入无效的文件(可能是您的进程用尽了要分配的最大 fd)等。为了理解它,我建议进行系统调用使用“strace”跟踪您的过程。您会看到“fopen”(用户/库级别 api)在内部调用“open”(系统调用)。

希望对你有帮助!

【讨论】:

  • 同意,但 fopen() 函数返回一个 FILE 指针。否则,返回 NULL 并设置全局变量 errno 以指示错误。由于 fopen() 返回一个 FILE* 您不能指望它在该指针中返回一个错误代码。指针的唯一“特殊”值是 0
【解决方案2】:

如果多个线程使用同一个 FILE*,那么如果对 fopen、fclose 和 fwrite 的所有调用都没有锁定,则可能会遇到许多问题。当您重新打开文件时,可能有另一个线程试图写入它。 fwrite 还执行缓冲写入,并且在缓冲区上操作的多个线程可能会导致内存损坏。

【讨论】:

  • 两个答案都帮助我调试和解决了问题。这确实发生了,因为没有实现锁,当两个不同的线程试图同时读取它时,fd 值被破坏了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 2014-04-25
  • 2015-07-25
  • 1970-01-01
  • 2018-03-10
相关资源
最近更新 更多