Exception messages hidden by visual studio/debugger breaking on the wrong line
Asked Answered
S

2

6

Visual studio is hiding my exception messages. Take the following code example:

#include <stdio.h>
#include <iostream>
#include <exception>

void exceptional_method(){
    throw std::runtime_error("Hello from exceptional_method!");
}

int main(){
    std::cout << "Hello world!" << std::endl;
    exceptional_method();
    std::cin.get();
}

Visual studio gives me some vague addresses:

Unhandled exception at 0x76A9DDC2 in ExceptionTest.exe: Microsoft C++ exception: std::runtime_error at memory location 0x006FFD34.

Whereas linux mint gives me the following output on the terminal:

Hello world!
terminate called after throwing an instance of 'std::runtime_error'
  what():  Hello from exceptional_method!
Aborted (core dumped)

I've googled a bunch, messed around with the settings in Visual studio, but cannot figure this out. My current workaround is writing the exception message to console before throwing so that I can at least catch the message so I know which exception was thrown.

inline void throw_exception(string& message)
{
    cout << message << endl;
    throw runtime_error(message);
}

This is not ideal. Any help would be greatly appreciated.

edit: Getting the debugger to break on the actual exception instead of a few lines ahead was the problem, causing me to investigate the wrong code. The following solution is what I was looking for.

#ifndef DEBUG_ASSERT_H
#define DEBUG_ASSERT_H

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

inline void log_failed_assert(const string message, const string expression, const string file, const long line) {
    cout << "Assert failed." << endl;
    cout << "Expression: "   << expression  << endl;
    cout << "Message   : "   << message     << endl;
    cout << "File      : "   << file        << endl;
    cout << "Line      : "   << line        << endl;
}

inline void windows_break()
{
#ifdef _WIN32
    __debugbreak();
#endif
}

//do {
//} while (0)

#ifdef _DEBUG
#ifdef _WIN32
#define DEBUG_ASSERT(expr, s) do{\
    if(!(expr)){\
        log_failed_assert(s, #expr, __FILE__, __LINE__);\
        __debugbreak();\
    }\
    } while(0)
#else
#define DEBUG_ASSERT(expr, s) do{\
    if(!(expr)){\
        log_failed_assert(s, #expr, __FILE__, __LINE__);\
    }\
    } while(0)
#endif
#else
#define DEBUG_ASSERT(expr, s)
#endif

#endif
Sosthena answered 26/9, 2018 at 8:11 Comment(15)
Put a try catch block around the code in main and output the exception message from the catch. Linux Mint is just being helpful, there is no requirement for the tool-chain to include the code to output uncaught exception messages.Distill
@RichardCritten Tried this and you are right. What if I don't want to catch the exception? I use exceptions in another codebase for debugging. I want to break where it goes wrong. Does this mean I can't use exceptions for this purpose?Sosthena
@Sosthena You can catch the exception and then rethrow it. Just add throw; to the end of your catch block.Azaria
To break when exception is thrown in VS you can set up Exception Filters. Note that throwing (uncaught) exceptions does not require cleanup either so you application may not exit properly.Olivenite
I'm looking at assert() from assert.h now. Seems to do exactly what I want.Sosthena
Note that assert is a macro and it's not enabled in typical release builds. Anyway, you should never let internal exceptions or assertions reach the end-users; Catch them, log them, and then tell the user something nice and sugarcoated, and exit.Grain
@Someprogrammerdude I'm aware of this, as I said before I just want to break while debugging. This is not supposed to end up in a release build. A macro is perfect for this because you can define an empty version of the macro in release builds.Sosthena
Well if you want to break while debugging, that will happen automatically when throwing an exception. The VS debugger should break directly to the location where the exception is thrown.Grain
@Someprogrammerdude while it does break, it breaks on the wrong line. This caused the initial problem. see: i.imgur.com/WgYEMHg.pngSosthena
Well unless you have two consecutive lines both with throw statements in them, then it shouldn't be that hard to figure out the exception is the one from the previous line. :)Grain
Maybe for you, I spent a whole day pulling my hair out. That should be unnecessary. Then again I'm a C# dev and not a C++ dev.Sosthena
@RichardCritten Please add you comment as answer so I can mark this question answered.Sosthena
Possible duplicate of Where can I see the what() message from an unhandled std::exception in Visual Studio 2012?Impetigo
I would propose changing the function to something longer like void exceptional_method(int i=0) { if (i == 0) { throw std::runtime_error("Hello from exceptional_method!"); } int x = i; } - so that we see that it breaks after the block with the exception.Cherubini
HMM, why not catch everything and print it out?Transitory
S
4

Exceptions are there to be catched. If you dont catch it your program will terminate. If this is what you want, there are easier ways to terminate. If you catch the exception in main you can use the message to eg print it:

#include <exception>
#include <iostream>
void exceptional_method(){
    throw std::runtime_error("Hello from exceptional_method!");
}

int main(){
    std::cout << "Hello world!" << std::endl;
    try {
        exceptional_method();
    } catch (std::exception& e) {
        std::cout << e.what(); 
    }
    std::cin.get();
}

As RichardCritten pointed out, it is mint being nice to you rather than visual studio "hiding" the message, as there is no requirement to print the message when your program terminates.

Sharkey answered 26/9, 2018 at 9:1 Comment(10)
Since RichardCritten didn't add his own answer, Ill mark this one.Sosthena
that's really annoying. I have to disable the catch statement to see the exception's message..... is there no way to instpect the exception directly when the debugger breaks on its throw?Cabala
@Cabala you dont need to "disable the catch". e.what() is the message of the exception. The posted code should display the message on the screen when it is catchedSharkey
that message doesn't include the source code location...Cabala
@Cabala then include it the message... something like throw std::runtime_error(std::string("Hello from exceptional_method!") + std::to_string(__LINE__) + std::to_string(__FILE__));Sharkey
it's a 3rd party lib that throws them. The catch also prevents the debugger from stopping at the appropriate location. isn't there a MSVC extension to dump std::exception messages when the debugger intercepts them?Cabala
@Cabala you seem to have an issue that is different from the question here. Then you should ask a new questionSharkey
This is not a useful answer, C++ developers know how to use try/catch. Visual Studio is an IDE with a debugger (so it's a reasonable expectation it can display uncaught exception messages) and if there's no way it can then there is no answer to this question.Cutout
@RusellNewman you should ping OP rather than me. I already wrote the best answer I was able to write. As this ansewr was accepted by OP probability that someone else writes an answer is rather low. Even if I realized the ansewr is so bad I should be deleted, I cannot, because as accepted answer it is blocked.Sharkey
@RusselNewman I started a bounty. this will help to draw more attention to the question.Sharkey
P
1

Visual Studio will show you the exception when it is thrown when you disable just my code in debugger settings. It will also show the address of the exception object (0x000000980FB3FA48) which you can add to a watch window and cast to the Exception object to inspect its contents.

enter image description here

enter image description here

To make the cast work you need to double click the method which throws the exception so the debugger can cast to the right object type or it will just display that it cannot cast to an unkown type.

Phantasm answered 5/9, 2024 at 6:2 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.