skl>>2) Я понимаю, что это скорее сишный код в методе, но я не знаю как с помощью файловых потоков С++ задать неблокируемый режим для файла на чтение (т. е. флаг O_NONBLOCK). Буду благодарен за подсказку как это сделать при помощи файловых потоков С++. CS>Ты зовешь read() и не дожидаясь его завершения — close() и более того разрушаешь буффер. понятно что упадет где-нибудь. CS>Мне кажется тв не понимаешь как работатет O_NONBLOCK — т.е. не блокирующий IO
это юникс, тут все не так)
виндовс-стайл асинк-IO тут делается через это или это
Как много веселых ребят, и все делают велосипед...
Re: Непонятная ошибка при закрытии дескриптора файла
skl>int FromFtpForm::getBarcode()
skl>{
skl> int barcode_fd;
skl> char buf_barcode[150];
skl> barcode_fd = open("/dev/ttyACM0", O_RDONLY| O_NONBLOCK);
skl> if (barcode_fd < 0) return -1;
skl> for (int i=0; i<150; i++) buf_barcode[i] = '\0';
skl> read(barcode_fd, buf_barcode, sizeof(buf_barcode));
skl> close(barcode_fd); // Если этот убрать, то программа работает, если оставить, то падает
skl> return 0;
skl>}
skl>
Это не минимальный падающий код. Минимальный выглядел бы так:
int main() //<-- ВСЯ РАЗНИЦА ТУТ;)
{
int barcode_fd;
char buf_barcode[150];
barcode_fd = open("/dev/ttyACM0", O_RDONLY| O_NONBLOCK);
if (barcode_fd < 0) return -1;
for (int i=0; i<150; i++) buf_barcode[i] = '\0';
read(barcode_fd, buf_barcode, sizeof(buf_barcode));
close(barcode_fd); // Если этот убрать, то программа работает, если оставить, то падаетreturn 0;
}
..но он не падает. так что ищите баги в других местах
Как много веселых ребят, и все делают велосипед...
Re[2]: Непонятная ошибка при закрытии дескриптора файла
Как я и предполагал поместил приведенную мной функцию в отдельный Singelton и код заработал без проблем, т. е. в Singelton'е open/read/close делается без всяких проблем. Очевидно библиотека QT вмешивалась в работу кода, как я и предположил немного ранее.
Всем спасибо, нужно было с кем-то умными поговорить чтобы навели на мысль и мысль пришла. Всем пока!
Re[3]: Непонятная ошибка при закрытии дескриптора файла
skl>Как я и предполагал поместил приведенную мной функцию в отдельный Singelton и код заработал без проблем, т. е. в Singelton'е open/read/close делается без всяких проблем. Очевидно библиотека QT вмешивалась в работу кода, как я и предположил немного ранее. skl>Всем спасибо, нужно было с кем-то умными поговорить чтобы навели на мысль и мысль пришла. Всем пока!
То есть баг вы не пофиксили, а написали код так, чтоб он перестал воспроизводиться. Ничего, вылезет когда нибудь. Перед релизом скорее всего.
Как много веселых ребят, и все делают велосипед...
Re[3]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, skl, Вы писали:
skl>Как я и предполагал поместил приведенную мной функцию в отдельный Singelton и код заработал без проблем, т. е. в Singelton'е open/read/close делается без всяких проблем. Очевидно библиотека QT вмешивалась в работу кода, как я и предположил немного ранее.
Если завёртывание в однопоточный апартамент спасло, это наводит на мысли, что должен падать код вида
int f1 = open(same_filename, O_RDONLY|O_NONBLOCK);
int f2 = open(same_filename, O_RDONLY|O_NONBLOCK);
read(f1, buf1, size);
read(f2, buf2, size);
close(f1);
close(f2);
То есть, или использование файла вообще нереентерабельно (любого файла, или конкретно /dev/ttyACM0), или нереентерабельно гоночное открытие, чтение или закрытие
#omp parallel for
for(int i=0; i<2; ++i)
f[i] = open(same_file, O_RDONLY|O_NONBLOCK);
#omp parallel for
for(int i=0; i<2; ++i)
read(f[i], buf[i], size);
#omp parallel for
for(int i=0; i<2; ++i)
close(f[i]);
Если дело обстоит именно так, то выход — обернуть в критическую секцию любой степени изоляционизма (хоть в синглетон, хоть ещё как).
Но здесь нужно учитывать такую штуку, как инверсия приоритетов и неявные дедлоки. То есть, если процедура открытия или чтения затянется по причине внешней блокировки устройства, его неготовности или тормозливости, то твой вызывающий поток заснёт на неопределённое время. Насколько это место критично?
Например, вызывая потенциально тормозливую функцию из GUI, можно заморозить экран.
Перекуём баги на фичи!
Re[3]: Непонятная ошибка при закрытии дескриптора файла
CS>>Мне кажется тв не понимаешь как работатет O_NONBLOCK — т.е. не блокирующий IO O>это юникс, тут все не так
Да, в линуксах, например, O_NONBLOCK есть флаг в поле структуры file, которая
ассоциируется с любым IO дескриптором и установка которого проверяется при
невозможности чтения/записи в дескриптор, если флаг не установлен, засыпаем,
в противном случае, возвращаем -EAGAIN
На примерах из linux:
Здравствуйте, skl, Вы писали:
skl>2) Я понимаю, что это скорее сишный код в методе, но я не знаю как с помощью файловых потоков С++ задать неблокируемый режим для файла на чтение (т. е. флаг O_NONBLOCK). Буду благодарен за подсказку как это сделать при помощи файловых потоков С++.
skl>>2) Я понимаю, что это скорее сишный код в методе, но я не знаю как с помощью файловых потоков С++ задать неблокируемый режим для файла на чтение (т. е. флаг O_NONBLOCK). Буду благодарен за подсказку как это сделать при помощи файловых потоков С++. Z>использовать std::istream::readsome() вместо read()
Да блин у человека явно какой то баг в окружающем коде. Его надо фиксить. Я кстати процентов на 60 уверен что close у него не тот, который он хочет позвать — макросом переопределили каким то или гдето в проекте есть другой левый close, на который и слинковался код. Вобщем, gdb в зубы и вперед.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, skl, Вы писали:
skl>Это практически невозможно сделать, т. к. я кросскомпилирую (на x86 компьютере) свой код специальным arm-gcc компилятором (для arm9 машины). Выполнить код и посмотреть его работу я могу только на том устройстве для которого кросскомпилирую код (установить туда какие-то средства отладки практически невозможное дело, использую просто отладочные вывод с помощью printf в консоль). skl>Код довольно-таки обширный и проблем я никаких не знал до сих пор, так что на кросскомпилятор не хочу грешить.
На том устройстве можно получить core dump от программы? Если да, получите его, перетащите на PC, соберите (или найдите) cross-gdb и посмотрите, где оно падает.
Re[2]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, c-smile, Вы писали:
CS>Ты зовешь read() и не дожидаясь его завершения — close() и более того разрушаешь буффер. понятно что упадет где-нибудь.
Это не венда с overlapped I/O, это линух. read(), как только вернулся, от буфера уже отсосался, и больше в него не полезет.
Re[7]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, VVV, Вы писали:
VVV>Похоже, что выходите за пределы массива при 'манипуляциях' и затираете переменную int barcode_fd;. printf("%d\n", barcode_fd) после open и printf перед close могут помочь в поиске ошибки.
Не похоже. close() сам по себе не сигфолтится, даже если ему фуфло вместо дескриптора файла подсунуть.
Худшее, что может быть от передачи close() в качестве параметра мусора — это то, что он закроет какой-нибудь другой, не имеющий отношения к делу, файл (со случайно совпавшим номером). Что может сломать какой-то другой код, который работал с тем дескриптором. Но это какое-то уж слишком маловероятное стечение обстоятельств, IMHO.
Re[3]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, skl, Вы писали:
skl>Всем спасибо, нужно было с кем-то умными поговорить чтобы навели на мысль и мысль пришла. Всем пока!
Это неправильная мысль. Очевидно, что падал не этот кусок кода (там нечему падать), а какой-то другой. Переорганизовав программу, вы спрятали проблему, а не решили ее. Когда-нибудь она опять вылезет. Причем, может вылезти в еще более непонятном виде. Лучше бы разобраться, пока у вас проблема, по крайней мере, воспроизводится устойчиво, чем прятать ее.
Re[4]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, Кодт, Вы писали:
К>То есть, или использование файла вообще нереентерабельно (любого файла, или конкретно /dev/ttyACM0), или нереентерабельно гоночное открытие, чтение или закрытие
. . . К>Если дело обстоит именно так, то выход — обернуть в критическую секцию любой степени изоляционизма (хоть в синглетон, хоть ещё как).
Дело не обстоит именно так. Линух не настолько плох
Re[4]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, skl, Вы писали:
skl>>Всем спасибо, нужно было с кем-то умными поговорить чтобы навели на мысль и мысль пришла. Всем пока!
Pzz>Это неправильная мысль. Очевидно, что падал не этот кусок кода (там нечему падать), а какой-то другой. Переорганизовав программу, вы спрятали проблему, а не решили ее. Когда-нибудь она опять вылезет. Причем, может вылезти в еще более непонятном виде. Лучше бы разобраться, пока у вас проблема, по крайней мере, воспроизводится устойчиво, чем прятать ее.
Я пишу с использованием QT2, вот такой код например работает чудесно, в том числе нет проблем закрытием:
Но стоит использовать линуксовые функции open/read/close (не важно блокируемые или нет), то начинаются проблемы, почему-то именно падает на close().
Поэтому подозреваю, что проблема именно в QT и искать обходные пути в этом случае на мой взгляд правильно. Кстати, это не первая проблема именно с QT в процессе написания программы, например у меня не получилось заставить работать QT-классы для работы с FTP, естественно решил обходным путем — просто задействовал консольную ftp и с помощью нее сделал что требуется, и т. п. Это просто очередная заморочка с устаревшей версией QT, кстати linux тоже старенький 2.6 ядро. Использую старое потому что оно быстрее и меньше жрет ресурсов, что немаловажно для моего устройства.
Re[5]: Непонятная ошибка при закрытии дескриптора файла
skl>Но стоит использовать линуксовые функции open/read/close (не важно блокируемые или нет), то начинаются проблемы, почему-то именно падает на close().
а если писать не close(fd) а ::close(fd)?
Как много веселых ребят, и все делают велосипед...
Re[5]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, skl, Вы писали:
skl>Но стоит использовать линуксовые функции open/read/close (не важно блокируемые или нет), то начинаются проблемы, почему-то именно падает на close().
Это наведенка. В close() нечему упасть. Даже если передать ему невалидные аргументы, он не упадет, а вернет ошибку.
Кстати, не факт, что там вызывается тот самый close(). В классе или его родителях нет метода close() с подходящими типами аргументов?
skl>Поэтому подозреваю, что проблема именно в QT и искать обходные пути в этом случае на мой взгляд правильно.
Если ситуация такова, что при использовании Qt работает, а без использования — нет, то вряд ли проблема в Qt. Вы же не думаете, что Qt за вами тайно следит, и наказывает за неиспользование себя сигфолтами?
skl>Кстати, это не первая проблема именно с QT в процессе написания программы, например у меня не получилось заставить работать QT-классы для работы с FTP, естественно решил обходным путем — просто задействовал консольную ftp и с помощью нее сделал что требуется, и т. п. Это просто очередная заморочка с устаревшей версией QT, кстати linux тоже старенький 2.6 ядро. Использую старое потому что оно быстрее и меньше жрет ресурсов, что немаловажно для моего устройства.
Когда я начинал работать с линухом, то ядро 1.2.13 было самым свежачком, вчера вышедшим, а Qt, по-моему, еще в природе не существовал. Так что стареньким меня не удивишь
Re[6]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, Pzz, Вы писали:
Pzz>Это наведенка. В close() нечему упасть. Даже если передать ему невалидные аргументы, он не упадет, а вернет ошибку.
Pzz>Кстати, не факт, что там вызывается тот самый close(). В классе или его родителях нет метода close() с подходящими типами аргументов?
Я не говорю, что close() падает, а когда присутствует close() в моей функции то программа падает, а без close() работает, но при этом все дескрипторы в системе со временем исчерпывает (т. к. функция по таймеру запускается много раз).
В man вообще про close() следующее сообщается: "It is probably unwise to close file descriptors while they may be in use by system calls in other threads in the same process. Since a file descriptor may be re-used, there are some obscure race conditions that may cause unintended side effects. "
Я сам потоки в своей программе не создаю вообще.
Pzz>Если ситуация такова, что при использовании Qt работает, а без использования — нет, то вряд ли проблема в Qt. Вы же не думаете, что Qt за вами тайно следит, и наказывает за неиспользование себя сигфолтами?
И что конкретно вы предлагаете?
Pzz>Когда я начинал работать с линухом, то ядро 1.2.13 было самым свежачком, вчера вышедшим, а Qt, по-моему, еще в природе не существовал. Так что стареньким меня не удивишь
Вы, наверное, еще и emacs'ом пользуетесь и наверняка еще и vim.
Re[7]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, skl, Вы писали:
skl>Я не говорю, что close() падает, а когда присутствует close() в моей функции то программа падает, а без close() работает, но при этом все дескрипторы в системе со временем исчерпывает (т. к. функция по таймеру запускается много раз).
Когда у вас отсутствует close(), то вместо него мало чего другого присутствует. Например, выделение/освобождение памяти. Если у вас где-то в другом месте присутствует "удар по памяти", то из-за этих добавленных операций с памятью он может приходиться на другое место, и не приводить к сигфолту.
Еще раз повторю, сам по себе close() не при чем. Ищите проблему в другом месте.
Pzz>>Если ситуация такова, что при использовании Qt работает, а без использования — нет, то вряд ли проблема в Qt. Вы же не думаете, что Qt за вами тайно следит, и наказывает за неиспользование себя сигфолтами?
skl>И что конкретно вы предлагаете?
Понять, где конкретно падает. Например, с помощью core dump'а.
Pzz>>Когда я начинал работать с линухом, то ядро 1.2.13 было самым свежачком, вчера вышедшим, а Qt, по-моему, еще в природе не существовал. Так что стареньким меня не удивишь
skl>Вы, наверное, еще и emacs'ом пользуетесь и наверняка еще и vim.
При чем тут?
Re[7]: Непонятная ошибка при закрытии дескриптора файла
skl>Я не говорю, что close() падает, а когда присутствует close() в моей функции то программа падает, а без close() работает, но при этом все дескрипторы в системе со временем исчерпывает (т. к. функция по таймеру запускается много раз). skl>В man вообще про close() следующее сообщается: "It is probably unwise to close file descriptors while they may be in use by system calls in other threads in the same process. Since a file descriptor may be re-used, there are some obscure race conditions that may cause unintended side effects. "
Подумайте кстати над тем вопросом что случится, если ваш /dev/ttyACM0 внезапно от системы отвалится физически, а потом опять вернется
Как много веселых ребят, и все делают велосипед...
Re[8]: Непонятная ошибка при закрытии дескриптора файла
Здравствуйте, ononim, Вы писали:
O>Подумайте кстати над тем вопросом что случится, если ваш /dev/ttyACM0 внезапно от системы отвалится физически, а потом опять вернется
В этом смысл каждый раз открытия и закрытия дескриптора. Иначе можно было бы где-нибудь в начале программы открыть один раз дескриптор и постоянно читать из него, но нет гарантии что в это время не вытащат и снова не вставят кабель.