
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.60] |
![]() |
|
Страницы: (10) [1] 2 3 ... 9 10 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Друзья! Есть рекурсивная функция, которая переполняет стек. Вот хочу чтобы об этом как-нибудь сигнализировалось, пишу обработку исключений и в catch (...) пишу ХОТЬ ЧТО-НИБУДЬ ЛИШЬ БЫ СКОМПИЛИЛОСЬ
Так, писать вроде как надо тип исключения. А какой у исключений тип? А чёрт его знает. Порылся по гуглу, у Джефри РИхтра всё очень-очень интересно. Вот, допустим отрывок его кода: (правда, там он использует компилятор msvs и соответственно конструкццию __try __except, но не суть) ![]() ![]() __except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO Что в левой части? Смотрим в msdn The return value identifies the type of exception ага, а в правой? лезем в winbase.h ![]() ![]() #define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094 #define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO неплохо, да? Идентификатор типа приравнивается к конкретному значению 0xC0000094! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Так чё писать-то в catch (...)? Я пробовал тупо cath (EXCEPTION_ACCESS_VIOLATION) (переполнен стек)- так компилятор говорит, что нужен тип... Какой тип? Пробовал cath (GetExceptionCode())- то же самое: expected type-specifier before 'GetExceptionCode' ...Опять же, макрос GetExceptionCode(). Роюсь в инклудах и вижу в: ![]() ![]() #define RpcExceptionCode() GetExceptionCode() Ну и хорош пока на этом. В общем, ребята помогите разобраться в данном вопросе! Компилятор g++ ![]() ![]() #include <windows.h> #include <stdio.h> using namespace std; void k () { printf ("hello, word!\n"); k(); } int main () { try { k(); } catch (EXCEPTION_ACCESS_VIOLATION) { // catch (GetExceptionCode()== EXCEPTION_ACCESS_VIOLATION) { } return 0; } |
Сообщ.
#2
,
|
|
|
Для MSVC так:
![]() ![]() LONG My_ExceptFilter(DWORD except_code,PEXCEPTION_POINTERS except_info) { if (except_code==EXCEPTION_STACK_OVERFLOW) { //some code } //return EXCEPTION_CONTINUE_SEARCH; //система дальше будет искать обработчик исключения //ИЛИ //return EXCEPTION_CONTINUE_EXECUTION //продолжает выполнение программы с точки где возникло исключение //ИЛИ //return EXCEPTION_EXECUTE_HANDLER; //мы обрабатываем, дальше поиск обработчика не пойдет, после возврата из функции выполнится блок __except } //............................................................................................................... __try { //КОД где предполагается возникновение исключения } __except(My_ExceptFilter(GetExceptionCode(),GetExceptionInformation())) { } Только при переполнении стека уже ничего не получится сделать. Всё кирдык, только закрыть всё, запомнить что нужно и завершать поток. Ну если только сами данные в стеке важны, а если не важны то можно указатель стека вновь на начало поставить. |
Сообщ.
#3
,
|
|
|
При всё уважении не рассматривал ваш вариант. У меня g++, другие инструменты работают на нём нормально так что хотелось всё же обсуждать возможности компилятора g++, кстати в сети примеры подобные вашему есть, а для g++ я не нашёл.
|
![]() |
Сообщ.
#4
,
|
|
В g++ есть SEH-обработка? Если нет, то SetUnhandledExceptionFilter и код, приведенный выше
|
Сообщ.
#5
,
|
|
|
![]() Я ж только-только начал заниматься исключениями... Откуда же мне знать, есть оно там или нет? И сключения ВООБЩЕ- поддерживаются. В частности SEH... Походил-походил по гуглу, нарыл, что: "Блоки SEH оформляются с помощью операторов __try, __finally, __except" Но такой синтаксис поддерживается компилятором MSVS! А g++ не поддерживется. Вывод: в g++ SEH нет. А потом я так понял, что при удачном вызове SetUnhandledExceptionFilter управление передаётся обработчику сообщений который действует в зависимости от... От чего? От типа исключения? И опять- как определять этот тип? Но как бы то ни было, вот код с использованием SetUnhandledExceptionFilter, что-то он не работает ![]() ![]() #include <windows.h> #include <iostream> #include <stdio.h> LONG WINAPI UEF(_EXCEPTION_POINTERS *ExceptionInfo) { printf ("пишу тут вдруг адрес, который ниже, невалидный \n"); getchar (); return EXCEPTION_EXECUTE_HANDLER; } int main() { SetConsoleCP (1251); SetConsoleOutputCP (1251); SetUnhandledExceptionFilter (UEF); throw std::exception(); getchar (); return 0; } |
Сообщ.
#6
,
|
|
|
![]() ![]() LONG WINAPI TopLevelUnhandledExceptionFilter(PEXCEPTION_POINTERS except_info) { if (except_info->ExceptionRecord->ExceptionCode==EXCEPTION_STACK_OVERFLOW) { //some code } //return EXCEPTION_CONTINUE_EXECUTION //ИЛИ //return EXCEPTION_EXECUTE_HANDLER; } //.................................................... SetUnhandledExceptionFilter(TopLevelUnhandledExceptionFilter); Добавлено Ещё такой вопрос, а что вас заставляет использовать именно g++, а не MSVC? |
Сообщ.
#7
,
|
|
|
neokoder, зачем давать неопробированные варианты? Запустите ваш код и увидите что он неработает. Вот он:
![]() ![]() #include <windows.h> #include <iostream> #include <stdio.h> LONG WINAPI TopLevelUnhandledExceptionFilter(PEXCEPTION_POINTERS except_info) { if (except_info->ExceptionRecord->ExceptionCode==EXCEPTION_STACK_OVERFLOW) { //some code } else { printf ("ÿ õî÷ó âèäåòü ýòó íàäïèñü, íî ÿ å¸ íå âèæó\n"); getchar (); } return EXCEPTION_CONTINUE_EXECUTION; } //.................................................... int main(){ SetConsoleCP (1251); SetConsoleOutputCP (1251); //SetUnhandledExceptionFilter (UEF); SetUnhandledExceptionFilter(TopLevelUnhandledExceptionFilter); throw std::exception(); getchar (); return 0; } компилятор- инструмент всего лишь если надо будет я перейду на MSVS, но я должен убедиться, что создатели g++ (или сторонних ибилиотек для g++) не предусмотрели обработку исключений. А не так, что ах не получилось быстренько меняем компилятор. Тем более, что у g++ есть и другие плюсы (нормальная работа с библиотеками OpenGL и pthread, тьфу-ьтьфу-тьфу). |
Сообщ.
#8
,
|
|
|
Цитата повстанец @ Запустите ваш код и увидите что он неработает. Вот он: А как он "не работает"? ![]() ![]() |
Сообщ.
#9
,
|
|
|
Если тыкать мышью, то окно появляется и тут же исчезает, а если в консоли запускать, то появляется:
![]() ![]() terminate called after throwing an instance of 'std::exception' what(): std::exception This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. А нужной мне строки "я хочу видеть эту надпись, но я её не вижу\n" как не было, так и нет |
Сообщ.
#10
,
|
|
|
Цитата повстанец @ А нужной мне строки "я хочу видеть эту надпись, но я её не вижу\n" как не было, так и нет Чтобы видеть надпись попробуй так: ![]() ![]() LONG WINAPI TopLevelUnhandledExceptionFilter(PEXCEPTION_POINTERS except_info) { if (except_info->ExceptionRecord->ExceptionCode==EXCEPTION_STACK_OVERFLOW) { //some code } else { printf ("Another exception catched.\n"); } return EXCEPTION_EXECUTE_HANDLER; } Я в комментарии дал немного неверную информацию тебе вначале. Если использовать EXCEPTION_CONTINUE_EXECUTION, то он возвращается в ту же точку где произошло исключение. Поэтому у тебя циклились исключения. |
Сообщ.
#11
,
|
|
|
Может быть они и циклились, но надпись-то должна была выводиться?
ТО есть если " Цитата ", то должно было быть так: EXCEPTION_CONTINUE_EXECUTION, то он возвращается в ту же точку где произошло исключение. генерация исключения- надпись генерация исключения- надпись генерация исключения- надпись генерация исключения- надпись генерация исключения- надпись И так далее. Я тебе больше скажу- ты опять не тестишь свой код. При ![]() ![]() return EXCEPTION_EXECUTE_HANDLER; |
Сообщ.
#12
,
|
|
|
Цитата повстанец @ Я тебе больше скажу- ты опять не тестишь свой код. Правильно, его тестить должен ты, поскольку у меня нет G++; ![]() В MSVC всё будет работать. Я думал может и в твоём компиляторе по аналогии заработает. Ну если нет надписи с EXCEPTION_EXECUTE_HANDLER, значит в G++ не работает такая обработка исключений. Попробуй в debug-режиме вообще попадает он в этот обработчик или нет, или добавь строчку printf ("In TopLevelUnhandledExceptionFilter.\n"); в начало фильтра. Конструкцию try/catch(...) пробовал? И опции компилятора, связанные с исключениями проверь, чтобы SEH-исключения также ловились. И ещё, а почему бы не задать свой вопрос разработчикам компилятора или здесь к примеру? Там по ходу не только у тебя такая проблема и здесь такая же. |
Сообщ.
#13
,
|
|
|
Так-то кто хочет тот и тестит, у на демократия. Но какое доверие будет к твоим кодам?
try/catch(...) я пробовал, о чём написал в первом собщении. В общем, спасибо за беспокойство, не смею больше тратить твоё время. Вопрос открыт. |
Сообщ.
#14
,
|
|
|
Цитата повстанец @ Так-то кто хочет тот и тестит, у на демократия. Но какое доверие будет к твоим кодам? В общем, спасибо за беспокойство, не смею больше тратить твоё время. Вопрос открыт. Тебе ещё раз говорю, что в MSVC всё будет работать без проблем, не раз я этот код писал, поэтому и уверен. Т.е. эта не проблема WinAPI, а проблема твоего компилятора. Так что не в той теме ты вопрос задаешь вообще. Добавлено Цитата повстанец @ try/catch(...) я пробовал, о чём написал в первом собщении. Кстати именно такой конструкции у тебя не было в коде: ![]() ![]() try { } catch(...) { } Проверь! Добавлено Ещё до кучи, проверьте включена ли у вас опция "-fhandle-exceptions" при компиляции. По умолчанию она вроде бы отключена. |
Сообщ.
#15
,
|
|
|
Я сразу сказал, что дело в компиляторе, гы. Ну то есть дело в том, что он не генерит нужный мне код с предложенным синтаксисом. Когдаааа я ещё сказал. Так зачем же предлагать коды, которые не опробированы на нём? Здесь- не здесь это второй вопрос, я не знаю где.
Вот отрывок из кода из первого сообщения, я проверил ![]() ![]() try { k(); } catch (EXCEPTION_ACCESS_VIOLATION) { // catch (GetExceptionCode()== EXCEPTION_ACCESS_VIOLATION) { } Не беспокойся, в общем, больше. До свидания. Желаю счастья. |