Reputation: 4884
I run this code in Visual Studio 2013 (Debug config):
#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;
}
The execution pauses at the breakpoint and I see the Call Stack:
> DemoProj.exe!c() Line 5 C++
DemoProj.exe!b() Line 10 C++
DemoProj.exe!a() Line 16 C++
[External Code]
This is great! I can see exactly where I am in the course of the execution.
After that I go one step (F10) just to execute this exception throwing line. Of course, the exception gets thrown but now my Call Stack looks like this:
> 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
This renders my debugging useless. The line
/* breakpoint here*/ throw std::runtime_error("error");
is just here for this simple example. In real project I will not know where the code will break. And it would be of great help if Visual Studio could stop the execution on the exact line where the error occurred.
But instead, if an exception gets thrown anywhere outside my main thread, I only get these system calls and can never figure out what line in my code is causing the crash.
Any help?
I feel like this question is similar to this one. The idea there is to catch exceptions in side threads and pass them to the main thread so that the main thread can re-throw them. Isn't there some more elegant solution?
Upvotes: 2
Views: 1351
Reputation: 47954
it would be of great help if Visual Studio could stop the execution on the exact line where the error occurred.
Visual Studio has an option to automatically break when an exception is thrown. In Vs 2015 it's Debug -> Windows -> Exception Settings. Tick the C++ Exceptions checkbox under the Break When Thrown heading.
This is helpful for figuring out which code is throwing an exception. The drawback is that, if you have code that routinely throws and handles exceptions, you'll have a lot of undesired breaks in the debugger.
Upvotes: 3
Reputation: 3812
Why not use task based programming. Whenever you want to run code in separate thread, instead of creating and running a new thread just use already exist threads in a thread pool.
C++11 provide std::async
that it's return type is a std::future
:
std::future<void> future = std::async(std::launch::async, []{ a(); });
Every Exception thrown in other thread will be catch and store in std::future
object and will throw if you call get
on the std::future
.
If you want to have stack trace you can write a custom exception that in it's ctor it use platform specific functions to capture stack function names and store them in itself.
Upvotes: 0