Когда значение дескриптора файла становится равным -1?

У меня есть многопоточная программа в CPP, в которой есть функция ведения журнала, которая используется во всем коде. Файл журнала открывается в основной функции с помощью fopen(), и эта функция ведения журнала записывает в него строку, переданную функции ведения журнала. Также функция проверяет размер файла. Если оно больше некоторого значения, он закрывает файл с помощью fclose() и открывает новый файл с помощью fopen(). Вопрос здесь в том, что я видел эту ошибку в журналах valgrind «неверный файловый дескриптор -1 в системном вызове write ()». Я хочу знать, каковы возможные причины того, что значение дескриптора файла становится -1. Я также наблюдал ошибку «Недопустимое чтение/запись» в строках, где выполняется любая операция с дескриптором открытого файла. Это заставляет меня чувствовать, что именно это значение дескриптора файла может вызывать эту ошибку. Любые подсказки будут высоко оценены.


person iqstatic    schedule 21.11.2014    source источник
comment
Если open возвращает -1, это индикатор ошибки, что можно увидеть на справочных страницах и т. д. Если вы используете этот файловый дескриптор для чтения/записи, вы в первую очередь не проверяли наличие ошибок, что вы должны сделать. Причин сбоя open(...) может быть много. Если это произойдет внезапно, то есть путь к файлу действителен, разрешения в порядке. и на диске достаточно места, скорее всего, в вашем процессе открыто слишком много файлов. ОС имеет максимальное количество файлов opn на процесс.   -  person Oncaphillis    schedule 21.11.2014
comment
Извините, я забыл упомянуть, что я использую fopen() и fclose(), а не open() и creat().   -  person iqstatic    schedule 21.11.2014
comment
Ну, другие функции могут использовать open/creat за вашей спиной, а также могут не проверять, есть ли у них действительный fd. Я предполагаю, что у вас слишком много открытых файлов...   -  person Oncaphillis    schedule 21.11.2014


Ответы (2)


Если несколько потоков используют один и тот же ФАЙЛ*, то вы можете столкнуться с рядом проблем, если не будет блокировки всех вызовов fopen, fclose и fwrite. Пока вы повторно открываете файл, может быть другой поток, пытающийся записать в него. fwrite также выполняет запись в буфер, и несколько потоков, работающих с буфером, могут привести к повреждению памяти.

person Reilly Grant    schedule 21.11.2014
comment
Оба ответа помогли мне отладить и решить проблему. Это действительно происходило, поскольку блокировка не была реализована, и когда два разных потока пытались прочитать ее одновременно, значение fd было повреждено. - person iqstatic; 01.12.2014

Посмотрите на открытую справочную страницу

--- вырезка из справочной страницы ---------

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

Очевидно, что ваш код не проверяет состояние ошибки в дескрипторе файла (-1) и продолжает чтение/запись, поэтому вы видите ошибку.

Изменить (пояснение относительно fopen)

Каждый открываемый вами файл связан с файловым дескриптором (независимо от того, используете ли вы fopen). Valgrind отслеживает трассировки ваших системных вызовов (чтение/запись). FILE* — это всего лишь оболочка над файловым дескриптором. Таким образом, сообщения об ошибках, связанные с "-1" fd, по-прежнему указывают на то, что вы читаете/записываете в недопустимый файл (возможно, ваш процесс исчерпал максимальное количество fd для выделения) и т. д. Чтобы понять это, я бы рекомендовал выполнить системный вызов трассировка вашего процесса с помощью "strace". вы увидите, что "fopen" (API уровня пользователя/библиотеки) внутренне вызывает "open" (системный вызов).

Надеюсь, поможет!

person sanjayk79    schedule 21.11.2014
comment
Согласен, но функция fopen() возвращает указатель FILE. В противном случае возвращается NULL, а глобальная переменная errno устанавливается для указания ошибки. Поскольку fopen() возвращает FILE*, вы не можете ожидать, что он вернет код ошибки в этом указателе. Единственным специальным значением для указателей является 0 - person iqstatic; 21.11.2014