Не ловит Segmentation faultПримерчик простой
int buf[10], i;
try
{
for(i=0;i<1000;i++) buf[i]=1234;
}
catch(...)
{
printf("Exception\n");
return 1;
}printf("All right\n");
т.е. выделяю буфер в 10 элементов, а потом пытаюсь пихнуть туда 1000 элементов.
По идее должен возникнуть экзепшион и перехватиться cath-ом и обработаться, типа написать сообщение и выйти спокойно.
Реально же выводит следующее при запускеAll right
Segmentation faultВ чем я не прав и почему так получается?
Спасибо заранее за помощь
>Не ловит Segmentation fault
>
>Примерчик простой
>
>int buf[10], i;
>
>try
>{
> for(i=0;i<1000;i++) buf[i]=1234;
>}
>catch(...)
>{
> printf("Exception\n");
> return 1;
>}
>
>printf("All right\n");
>
>т.е. выделяю буфер в 10 элементов, а потом пытаюсь пихнуть туда 1000
>элементов.
>По идее должен возникнуть экзепшион и перехватиться cath-ом и обработаться, типа написать
>сообщение и выйти спокойно.
>Реально же выводит следующее при запуске
>
>All right
>Segmentation fault
>
>В чем я не прав и почему так получается?
>
>Спасибо заранее за помощьexception порождается вызовом throw, а кто тут вызывает throw? нихто...
>>Не ловит Segmentation fault
>>
>>Примерчик простой
>>
>>int buf[10], i;
>>
>>try
>>{
>> for(i=0;i<1000;i++) buf[i]=1234;
>>}
>>catch(...)
>>{
>> printf("Exception\n");
>> return 1;
>>}
>>
>>printf("All right\n");
>>
>>т.е. выделяю буфер в 10 элементов, а потом пытаюсь пихнуть туда 1000
>>элементов.
>>По идее должен возникнуть экзепшион и перехватиться cath-ом и обработаться, типа написать
>>сообщение и выйти спокойно.
>>Реально же выводит следующее при запуске
>>
>>All right
>>Segmentation fault
>>
>>В чем я не прав и почему так получается?
>>
>>Спасибо заранее за помощь
>>exception порождается вызовом throw, а кто тут вызывает throw? нихто...
вообщем то, я всегда думал что throw для принудительного вызова exception
а тут зачем делать принудительный вызов?
тут задача такая: нечто (в даном примере залез за пределы выделенной памяти) срабатывает некоректно с exception-ом, который впоследствии хорошо бы отловить и обработать...
вот как это сделать?
то что написанно в примере не работает :( а почему не понятно
а
>вообщем то, я всегда думал что throw для принудительного вызова exceptionправильно. в случае с неудачным выходом за границы массива вы получите исключение, которое отобразится в OS, которая отобразит его в сигнал SIGSEGV. и кто в этой схеме вызывает throw?
>а тут зачем делать принудительный вызов?чтобы получить исключение *C++*
>тут задача такая: нечто (в даном примере залез за пределы выделенной памяти)
>срабатывает некоректно с exception-ом, который впоследствии хорошо бы отловить и обработать...
>вот как это сделать?afaiu в модели исключений C++ - никак
если идти ниже, то можно перехватывать сигнал SIGSEGV и уже в нём решать, что и как делать. только это достаточно муторный и, как правило, бесполезный процесс.>то что написанно в примере не работает :( а почему не понятно
исключения процессора (нарушение общей защиты для i386 в вашем случае) не отображаются в исключения языка С++.
// wbr
>Не ловит Segmentation fault
>
>Примерчик простой
>
>int buf[10], i;
>
>try
>{
> for(i=0;i<1000;i++) buf[i]=1234;
>}
>catch(...)
>{
> printf("Exception\n");
> return 1;
>}
>
>printf("All right\n");
>
>т.е. выделяю буфер в 10 элементов, а потом пытаюсь пихнуть туда 1000
>элементов.
>По идее должен возникнуть экзепшион и перехватиться cath-ом и обработаться, типа написать
>сообщение и выйти спокойно.
>Реально же выводит следующее при запуске
>
>All right
>Segmentation fault
>
>В чем я не прав и почему так получается?
>
>Спасибо заранее за помощь
Если в виндах прямо в ядре имеется механизм SEH, который отображается в расширениях MSVC на exceptions, и ошибка сегментации там отображается в прикладной слой в виде exception и может быть перехвачена, то в Linux'е при ошибке сегментации процессу посылается сигнал SIGSEGV, а никаких exceptions не возникает. При желании можно, конечно, написать сигнальный обработчик, и повесить его на перехват SIGSEGV, но это очень порочная практика, обычно ни к чему хорошему не приводящая...
>В чем я не прав и почему так получается?Буквально недавно попадалось на глаза сообщение, прочтите:
http://gzip.rsdn.ru/forum/Message.aspx?mid=1421018&only=1
>>В чем я не прав и почему так получается?
>
>Буквально недавно попадалось на глаза сообщение, прочтите:
>http://gzip.rsdn.ru/forum/Message.aspx?mid=1421018&only=1
ага, понятно, спасибо всем за советы!только вот почему все пишут, что перехватывать сигнал, это порочная практика или это бесполезно?
я вот написал перехватчик и все нормально, екзепшн ловит на сигнал SIGSEGV, я там обработать могу, в конце концов, к примеру, закрыть открытые дискрипторы файлов или сокетов...
только почему все говорят, что так не очень хорошо?
есть какие то скрытые проблеммы?и еще вопрос, если так в Юниксах работают странно catch, то как пишут тогда вообще нормально программы под Юниксы?
Извините за вопрос, просто писал много под Винды и вообщем хорошим тоном считается try catch использовать, т.к. может произойти что угодно, особенно если проект огромный и работает круглые сутки и в котором не хотелось бы , чтоб вываливалась прога с диким криком, а хотелось бы чтоб хотя бы закрывалась корректно если что...спасибо заранее за ответы
>только вот почему все пишут, что перехватывать сигнал, это порочная практика или
>это бесполезно?Порочная практика, вероятно, потому, что после выхода за границы массива (например), часть данных, точки выхода из функций (если массив лежал в стеке) и т.д. можно считать неопределёнными. Что ж тут ещё делать, как не срочно завершить приложение, пока переходы в случайные места или использование случайных данных, которые программа считает не случайными, не натворили бог знает чего...
>и еще вопрос, если так в Юниксах работают странно catch, то как пишут тогда вообще нормально программы под Юниксы?Вероятно, проверяют границы массивов, не используют потенциально опасных функций вроде strcpy где не надо, проверяют возвращаемые значения... Короче, делают всё, что положено, а как без этого? И Юникс тут не при чём.
И ничего странного в такой работе try/catch я не вижу. Просто они IMHO не для этого.
>>>В чем я не прав и почему так получается?
>>
>>Буквально недавно попадалось на глаза сообщение, прочтите:
>>http://gzip.rsdn.ru/forum/Message.aspx?mid=1421018&only=1
>
>
>ага, понятно, спасибо всем за советы!
>
>только вот почему все пишут, что перехватывать сигнал, это порочная практика или
>это бесполезно?Потому что после SIGSEGV-а состояние программы не определено - какая-то инструкция процессора не завершилась как положено.
>
>я вот написал перехватчик и все нормально, екзепшн ловит на сигнал SIGSEGV,
>я там обработать могу, в конце концов, к примеру, закрыть открытые
>дискрипторы файлов или сокетов...Вот только попытка корректного выхода из программы и есть единсвенно возможное правильное действие. (Попытка, поскольку после SISEGVа программа ужв битая). Дескрипторы ОС сама закрывает - поэтому иногда самое лучшее решение просто позволить ей самой умереть без какой либо обработки сигнала.
>только почему все говорят, что так не очень хорошо?
>есть какие то скрытые проблеммы?
>
>и еще вопрос, если так в Юниксах работают странно catch, то как
>пишут тогда вообще нормально программы под Юниксы?
>Извините за вопрос, просто писал много под Винды и вообщем хорошим тоном
>считается try catch использовать, т.к. может произойти что угодно, особенно если
>проект огромный и работает круглые сутки и в котором не хотелось
>бы , чтоб вываливалась прога с диким криком, а хотелось бы
>чтоб хотя бы закрывалась корректно если что...Программы надо писать так чтобы SIGSEGV-ы не случались. Если случилось - это все, конец, застрелись и умри. Если в программе "может произойти что угодно" - надо это "что угодно" предусмотреть и обработать как следует, не дожидаясь SIGSEGVа...
Точно так же как не стоит использовать exception для проверки и выхода из цикла по достижению конца массива, не надо для этого и SIGSEGV использовать.
А вообще, сигналы в Unix настолько же фундаментальны, как и message dispatch в windows gui. Надежные сервера обязательно перехватывают и корректно обрабатывают некоторые сигналы - SIGINT, SIGTERM, SIGCHILD если запускаются дочерние процессы, SIGPIPE если работают с сокетами... Это все стоит сначала хорошо изучить, а потом и посмотреть как на все это наложить семантику конкретного языка - C++ exceptions, например...
>[оверквотинг удален]
>Точно так же как не стоит использовать exception для проверки и выхода
>из цикла по достижению конца массива, не надо для этого и
>SIGSEGV использовать.
>
>А вообще, сигналы в Unix настолько же фундаментальны, как и message dispatch
>в windows gui. Надежные сервера обязательно перехватывают и корректно обрабатывают некоторые
>сигналы - SIGINT, SIGTERM, SIGCHILD если запускаются дочерние процессы, SIGPIPE если
>работают с сокетами... Это все стоит сначала хорошо изучить, а
>потом и посмотреть как на все это наложить семантику конкретного языка
>- C++ exceptions, например...Конечно в большом проекте можно упустить выходы за границы, использование неинициализированных указателей ... очень тяжко их находить и легко наступать на одни и те=же грабли.
Подскажите пожалуйста инструмен для Solaris/SUN. Использую компилятор Sunstudio 10.
Valgrind использовал для Linux, но при компиляции с OCI очень много ругается, тож непонятно. В винде помоему хорошая вешь была BoundaryChecker, но для VC7 уже неработает.
И еще в Unix-ах че-то немогу просматривать дамп памяти в точках останова, в винде очень легко и просто.
Я тоже долго бился, но докопался до истины - http://www.visualdata.ru/blog/109-segv-signal.html. Теперь try catch ловит SIGSEGV и SIGFPE :)
>Я тоже долго бился, но докопался до истины - http://www.visualdata.ru/blog/109-segv-signal.html. Теперь try
>catch ловит SIGSEGV и SIGFPE :)Чтобы не делать - лишь бы ошибки не исправлять
>>Я тоже долго бился, но докопался до истины - http://www.visualdata.ru/blog/109-segv-signal.html. Теперь try
>>catch ловит SIGSEGV и SIGFPE :)
>
>Чтобы не делать - лишь бы ошибки не исправлятьНикто не отказывается от исправления ошибок, но спокойствие пользователей тоже важный фактор.
Падать - это не выход из ситуации.
>>>Я тоже долго бился, но докопался до истины - http://www.visualdata.ru/blog/109-segv-signal.html. Теперь try
>>>catch ловит SIGSEGV и SIGFPE :)
>>
>>Чтобы не делать - лишь бы ошибки не исправлять
>
>Никто не отказывается от исправления ошибок, но спокойствие пользователей тоже важный фактор.Ни какого спокойствия не добьешься
>Падать - это не выход из ситуации.а оживлять труп, это выход ?
>[оверквотинг удален]
>>>>catch ловит SIGSEGV и SIGFPE :)
>>>
>>>Чтобы не делать - лишь бы ошибки не исправлять
>>
>>Никто не отказывается от исправления ошибок, но спокойствие пользователей тоже важный фактор.
>
>Ни какого спокойствия не добьешься
>>Падать - это не выход из ситуации.
>
>а оживлять труп, это выход ?Иногда очень даже выход. Мой пример: использую для открытия изображения сотороннюю библиотеку, в которой в некоторых ситуациях случается segmentation fault, который можно просто проигнорировать. В винде ставится try-catch и все замечательно работает, а вот под линухом все падает, поэтому приходится извращаться, используя setjmp. Возможность поймать этот segmentation fault и под линукс через try-catch замечательный выход в данной ситуации.
На всякий случай, чтобы не было недопонимания ситуации: возникновение segmentation fault зависит исключительно от изображения. И написать программу так, чтобы его не было, просто невозможно...
>Я тоже долго бился, но докопался до истины - http://www.visualdata.ru/blog/109-segv-signal.html. Теперь try
>catch ловит SIGSEGV и SIGFPE :)Ссылка не работает =(, не могли бы Вы либо кинуть другую ссылку на идентичную статью, либо описать здесь, что нужно сделать, чтобы segmentation fault ловился в try-catch?
>Ссылка не работает =(А из кэша гугла не пробовали читать?
>>Ссылка не работает =(
>
>А из кэша гугла не пробовали читать?Спасибо.