web-dev-qa-db-fra.com

comment intercepter une exception inconnue et l'imprimer

J'ai un programme et chaque fois que je l'exécute, il lève une exception et je ne sais pas comment vérifier exactement ce qu'il lance, donc ma question est, est-il possible de détecter une exception et de l'imprimer (j'ai trouvé des lignes qui lève une exception) merci en avance

39
helloWorld

S'il dérive de std::exception vous pouvez attraper par référence:

try
{
    // code that could cause exception
}
catch (const std::exception &exc)
{
    // catch anything thrown within try block that derives from std::exception
    std::cerr << exc.what();
}

Mais si l'exception est une classe qui n'a pas été dérivée de std::exception, vous devrez connaître à l'avance son type (c'est-à-dire si vous devez attraper std::string ou some_library_exception_base).

Vous pouvez tout faire:

try
{
}
catch (...)
{
}

mais alors vous ne pouvez rien faire à l'exception.

51
R Samuel Klatchko

En C++ 11, vous avez: std :: current_exception

Exemple de code du site:

#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>

void handle_eptr(std::exception_ptr eptr) // passing by value is ok
{
    try {
        if (eptr) {
            std::rethrow_exception(eptr);
        }
    } catch(const std::exception& e) {
        std::cout << "Caught exception \"" << e.what() << "\"\n";
    }
}

int main()
{
    std::exception_ptr eptr;
    try {
        std::string().at(1); // this generates an std::out_of_range
    } catch(...) {
        eptr = std::current_exception(); // capture
    }
    handle_eptr(eptr);
} // destructor for std::out_of_range called here, when the eptr is destructed
19
Dawid Drozd

Si vous utilisez ABI pour gcc ou CLANG, vous pouvez connaître le type d'exception inconnu. Mais ce n'est pas une solution standard.

Voir ici https://stackoverflow.com/a/24997351/1859469

3
Grzegorz Wolszczak

Inspiré par la réponse de Dawid Drozd:

#include <exception>
try
{
    // The code that could throw
}
catch(...)
{
    auto expPtr = std::current_exception();

    try
    {
        if(expPtr) std::rethrow_exception(expPtr);
    }
    catch(const std::exception& e) //it would not work if you pass by value
    {
        std::cout << e.what();
    }
}
1
hamaney

Inspiré par la réponse hamaney:

#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>

int main()
{
   try
   { 
      // Your code
   }
   catch (...)
   {
      try
      {
         std::exception_ptr curr_excp;
         if (curr_excp = std::current_exception())
         {
            std::rethrow_exception(curr_excp);
         }
      }
      catch (const std::exception& e)
      {
         std::cout << e.what();
      }
   }
}
1
Lyndon Bauto

Essayez d'abord comme suggéré par R Samuel Klatchko. Si cela n'aide pas, il y a autre chose qui pourrait aider:

a) Placez un point d'arrêt sur le type d'exception (géré ou non) si votre débogueur le prend en charge.

b) Sur certains systèmes, le compilateur génère un appel à une fonction (non documentée?) lorsqu'une instruction throw est exécutée. pour savoir quelle fonction correspond à votre système, écrivez un simple programme hello world qui lève et intercepte une exception. démarrez un débogueur et placez un point d'arrêt dans le constructeur d'exceptions et voyez d'où il est appelé. la fonction de calage est probablement quelque chose comme __throw (). ensuite, redémarrez le débogueur avec le programme que vous souhaitez étudier en tant que débogueur. placez un point d'arrêt sur la fonction mentionnée ci-dessus (__throw ou autre) et exécutez le programme. lorsque l'exception est levée, le débogueur s'arrête et vous êtes là pour découvrir pourquoi.

1
Axel