我在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