2

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?

5
  • 2
    After the exception has already been caught, there is nothing you can do. The stack has already been unwound. You can however write your own exception class that dumps the stack (read StackWalk64) before actually throwing anything. msdn.microsoft.com/en-us/library/windows/desktop/… Commented Jan 9, 2017 at 11:08
  • 1
    The debugger normally stops on an unhandled exception. Trouble is, it is not unhandled. You are seeing the code that implements the requirement that an unhandled exception calls terminate(). It is an std::thread hazard. You'll have to debug this one with Debug > Exceptions > tick the Thrown checkbox for C++ exceptions. Commented Jan 9, 2017 at 12:36
  • 1
    What do you want to see in the debugger? Given F10 steps over the line, and you're done. Are you asking how to catch the exeception on another thead? Commented Jan 9, 2017 at 13:12
  • The line where I throw the exception is just 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 executing on the exact line where the error occurred. I will update the question. Commented Jan 9, 2017 at 14:56
  • 1
    When I wrote my answer, I thought you want to log exceptions from worker threads. In VS2015 there is ExceptionSetting window that you can check various exceptions to always break when they get thrown. Also __debugbreak() compiler intrinsic in VC++ force debugger to break. Commented Jan 9, 2017 at 16:01

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, this is the answer I was looking for. MRB already answered it in the comment. But I cannot accept comment as an answer...
0

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.

2 Comments

I was not the one who downvoted, I hope an explanation will come for that downvote.
@ancajic As I understand you want a way of exception logging in concurrent environment, and I think it's a way of doing that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.