2009-05-27 4 views
0

У меня есть C++ DLL с кодом вроде этого:Возможно ли, что потребитель библиотеки может переопределить обработку исключений C++?

LogMessage("Hello world"); 
try { 
    throw new int; 
} catch(int* e) { 
    LogMessage("Caught exception"); 
    delete e; 
} 
LogMessage("Done"); 

Этой DLL загружаются некоторым приложением третьей стороны и выше код вызывается. Проблема заключается только в вызове первого LogMessage - хотя есть обработчик исключений, поток управления передается неизвестному.

Я вижу это и не могу решить, нужно ли исследовать какую-то неясную ошибку или просто злую силу потребительского приложения.

Действительно ли потребительское приложение может переопределить обработку исключений C++ в DLL?

РЕДАКТИРОВАТЬ: Проблема решена после того, как вы подумали обо всех вещах, чтобы проверить изложенные в ответах. В реальном коде это не просто throw, там есть специальная функция для исключения исключений, которая имеет вызов вызова MessageBoxW() Win32 в отладочной версии. И у потребительского приложения были проблемы с показом окна сообщения (это служба NT) и эффективно повесили трубку. Таким образом, это не проблема обработки исключений C++.

ответ

1

Код выглядит хорошо для меня, но у меня возникнет соблазн поставить еще несколько предложений catch, чтобы увидеть, попадает ли он в один из других. А именно, я бы поставил в:

 
    catch (const std::exception &ex) { 
    ... log exception ... 
    } 
    catch (...) { 
    ... log exception .. 
    } 

Я бы ожидать, что это будет либо ударить указатель поймать (даже если это на самом деле не очень хорошая идея, увидеть ссылку, которую Игорь Окс комплект поставки) или зЬй :: исключение в случае, если он не может выделить память. Тем не менее, он должен ударить по одному из трех предложений catch, чтобы исключить возможность исключения из библиотеки DLL.

Я также изменил бы объект, который был добавлен в тип значения (даже если он был int) и обновил предложение catch соответственно, чтобы увидеть, если вы так изменили поведение.

+0

Я принимаю этот ответ, потому что он предлагает самый широкий список вещей для проверки при отладке таких проблем. – sharptooth

1

Код в порядке. Я выполнил его с помощью этой функции:

void LogMessage(char* s) 
{ 
    cout << s << endl; 
} 

И получил правильный вывод:

Привет мир

Caught исключение

Совершено

возможно, что ли там проблема с вашим Log Сообщение функция?

Я предлагаю исследовать (отладчиком или добавлением отладочных отпечатков), достигнут ли ваш поток до блока try и достигнет ли он блока catch.

Не проблема, все еще неясно, что вы достигаете, бросая указатель, а не значение. Я бы рекомендовал не использовать catch-by-pointer, см. Рассуждения here, на C++ - FAQ-lite.

+0

Очень маловероятно. Он работает в первый раз и выглядит так, как будто ничто не помешало ему работать дальше. – sharptooth

1

Во-первых, проверьте, выключен ли вызов LogMessage (используйте << endl).

Хотя надуманный, возможно ли, что новый вызов выбрасывает исключение (из памяти)? Я считаю это одной из причин не для новых исключений (просто чтобы добавить к словам Игоря).

1

Код выглядит нормально. Но можете ли вы проверить, есть ли какое-либо необработанное исключение до того, как будет сформировано структурированное исключение throw new int;.

LogMessage("Hello world"); 
try { 

    //some unhandled exception here 

    throw new int; 
} catch(int* e) { 
    LogMessage("Caught exception"); 
    delete e; 
} 
LogMessage("Done"); 

Если это так, то вы можете проверить же, используя SetUnhandledExceptionFilter функцию.

Если DLL уже предоставляет необработанный фильтр исключительных ситуаций, и если это возвращает EXCEPTION_EXECUTE_HANDLER, то ваш обработчик исключений не будет вызван.

Чтобы преобразовать исключения win32 в структурированные исключения C++, необходимо использовать _set_se_translator.

0

Поддавка фактически находится в РЕДАКТОРЕ. «Служба MessageBoxW() ... NT ... эффективно зависает». Это справедливое описание. Поле сообщения находится на рабочем столе, не связанном с зарегистрированным пользователем. Следовательно, он все еще там, ожидая музлик, который никогда не случится.

Смежные вопросы