Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | |
Мож, у тебя переполнение буфера в хипе? 27.09.09 07:10 Число просмотров: 6441
Автор: Zef <Alloo Zef> Статус: Elderman
|
Я как-то сталкивался с такой фигней: если пытаешься вылезти за пределы выделенного блока памяти, мастдай преспокойно позволяет обратиться к следующей странице, при этом, он ее помечает, как связанную и никакой ошибки не выдает. А ошибка вылазит где-то в совершенно другом месте, когда прога пытается аллоцировать другой буфер - при этом дура мелкомягкая пытается выделить уже выделенную страницу, натыкается на метку связанности и орет "караул!".
|
<theory>
|
Вся программа в блоках __try/__except. Но когда возникает исключение выдаётся окошко типа (Ошибка приложения): The Memory could not be read. Почему? Вот схема, которую я использую: 26.09.09 14:09
Автор: Vedrus <Serokhvostov Anton> Статус: Member
|
void my_function()
{
__try
{
тело функции
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
...
}
}
---
|
|
Maybe we need: make sure structural exception handling is ON... 06.10.09 23:36
Автор: void <Grebnev Valery> Статус: Elderman
|
> > void my_function()
> {
> __try
> {
> тело функции
> }
> __except (EXCEPTION_EXECUTE_HANDLER)
> {
> ...
> }
> }
> ---
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 14:28
Автор: Fighter <Vladimir> Статус: Elderman
|
|
| |
Большинство ошибок, которые у меня так вылетают примерно... 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. Название, как раз на хип смахивает...
И как из этой ситуации выкрутиться? Чтобы моя программа не вылетала?
|
| | | | |
CObjectArray тебя спасет 07.10.09 12:12
Автор: Zef <Alloo Zef> Статус: Elderman
|
У него автоматический контроль переполнения с автовыделением дополнителных страниц. А, вообще, контролировать переполнение надо самому специальным кодом.
|
| | |
Закономерный вопрос - какой компилятор используется? Например, gcc долгое время не поддерживал (может быть еще и не поддерживает) обработку исключений. 26.09.09 17:42
Автор: kstati <Евгений Борисов> Статус: Elderman
|
|
| | | |
Microsoft Visual C++ 6.0 (98 год) 27.09.09 03:16
Автор: Vedrus <Serokhvostov Anton> Статус: Member
|
|
|
|