【问题标题】:how to catch unknown exception and print it如何捕获未知异常并打印它
【发布时间】:2011-03-05 17:11:42
【问题描述】:

我有一些程序,每次运行它都会抛出异常,我不知道如何检查它到底抛出了什么,所以我的问题是,是否可以捕获异常并打印它(我发现抛出的行例外)提前感谢

【问题讨论】:

    标签: c++ exception


    【解决方案1】:

    灵感来自 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();
          }
       }
    }
    

    【讨论】:

      【解决方案2】:

      灵感来自 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();
          }
      }
      

      【讨论】:

      • 仍然只处理std::exception
      【解决方案3】:

      在 C++11 中你有:std::current_exception

      来自网站的示例代码:

      #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
      

      【讨论】:

      • 这没有帮助,它仍然只处理 std::exception。如果抛出 char* 之类的东西,这将无济于事。
      • 戴维德罗兹德。您回答的评论是用事实而非礼貌的方式表达的,并通过技术解释支持所做的陈述。另一方面,您的评论....不是,也没有。
      【解决方案4】:

      如果您将 ABI 用于 gcc 或 CLANG,您可以知道未知的异常类型。但它是非标准解决方案。

      看这里 https://stackoverflow.com/a/24997351/1859469

      【讨论】:

        【解决方案5】:

        如果它源自std::exception,您可以通过引用来捕获:

        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();
        }
        

        但如果异常是某个类不是从std::exception 派生的,则您必须提前知道它的类型(即您应该捕获std::string 还是some_library_exception_base)。

        你可以一网打尽:

        try
        {
        }
        catch (...)
        {
        }
        

        但是你不能做任何例外的事情。

        【讨论】:

        • @R Samuel Klatchko:非常感谢,还有一个问题,我可以用你的方法检查 new 和 delete 的异常吗?
        • @helloWorld - 是的,这将捕获从newdelete 以及它们调用的任何构造函数或析构函数抛出的异常(前提是newdelete 语句在@987654331 内@块)。
        • 如果异常不是从 std::exception 派生的,我应该如何解决我的问题?
        • @javapowered 您是否偶然看到下面的 Gregory81 的答案(在您的评论后添加)?
        【解决方案6】:

        首先按照 R Samuel Klatchko 的建议尝试。如果这没有帮助,还有其他可能会有所帮助的方法:

        a) 如果您的调试器支持,则在异常类型(已处理或未处理)上放置断点。

        b) 在某些系统上,编译器会在执行 throw 语句时生成对(未记录的?)函数的调用。要找出适用于您的系统的功能,请编写一个简单的 hello world 程序,该程序会引发和捕获异常。启动调试器并在异常构造函数中放置一个断点,然后查看它被调用的位置。校准函数可能类似于 __throw()。之后,使用要作为调试对象调查的程序再次启动调试器。在上面提到的函数(__throw 或其他)上放置断点并运行程序。当抛出异常时,调试器停止,您就可以找出原因。

        【讨论】:

          猜你喜欢
          • 2017-12-27
          • 1970-01-01
          • 2011-10-24
          • 2015-06-10
          • 2012-06-12
          • 2014-02-04
          • 2011-07-14
          • 1970-01-01
          • 2019-05-02
          相关资源
          最近更新 更多