0

Given the basic code:

std::vector<int> foo(10);
foo.at[100] = 42;

This will throw an std::out_of_range as expected, and the default behaviour on my machine is to print a string like:

terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 100) >= this->size() (which is 10)

If I wrap the code with a try/catch:

try {
    foo.at[100] = 42;
} catch (std::out_of_range e) {
    printf("Error at %s line %d\n", __FILE__, __LINE);
}

I can of course get the line where the problem occurs, but if the code has tens of uses of at and I do this:

try {
    functionThatCallsAtFromLotsOfPlaces();
} catch (std::out_of_range e) {
    printf("Error at %s line %d\n", __FILE__, __LINE);
}

I only get the line number of the catch, not the throw.

On the other hand, if I load up the program in gdb and type catch throw, gdb will hand control back to me at the throw, so I can easily trace where exactly the error is, not where it was caught. Is there a mechanism in C++11, or gcc-specific, where I can emulate what gdb is doing?

Note, there is this question, but that is for signal errors; it doesn't work for me for normal throws.

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
  • 1
    You can't do much about the std exceptions. You can intercept your own class throws so that they record __FILE__ and __LINE__ info if you wish, but you do need a macro to do it. This can be useful for debugging if you throw the same exception from a number of places, but perhaps it is better to throw unique derived exceptions, and catch the base - a log message at the catch can get the type name of the actual exception site. – Gem Taylor Apr 11 '18 at 11:14

1 Answers1

2

boost::exception e.g. stores the stack trace on an initial throw. std:: exception doesn't and hence you can't see the stack trace before it was unrolled. Rethrowing the original exception nested in something like a Boost exception would provide you a stacktrace, but still only up to the creation of the nested exception.

There is no way around that, all you could do, is installing a custom handler to catch exceptions as they are thrown, but that is very much compiler and runtime specific. Essentially you would use the ports which area designed for debugging.

Anyway, you should really not care about stack traces for an exception you have caught. It's better to just let the exception crash in such case, and utilize full crash dump creation with Breakpad or alike, for posthum analysis with not only full stack trace, but also stack contents intact. Only catch exceptions from which you intend to recover, everything else is just error concealing (even if not intended) and makes debugging harder.

Ext3h
  • 5,713
  • 17
  • 43