LINUX.ORG.RU

fclose вылетает с SIGABRT


0

1

Столкнулся со странной проблемой. Есть функция, которая по какой-то причине валится. Я пытаюсь организовать вывод отладочных сообщений из нее в файл. Помимо этого она вызывает другие функции из того же файла, которые я тоже хочу залоггировать.

Пишу:

FILE *fp = NULL;

void f(void){
if (!fp) fp = fopen(«/tmp/log.txt», «a»);
...
if (fp) fprintf(fp, «something happened in f()\n»);
...
f2();
...
if (fp) fclose(fp);
return;
}

void f2(void)
{
if (fp) fprintf(fp, «something happened in f2()\n»);
}



т.е. вызов f2 меня интересует только если он происходит из f(), которая инициализирует указатель на файл. По идее все должно быть нормально, по факту нормально работает только первый раз, когда вызывается f(). Если она вызывается в цикле, то на втором fclose() программа вылетает с sigabrt. Если я переношу объявление *fp внутрь f() и убираю логи из f2(), все работает. Но мне нужно и из f2() логгировать тоже. Как можно наименее затратно это решить?

Цикл, вызывающий f() находится в другом файле, изменять который нельзя. Точнее можно, но нет смысла - f() и f2() это части библиотеки, которая линкуется статически к приложению, я тестирую с одной оберткой поверх библиотеки, чувак, у которого проблема проявляется - с другой, но т.к. проблема точно в самой библиотеке, то это не важно

★★★

Последнее исправление: marvin_yorke (всего исправлений: 1)

Ответ на: комментарий от geekless

черт, а ведь верно, с чего я взял, что fclose поинтер зануляет.. должно сработать, спасибо

marvin_yorke ★★★
() автор топика

На втором вызове функции fp уже не NULL, и указывает вообще в никуда, то есть первое условие, по которому открывается файл уже не отработает. Закрыть-то его в первом вызове закрыли, а переменную обнулять не надо??

Кроме того, сделано совсем неправильно. Если надо логи писать пишется пара функций, грубо говоря так: open_syslog - инициализировать логирование write_syslog - записать что-то, внутри проверяется, была ли инициализация и если нет вызывается open_syslog close_syslog - закрыть логирование.

А всякие глобальные fp прячутся в отдельном модуле, лучше всего

static FILE *fp = NULL;

grondek
()

Кстати лучше для таких вещей использовать syslog, а не открывать файл. Единственное, что там сложно большие структуры печатать...

rymis ★★
()
Ответ на: комментарий от rymis

когда нужно постоянное решение - согласен. Но мне нужен одноразовый фикс, чтобы локализовать проблему. В сислог, помимо этого, срет еще миллиард сервисов, следовательно надо syslogd настраивать, чтобы логи от этого процесса отправлял в другой файл.. овчинка того не стоит

marvin_yorke ★★★
() автор топика

if (fp) { fclose(fp); fp = NULL; } ... сказала монашка одевая на свечку второй самзнаешьчё ;)

aol ★★★★★
()
Последнее исправление: aol (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.