How to know the exact line of code where an exception has been caused?

If I generate an exception on my own, I can include any info into the exception: a number of code line and name of source file. Something like this:

throw std::exception("myFile.cpp:255");

But what's with unhandled exceptions or with exceptions that were not generated by me?


A better solution is to use a custom class and a macro. :-)

#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>

class my_exception : public std::runtime_error {
    std::string msg;
public:
    my_exception(const std::string &arg, const char *file, int line) :
    std::runtime_error(arg) {
        std::ostringstream o;
        o << file << ":" << line << ": " << arg;
        msg = o.str();
    }
    ~my_exception() throw() {}
    const char *what() const throw() {
        return msg.c_str();
    }
};
#define throw_line(arg) throw my_exception(arg, __FILE__, __LINE__);

void f() {
    throw_line("Oh no!");
}

int main() {
    try {
        f();
    }
    catch (const std::runtime_error &ex) {
        std::cout << ex.what() << std::endl;
    }
}

It seems everyone is trying to improve your code to throw exceptions in your code, and no one is attempting the actual question you asked.

Which is because it can't be done. If the code that's throwing the exception is only presented in binary form (e.g. in a LIB or DLL file), then the line number is gone, and there's no way to connect the object to to a line in the source code.


There are several possibilities to find out where the exception was thrown:

Using compiler macros

Using __FILE__ and __LINE__ macros at throw location (as already shown by other commenters), either by using them in std exceptions as text, or as separate arguments to a custom exception:

Either use

throw std::runtime_error(msg " at " `__FILE__` ":" `__LINE__`);

or throw

class my_custom_exception {
  my_custom_exception(const char* msg, const char* file, unsigned int line)
...

Note that even when compiling for Unicode (in Visual Studio), FILE expands to a single-byte string. This works in debug and release. Unfortunately, source file names with code throwing exceptions are placed in the output executable.

Stack Walking

Find out exception location by walking the call stack.

  • On Linux with gcc the functions backtrace() and backtrace_symbols() can get infos about the current call stack. See the gcc documentation how to use them. The code must be compiled with -g, so that debug symbols are placed in the executable.

  • On Windows, you can walk the stack using the dbghelp library and its function StackWalk64. See Jochen Kalmbach's article on CodeProject for details. This works in debug and release, and you need to ship .pdb files for all modules you want infos about.

You can even combine the two solutions by collecting call stack info when a custom exception is thrown. The call stack can be stored in the exception, just like in .NET or Java. Note that collecting call stack on Win32 is very slow (my latest test showed about 6 collected call stacks per second). If your code throws many exceptions, this approach slows down your program considerably.


The simplest solution is to use a macro:

#define throw_line(msg) \
    throw std::exception(msg " " __FILE__ ":" __LINE__)

void f() {
    throw_line("Oh no!");
}

If you have a debug build and run it in the Visual Studio debugger, then you can break into the debugger when any kind of exception is thrown, before it propagates to the world.

Enable this with the Debug > Exceptions menu alternative and then check-marking the kinds of exceptions that you are interested in.

You can also add the ability to create a dump file, if the application source code is your own. With the dump file and PDB files (symbols) for the specific build, you'll get stacktraces with WinDbg, for example.