Портировал я давеча один непутевый код с SUN на Linux
И программа все время валилась c Segmentation fault
притом самое интересное что было это внутри fclose()
Спасибо людям что открыли мне прекрассный тулз valgrind
Он и раскрыл мне глаза на то что в одном месте файл открытый на чтение
закрывался дважды (заметьте не тот файл при закрытии которого был
Segmentation fault)
А возмутило меня другое Анализ лога valgrind показал что библиотечные
функции fprintf, fclose вовсю юзают malloc, free
Не порядок однако
Ошибки при работе с памятью в моих программах не должны влиять на работу
библиотечных функций и наоборот
Повторное (случайное) закрытие файла влечет за собой харакири всей кучи
Здравствуйте, Кирпа В.А., Вы писали:
КВА>Портировал я давеча один непутевый код с SUN на Linux
КВА>И программа все время валилась c Segmentation fault КВА>притом самое интересное что было это внутри fclose() КВА>Спасибо людям что открыли мне прекрассный тулз valgrind КВА>Он и раскрыл мне глаза на то что в одном месте файл открытый на чтение КВА>закрывался дважды (заметьте не тот файл при закрытии которого был КВА>Segmentation fault)
close(fd);
fd = -1;
ну и анализировать возврат из close.
КВА>А возмутило меня другое Анализ лога valgrind показал что библиотечные КВА>функции fprintf, fclose вовсю юзают malloc, free
Здравствуйте, execve, Вы писали:
E>Здравствуйте, Кирпа В.А., Вы писали:
КВА>>Портировал я давеча один непутевый код с SUN на Linux
КВА>>И программа все время валилась c Segmentation fault КВА>>притом самое интересное что было это внутри fclose() КВА>>Спасибо людям что открыли мне прекрассный тулз valgrind КВА>>Он и раскрыл мне глаза на то что в одном месте файл открытый на чтение КВА>>закрывался дважды (заметьте не тот файл при закрытии которого был КВА>>Segmentation fault)
E>
E>close(fd);
E>fd = -1;
E>
E>ну и анализировать возврат из close.
Покатим бочку на Linux дальше
Это же как надо тупо реализовать библиотечные функции ввода/вывода
чтобы повторное закрытие файла ломало heap
кстати повторное закрытие файла в SUN, Windows ничего вредного не делает
КВА>>А возмутило меня другое Анализ лога valgrind показал что библиотечные КВА>>функции fprintf, fclose вовсю юзают malloc, free
E>А какие функции они должны юзать?
Раз они юзают malloc, free то пусть будут добры не попадать в условия когда
портится heap (например повторное закрытие файла)
On Mon, 12 Dec 2005 11:37:36 -0000, Кирпа В.А. <5450@users.rsdn.ru> wrote:
[]
> Покатим бочку на Linux дальше > Это же как надо тупо реализовать библиотечные функции ввода/вывода > чтобы повторное закрытие файла ломало heap > кстати повторное закрытие файла в SUN, Windows ничего вредного не делает
Сиди в виндозе и радуйся жизни.
> КВА>>А возмутило меня другое Анализ лога valgrind показал что библиотечные > КВА>>функции fprintf, fclose вовсю юзают malloc, free > > E>А какие функции они должны юзать? > > Раз они юзают malloc, free то пусть будут добры не попадать в условия когда > портится heap (например повторное закрытие файла)
Лучше пусть они маскируют ошибки в твоем коде, так?
Здравствуйте, Кирпа В.А., Вы писали:
КВА>Раз они юзают malloc, free то пусть будут добры не попадать в условия когда КВА>портится heap (например повторное закрытие файла)
Хм... не нужно попадать в условия, когда возможно повторное закрытие файла.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, Кирпа В.А., Вы писали:
КВА>>Раз они юзают malloc, free то пусть будут добры не попадать в условия когда КВА>>портится heap (например повторное закрытие файла)
ДД>Хм... не нужно попадать в условия, когда возможно повторное закрытие файла.
Так и знал что всех собак повесят на меня
Я не любитель повторного закрытия файла и знаю что закрыть файл необходимо и достаточно один раз
Как я говорил я просто портировал чужой проект
Я лишь знаю что системная библиотека ввода/вывода не должна разрушать кучу ни при каких условиях
Повторное fclose() должно завершиться с ошибкой В errno должен быть установлен соотвествующий код ошибки
А возражения MaximE Ну и сиди в Винде и радуйся жизни не принимаются
КВА>Покатим бочку на Linux дальше КВА>Это же как надо тупо реализовать библиотечные функции ввода/вывода КВА>чтобы повторное закрытие файла ломало heap КВА>кстати повторное закрытие файла в SUN, Windows ничего вредного не делает
В Windows они ничего вредного не делают, потому что как я предполагаю, все эти функции реализованы через CreateFile(), CloseHandle(). А когда им передать неправильный хэндл, они его просто не находят в таблице открытых хэндлов и всё. В Линуксе наверно никаких таблиц нет, функция просто работает с указателем, считая
его правильным по умолчанию.
Здравствуйте, Кирпа В.А., Вы писали:
КВА>Я лишь знаю что системная библиотека ввода/вывода не должна разрушать кучу ни при каких условиях КВА>Повторное fclose() должно завершиться с ошибкой В errno должен быть установлен соотвествующий код ошибки
fclose принимает на вход указатель.
Вполне возможно, что он что-то пишет по этому указателю.
Если ты подсовываешь ему указатель неизвестно на что, то как он обнаружит, что этот указатель невалидный?
В результате и получаем странное: разрушение кучи.
На самом деле проверку на валидность указателя можно сделать (free с какими-то флагами ЕМНИПС уже умеет это), но её добавление ударит либо по производительности, либо по объёму используемой памяти.
Здравствуйте, MaximE, Вы писали:
ME>Сиди в виндозе и радуйся жизни.
Грубить-то зачем? После подобных ответов окружающие начинают к юниксоидам относиться как красноглазым пионерам.
ME>Лучше пусть они маскируют ошибки в твоем коде, так?
Тем более, что выдвинутый тобою тезис, сводящийся к тому, что в операционной системе всякого рода защита от кривых приложений — вещь ненужная, не выдерживает никакой критики.
Здравствуйте, Кирпа В.А., Вы писали:
КВА>Как я говорил я просто портировал чужой проект
if (f)
{
fclose(f);
f = NULL;
}
КВА>Я лишь знаю что системная библиотека ввода/вывода не должна разрушать кучу ни при каких условиях КВА>Повторное fclose() должно завершиться с ошибкой В errno должен быть установлен соотвествующий код ошибки
Не забывайте, что FILE — это структура, и fopen() распределяет память под нее, а fclose() освобождает. При повторном вызове fclose аргумент уже указывает неизвестно на что и close(2) не может даже прочитать значение дескриптора. close(2), кстати, корректно возвращает "Bad file descriptor".
Или вы предлагаете при каждом free() делать проверку на валидность блока?
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
ДД>Не забывайте, что FILE — это структура, и fopen() распределяет память под нее, а fclose() освобождает. При повторном вызове fclose аргумент уже указывает неизвестно на что и close(2) не может даже прочитать значение дескриптора. close(2), кстати, корректно возвращает "Bad file descriptor". ДД>Или вы предлагаете при каждом free() делать проверку на валидность блока?
Ну вот и начался конструктивный диалог
Я веду к тому что в библиотеке ввода/вывода необходим список открытых файлов
что-то типа std::vector<FILE *>
в который fopen добавляет а fclose удаляет
Тогда проверка на валидность указателя FILE * элементарна
Вывод: реализация библиотеки ввода/вывода в Linux — кривовата
Здравствуйте, Кирпа В.А., Вы писали:
ДД>>Не забывайте, что FILE — это структура, и fopen() распределяет память под нее, а fclose() освобождает. При повторном вызове fclose аргумент уже указывает неизвестно на что и close(2) не может даже прочитать значение дескриптора. close(2), кстати, корректно возвращает "Bad file descriptor". ДД>>Или вы предлагаете при каждом free() делать проверку на валидность блока? КВА>Ну вот и начался конструктивный диалог КВА>Я веду к тому что в библиотеке ввода/вывода необходим список открытых файлов КВА>что-то типа std::vector<FILE *> КВА>в который fopen добавляет а fclose удаляет КВА>Тогда проверка на валидность указателя FILE * элементарна
КВА>Вывод: реализация библиотеки ввода/вывода в Linux — кривовата
Странный вывод... Почему тогда нет претензий к коредампу на, к примеру, вот это:
int *a = 0xdeadbeaf;
*a = 17;
? И к прочим радостям при работе с невалидной памятью?..
Здравствуйте, Кирпа В.А., Вы писали:
КВА>Ну вот и начался конструктивный диалог КВА>Я веду к тому что в библиотеке ввода/вывода необходим список открытых файлов КВА>что-то типа std::vector<FILE *> КВА>в который fopen добавляет а fclose удаляет
Допустим, программа открывает файл f1, получает как результат указатель p1. fopen() добавляет этот указатель в список валидных. Программа работает с ним, потом закрывает. fclose() закрывает f1 и удаляет p1 из списка. Программа открывает другой файл f2, указатель возвращается численно равный p1 (ну, аллокатор так вернул). Потом следует повторное закрытие f1 и работа с f2. Каковы будут последствия?
КВА>Вывод: реализация библиотеки ввода/вывода в Linux — кривовата
В данном случае реализация библиотеки критична к грубым ошибкам в приложении.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, Кирпа В.А., Вы писали:
КВА>>Ну вот и начался конструктивный диалог КВА>>Я веду к тому что в библиотеке ввода/вывода необходим список открытых файлов КВА>>что-то типа std::vector<FILE *> КВА>>в который fopen добавляет а fclose удаляет
ДД>Допустим, программа открывает файл f1, получает как результат указатель p1. fopen() добавляет этот указатель в список валидных. Программа работает с ним, потом закрывает. fclose() закрывает f1 и удаляет p1 из списка. Программа открывает другой файл f2, указатель возвращается численно равный p1 (ну, аллокатор так вернул). Потом следует повторное закрытие f1 и работа с f2. Каковы будут последствия?
Никаких
Работа с f2 уже невозможна потому что он закрыт Любая работа с файлом не только fclose (но и fprintf и т д) идут через валидацию указателя на файл
FILE *f1 = fopen("/tmp/1", "w");
FILE *f2 = f1;
fclose(f2);
fprintf(f1, "%s\n", "Ups"); // упс файл закрыт
fclose(f1); // упс файл закрыт
КВА>>Вывод: реализация библиотеки ввода/вывода в Linux — кривовата
ДД>В данном случае реализация библиотеки критична к грубым ошибкам в приложении.
Здравствуйте, ДимДимыч, Вы писали:
КВА>>>Вывод: реализация библиотеки ввода/вывода в Linux — кривовата
ДД>>В данном случае реализация библиотеки критична к грубым ошибкам в приложении.
ДД>Кстати, при повторном вызове fclose() сразу же после первого вызова glibc вполне внятно сообщает о ДД>
Здравствуйте, Кирпа В.А., Вы писали:
КВА>Здравствуйте, ДимДимыч, Вы писали:
КВА>>>>Вывод: реализация библиотеки ввода/вывода в Linux — кривовата
ДД>>>В данном случае реализация библиотеки критична к грубым ошибкам в приложении.
Ваше приложение криво написанно — 2 раза закрывается 1 файл.
Действия системы при детектировании этого события — закрыть ваше приложение.
Не вижу никаких проблемм. . Правда закрывают вас не совсем коректно это да.
Здравствуйте, Кирпа В.А., Вы писали:
КВА>Здравствуйте, ДимДимыч, Вы писали:
КВА>>>>Вывод: реализация библиотеки ввода/вывода в Linux — кривовата
ДД>>>В данном случае реализация библиотеки критична к грубым ошибкам в приложении.
ДД>>Кстати, при повторном вызове fclose() сразу же после первого вызова glibc вполне внятно сообщает о ДД>>
_>а к реализации free и malloc у вас нет притензий?
_>тоже библиотечные функции и тоже могут разрушить кучу.
_>немного непонятная притензий для меня, это "кривоватая" реализация _>помогла вам найти и исправить ошибку
Так ошибки не было Ну подумаеш два раза закрыли файл
Для надежности
Так нет эту оплошность разработчики библиотеки ввода-вывода умудрились
преобразовать в Segmentation fault