Вся программа в блоках __try/__except. Но когда возникает исключение выдаётся окошко типа (Ошибка приложения): The Memory could not be read. Почему? Вот схема, которую я использую:26.09.09 14:09 Автор: Vedrus <Serokhvostov Anton> Статус: Member
---
Maybe we need: make sure structural exception handling is ON in the project settings; make sure you are not doing wrong thinks exactly inside __except block. Also keep in mind that VC6.0 had some problems with /EHa.
Заключение всей функции в try/except тоже проблему не решило, но проблема оказалась в другом.07.10.09 01:49 Автор: Vedrus <Serokhvostov Anton> Статус: Member
Решил вопрос. Ошибка оказалась в неожиданном для меня месте. Дело в том, что у меня в программе создаются и уничтожаются тысячи потоков. До недавнего времени я не знал, что дескрипторы потоков нужно закрывать функцией CloseHandle (думал, что когда поток завершается, то и его дескриптор освобождается).
В моём случае программа создавала примерно 700 000 дескрипторов, после этого возникало исключение. Мало того, пока эти дескрипторы не были закрыты я не мог запустить ни одного приложения.
Сейчас я сделал удаление дескрипторов и всё работает как часы. libcurl форева!
Но теперь возникла ещё одна проблема: на процессоре с одним ядром программа работает без сбоев, а на многоядерном периодически вылетает с исключением.
void, ты говоришь, что у VC6.0 есть проблемы с исключениями? А если перекомпилировать проект на VC7.0, 9.0?
Про теорию07.10.09 06:07 Автор: void <Grebnev Valery> Статус: Elderman
Много потоков - это не совсем хорошо. Хорошо бы иметь один-два потока иметь. Обычно при 500 - 1000 потоков у серверного приложения оно пересаёт работать. В таких случаях делают используют пул потоков.
> Но теперь возникла ещё одна проблема: на > процессоре с одним ядром программа работает без сбоев, а на > многоядерном периодически вылетает с исключением.
Обычное дело когда конкурентный доступ потоков не синхронизирован.
> void, ты говоришь, что у VC6.0 есть > проблемы с исключениями? А если перекомпилировать проект на > VC7.0, 9.0?
Да были и есть. Погугли. Начиная с VS 2005 модель и имплементация компилятором исключений другая. Мигрировать желательно. /EHa - очень надёжна в VS 2005 . Можешь забыть в C++ коде про __try/__except
Достаточно try/catch. Усли уж так необходимо, можешь назначить свой обработчик структурных иключений. Однако опять - мешать C и С++ исключения в одном коде не следовало бы. Используй C++.
Я вроде бы всё что нужно синхронизировал...07.10.09 06:26 Автор: Vedrus <Serokhvostov Anton> Статус: Member Отредактировано 07.10.09 06:26 Количество правок: 1
Я вроде бы всё что нужно синхронизировал (Semaphore/Event/WaitForSingleObject и всё такое). Единственное, что я разрешаю не синхронизированный доступ к глобальным переменным, которые только для чтения используются. Но ведь это вроде бы легальная комбинация?
И если несинхронизированные места являются причиной исключений в многоядерной системе, то они и же наверно должны и в одноядерной исключения давать - я ведь не один, а много потоков использую. Или в чём тут в другом замут?
Пул? Он у меня есть. Просто у меня в программе настраивается число параллельно работающих потоков. И 1000 потоков для решения моей задачи дают лучшие показатели.
Ну в принципе легально, если только другие потоки не будут...07.10.09 07:41 Автор: void <Grebnev Valery> Статус: Elderman
> Я вроде бы всё что нужно синхронизировал > (Semaphore/Event/WaitForSingleObject и всё такое). > Единственное, что я разрешаю не синхронизированный доступ к > глобальным переменным, которые только для чтения > используются. Но ведь это вроде бы легальная комбинация?
Ну в принципе легально, если только другие потоки не будут обносвять эти переменные, и оптимизирующий компилятор не поместит их в регистр. Может volatile попробовать?
> > И если несинхронизированные места являются причиной > исключений в многоядерной системе, то они и же наверно > должны и в одноядерной исключения давать
Нет не так. То, что проявляется в много процессорной системе, может непроявитья или проявляться очень редко в многопроцессорной. В однопроцессорной ситеме только один поток может выполняться в одно и тоже время (если нет всяких конвееров, гипертрединга).
> Пул? Он у меня есть. Просто у меня в программе > настраивается число параллельно работающих потоков. И 1000 > потоков для решения моей задачи дают лучшие показатели.
Возможно. Но на однопроцессорном PC только один поток работает. Остальные отдыхают- будучи зашедулены или нет.
Спасибо, эта информация для меня в новинку. Насчёт volatile тема, надо попробовать!07.10.09 08:27 Автор: Vedrus <Serokhvostov Anton> Статус: Member
Большинство ошибок, которые у меня так вылетают примерно...26.09.09 15:00 Автор: Vedrus <Serokhvostov Anton> Статус: Member Отредактировано 26.09.09 15:19 Количество правок: 2
Большинство ошибок, которые у меня так вылетают примерно такие: "инструкция X обратилась по адресу 00000000". Скорее всего, я где-то в программе использую неинициализированный указатель. Хотел найти его, сохраняя логи из блока __except. Но почему-то исключения пролетают мимо блока __except. Или данная ошибка не является исключением?
Мож, у тебя переполнение буфера в хипе?27.09.09 07:10 Автор: Zef <Alloo Zef> Статус: Elderman
Я как-то сталкивался с такой фигней: если пытаешься вылезти за пределы выделенного блока памяти, мастдай преспокойно позволяет обратиться к следующей странице, при этом, он ее помечает, как связанную и никакой ошибки не выдает. А ошибка вылазит где-то в совершенно другом месте, когда прога пытается аллоцировать другой буфер - при этом дура мелкомягкая пытается выделить уже выделенную страницу, натыкается на метку связанности и орет "караул!".
Может быть... Я в режиме отладки посмотрел адрес, на который...27.09.09 14:18 Автор: Vedrus <Serokhvostov Anton> Статус: Member
Может быть... Я в режиме отладки посмотрел адрес, на который винда ругается (в debug-mode MSVS c++6.0 ассемблерный код "расположен в перемешку с сишным"), думал найти ошибочное место в своей программе. А у меня студия запросила местоположение файла SBHEAP.c. Название, как раз на хип смахивает...
И как из этой ситуации выкрутиться? Чтобы моя программа не вылетала?
У него автоматический контроль переполнения с автовыделением дополнителных страниц. А, вообще, контролировать переполнение надо самому специальным кодом.
Закономерный вопрос - какой компилятор используется? Например, gcc долгое время не поддерживал (может быть еще и не поддерживает) обработку исключений.26.09.09 17:42 Автор: kstati <Евгений Борисов> Статус: Elderman