Search code examples
c++visual-studio

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


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

Solution

  • 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.