簡體   English   中英

C++ 未處理的異常

[英]C++ unhandled exceptions

如果發生未處理的異常,C++ 是否提供了一種“顯示”視覺效果的方法?

如果它真的發生了,我想做的是做出類似assert(unhandled exception.msg())的事情(就像下面的示例一樣):

#include <stdexcept>

void foo() {
   throw std::runtime_error("Message!");
}

int main() {
 foo();
}

我希望這種代碼不會立即終止(因為未處理異常),而是顯示自定義斷言消息(實際上是Message! )。

那可能嗎?

標准沒有規定實際顯示未捕獲異常的消息的方法。 但是,在許多平台上,無論如何都是可能的。 在 Windows 上,您可以使用 SetUnhandledExceptionFilter 並提取 C++ 異常信息。 使用 g++(無論如何的適當版本),終止處理程序可以使用以下代碼訪問未捕獲的異常:

   void terminate_handler()
   {
       try { throw; }
       catch(const std::exception& e) { log(e.what()); }
       catch(...) {}
   }

確實 g++ 的默認終止處理程序做了類似的事情。 您可以使用 set_terminate 設置終止處理程序。

簡而言之,沒有通用的 C++ 方法,但有一些方法取決於您的平台。

Microsoft Visual C++ 允許您像這樣掛鈎未處理的 C++ 異常。 這是標准的 STL 行為

您通過調用set_terminate設置處理程序。 建議您的處理程序不要做太多工作,然后終止程序,但我不明白為什么您不能通過斷言發出信號 - 盡管您無權訪問導致問題的異常。

如果您使用的是 Windows,則處理未處理異常和崩潰的好庫是CrashRpt 如果您想手動執行此操作,您也可以使用我在此答案中寫的以下內容

我認為您將受益於如下包羅萬象的聲明:

int main() {
 try {
   foo();
 catch (...) {
   // Do something with the unhandled exception.
 }
}

如果我正確閱讀了您的問題,那么您是在詢問是否可以重載throw (更改其默認行為),以便它執行用戶定義的操作。 不,你不能。

編輯:既然你堅持:),這是一個壞主意™:

#include <iostream>
#include <stdlib.h>
#include <windows.h>

void monkey() {
   throw std::exception("poop!");
}

LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
    std::cout << "poop was thrown!" << std::endl;
    return EXCEPTION_EXECUTE_HANDLER;
  }

int main() {
    SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
    monkey();
    return 1;
}

同樣,這是一個非常糟糕的主意,它顯然依賴於平台,但它確實有效。

是的,有可能。 干得好:

#include <iostream>
#include <exception>

void foo() 
{
   throw std::exception("Message!");
}

int main() 
{
  try
  {
    foo();
  }
  catch (std::exception& e)
  {
    std::cout << "Got exception: " << e.what() << std::endl;
  }

  return 0;
}

c++ 標准是終止處理程序 - 正如其他人所說

如果您追求更好的投擲可追溯性,那么這就是我們所做的

我們有一個宏 Throw,它記錄文件名、行號和消息,然后拋出。 它需要一個 printf 樣式的可變參數消息。

Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);

我收到一條不錯的日志消息

Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99

如果您真的對導致程序失敗的原因感興趣,您可能會受益於在事后調試器中檢查過程映像。 精確的技術因操作系統而異,但基本訓練是首先啟用核心轉儲,然后編譯帶有調試符號的程序。 一旦程序崩潰,操作系統會將其內存復制到磁盤,然后您可以檢查程序崩潰時的狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM