2017-01-18 2 views
0

Мне нужно поймать ошибку сегментации и другие неизвестные исключения в моем приложении. Но я не знаю, как я могу это сделать! Могу ли я использовать std :: uncaught_exceptions для этой цели?Является ли std :: uncaught_exceptions полезным для исключения всех исключений?

+0

No can can. Segfault создается ниже C++. Это не исключение или даже C++. – user4581301

+0

Возможно, вы захотите прочитать: http://stackoverflow.com/questions/457577/catching-access-violation-exceptions –

+6

Вам нужно поймать его и сделать * что * точно? На самом деле это не то, от чего вы можете спокойно оправиться. SEGV означает, что ваш код серьезно нарушен, вы, вероятно, должны инвестировать усилия в устранение основной причины. – paxdiablo

ответ

1

Могу ли я использовать std::uncaught_exceptions для этой цели?

Рассмотрим этот код:

int main(int argc, char* argv[]) 
{ 
    int *val = NULL; 
    *val = 1; 
    std::cout << "uncaught: " << std::uncaught_exceptions() << std::endl; 
    return 0; 
} 

Это, вероятно, приведет к ошибке сегментации и ничего не будет выводиться.

Мне нужно поймать ошибку сегментации и другие неизвестные исключения в моем приложении. Но я не знаю, как я могу это сделать!

Обработка исключений в C++ можно сделать через try-catch блок, и вы можете использовать функцию std::signal поймать некоторые ошибки, как SIGSEGV, SIGFPE, or SIGILL, например:

#include <iostream> 
#include <exception> 
#include <csignal> 
#include <cstdio> 

extern "C" { 
    void sig_fn(int sig) 
    { 
     printf("signal: %d\n", sig); 
     std::exit(-1); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    int *val = NULL; 
    std::signal(SIGSEGV, sig_fn); 
    try { 
     *val = 1; 
    } catch (...) { 
     std::cout << "..." << std::endl; 
    } 
    if (std::uncaught_exception()) { 
     std::cout << "uncaught" << std::endl; 
    } 
    std::cout << "return" << std::endl; 
    return 0; 
} 

Но следует отметить, что этот тип исключения обработка действительно предназначена для очистки и выключения, а не для улова и выпуска; воспользуйтесь этим кодом, например:

#include <iostream> 
#include <exception> 
#include <csignal> 
#include <cstdio> 

extern "C" { 
    void sig_fn(int sig) 
    { 
     printf("signal: %d\n", sig); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    int *val = NULL; 
    std::signal(SIGSEGV, sig_fn); 
    while (true) { 
     try { 
      *val = 1; 
     } catch (...) { 
      std::cout << "..." << std::endl; 
     } 
    } 
    if (std::uncaught_exception()) { 
     std::cout << "uncaught" << std::endl; 
    } 
    std::cout << "return" << std::endl; 
    return 0; 
} 

Этот код вызовет и поймает ошибку сегментации навсегда!

Если вы пытаетесь поймать ошибку сегментации, вам необходимо выяснить, почему в первую очередь произошла ошибка сегментации (или любая ошибка) и исправить эту проблему; используя код выше в качестве примера:

int *val = NULL; 
if (val == NULL) { 
    std::cout << "Handle the null!" << std::endl; 
} else { 
    *val = 1; 
} 

Для дальнейшего чтения: here is a SO Q&A на то, что это выдаёт ошибку сегментации, а также, here is the Wiki на нем, и MIT имеет некоторые советы по обработке и отладке тоже ошибки сегментации.

Надеюсь, что это поможет.

+0

Первый пример - это неопределенное поведение в соответствии со стандартом C++. Вероятно, это приведет к segfault для каждой системы, с которой вы столкнетесь в своем опекуне, в качестве программиста, но никаких гарантий. – user4581301

+0

@ user4581301 .. технически все примеры являются UB, поскольку все они разыменовывают нулевой указатель; но, учитывая знание ФП об исключениях и сигналах, я больше пытался выразить, что ОП должен видеть это как ошибку (а не только UB); Я изменил _allways_ на _вероятно ... потому что этот код: 'int * v = NULL; попробуйте {* v = 1; } catch (...) {std :: cout << "..." << std :: endl; } 'работает" как ожидалось "в Windows, но не на других платформах (технически код все равно должен вызывать segfault, но обработчик прерываний внутреннего segfault Windows фактически тогда« бросает ошибку, которая поймана »). – txtechhelp

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