我在Visual Studio中運行該代碼2013(調試配置):Visual Studio的多線程調試
#include <thread>
#include <stdexcept>
void c() {
/* breakpoint here*/ throw std::runtime_error("error");
}
void b() {
c();
}
void a() {
b();
}
int main(int argc, char** argv) {
std::thread thr(a);
if (thr.joinable()) thr.join();
return 0;
}
執行暫停在斷點處,我看到的調用堆棧:
> DemoProj.exe!c() Line 5 C++
DemoProj.exe!b() Line 10 C++
DemoProj.exe!a() Line 16 C++
[External Code]
這是偉大的!我可以確切地看到我在執行過程中的位置。
之後,我走了一步(F10)只是爲了執行這個異常投擲線。 當然,除了得到投擲,但現在我的調用堆棧看起來是這樣的:
> msvcp120d.dll!_Call_func$catch$0() Line 30 C++
msvcr120d.dll!_CallSettingFrame() Line 51 Unknown
msvcr120d.dll!__CxxCallCatchBlock(_EXCEPTION_RECORD * pExcept) Line 1281 C++
ntdll.dll!RcConsolidateFrames() Unknown
msvcp120d.dll!_Call_func(void * _Data) Line 28 C++
msvcr120d.dll!_callthreadstartex() Line 376 C
msvcr120d.dll!_threadstartex(void * ptd) Line 359 C
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
這使我調試沒用。 線
/* breakpoint here*/ throw std::runtime_error("error");
只是這裏這個簡單的例子。在真實的項目中,我不知道代碼會在哪裏破壞。如果Visual Studio可以在發生錯誤的確切行上停止執行,那將會非常有幫助。但是相反,如果在我的主線程之外的任何地方拋出一個異常,我只能得到這些系統調用,並且永遠無法弄清楚我的代碼中的哪一行導致崩潰。
任何幫助?我覺得這個問題跟this one差不多。 想法是捕獲側線程中的異常並將它們傳遞給主線程,以便主線程可以重新拋出它們。沒有更優雅的解決方案嗎?
異常已被捕獲後,您無法做任何事情。堆棧已經被解開。但是,在實際拋出任何東西之前,您可以編寫自己的異常類來轉儲堆棧(讀取StackWalk64)。 https://msdn.microsoft.com/en-us/library/windows/desktop/ms680650(v=vs.85).aspx –
調試器通常停止在未處理的異常。麻煩的是,它不是無法處理的。您將看到實現未處理的異常調用terminate()的要求的代碼。這是一個std :: thread危險。您必須使用調試>例外>調試這一個,在C++異常中勾選Thrown複選框。 –
你想在調試器中看到什麼?鑑於F10的步驟,你就完成了。你在問如何在另一個玩家身上抓住這個模樣? – doctorlove