A program of mine throws a std::out_of_range. I know the reason for that, I'm accessing a vector with index -1 somewhere. What I don't know is the name of the vector (variable name) and location in the code. The error message produced by my program looks like this:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
zsh: abort (core dumped) ./main.x config.cfg
whereas the error message produced by the code of some other guy (he uses g++ too) and posted in the question C++ accessing vector looks like this:
Error for vec.at(i).setVec(tmp);
Error is: terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
I.e. he is told the name of the variable. My question is:
Is there any way to tell g++/gcc to give me the extended info? Maybe even include line numbers (don't know whether that's possible but hey, a guy can dream ;) ).
Just for funsies I ran my program in gdb with the catch thrown option (I might add, I have near zero experience in using an actual debugger) which didn't tell me anything new either, in fact, it didn't tell me that the error was due to a std::out_of_range exception.
Btw, my compiler flags (for debug) are:
CFLAGS = --exceptions -I$(ROOTSYS)/include --std=c++11 -Wall -g -O0 -fno-inline -fno-eliminate-unused-debug-types
After hitting the breakpoint enter bt (backtrace) command in the gdb shell. This will print the stack trace (a sequence of function calls leading to the error).
To get the variable name you can now use up command to navigate upwards in the stack and see what variables where used in each of those functions.
Put a breakpoint on std::out_of_range::out_of_range. An exception object, like all C++ objects, starts its life after its constructor exits.
[EDIT]
Comment made it clear: the problem the string produced by std::out_of_range::what(). That's implementation-defined. Obviously in your case it's composed from __FUNCTION__, a GCC macro which names the current (i.e. throwing) function. But such a function only knows this, i.e. the pointer to the current object and not its name. In the other case, the objects name is retrieved via some other method, not std::out_of_range::what().
To avoid hitting a break point at every exception thrown and stop only atstd::out_of_range use this command in gdb:
catch throw std::out_of_range
Then run the commad bt or where when the breack point is hit to see where in the code the exception was thrown
Related
I'm using unordered_map<std::string, Thing>.emplace where Thing is a class I wrote. Thing may throw an exception in its constructor.
I observed that if Thing throws while being constructed by emplace, the program simply crashes - but without any exception message. (I had to step in the debugger to figure out it was Thing::Thing() throwing an exception, as opposed to any other reason for a crash).
On this cppreference page it says
If an exception is thrown by any operation, this function has no effect.
However - what exactly is meant by "no effect"? I figure the container would stay un-touched. But does the standard make any guarantee as to what else happens to the program? Why doesn't it show the exception as we would expect? emplace is not marked as noexcept.
EDIT:
Elaborating a little bit.
I do not attempt to catch this exception anywhere (if I do, it gets caught). The thing is, I am used to uncaught exceptions printing a message to the console, before crashing the app (I'm running Windows 7 with Mingw-w64 G++).
For example, here is what I'm used to get from an uncaught exception:
terminate called after throwing an instance of 'std::runtime_error'
what(): Failed to make sandwich, tomato was not good
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
However - in this case, I only get the general crash message (which I also get for segfaults, for example):
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
So the question becomes - does the standard (or at least the Mingw-w64 implementation) guarantee any sort of console output from an uncaught exception? What are the rules about when we do and when we don't receive such an output? Is the fact the I don't get an output now related to my own program, to unorderd_map.emplace or to something else?
I was wondering, will new T still throw bad_alloc if I compile my program using the -fno-exceptions option to disable exception handling?
Or will the compiler (GCC and clang support that option) implicitly transform the use of new T to new (nothrow) T?
The way I understand it, operator new is defined by libstdc++. If you now compile your own code with -fno-exceptions, you cannot catch any exceptions, but you will still be linking against the normal version of libstdc++, which does throw an exception.
So yes, new T will throw an exception, even with -fno-exception.
However, if you compiled libstdc++ with -fno-exception as well, things become different. Now, new T cannot throw an exception but, if I read the libstdc++ manual right it will call abort() instead.
It seems that, if you want your new T to return NULL on failure, the only way is to explicitely specify nothrow...
I can't give a definitive answer to all the perks around -fno-exceptions, just the observations on a 32 bit linux machine, gcc 4.5.1 - bad_alloc is thrown with and without -fno-exceptions
[21:38:35 1 ~/tmp] $ cat bad_alloc.cpp
int main()
{
char* c = new char[4000000000U];
}
[21:38:58 1 ~/tmp] $ g++ bad_alloc.cpp
[21:39:06 1 ~/tmp] $ ./a.out
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
[21:39:07 1 ~/tmp] $ g++ -fno-exceptions bad_alloc.cpp
[21:39:16 1 ~/tmp] $ ./a.out
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
It's not a definitive answer, but the GCC Manual (see the section "Doing Without") has this:
Before detailing the library support
for -fno-exceptions, first a passing
note on the things lost when this flag
is used: it will break exceptions
trying to pass through code compiled
with -fno-exceptions whether or not
that code has any try or catch
constructs. If you might have some
code that throws, you shouldn't use
-fno-exceptions.
The way I read that, you might have to explicitly ask for the nothrow version of new to be completely safe.
In many exception-handling systems, if routine "foo" calls "bar", which in turn calls "moo", and "moo" throws an exception, the only way that exception can cleanly make it back to "foo" is if "bar" has code to handle the exception. Even if "bar" is going to let the exception propagate uncaught, it will generally have to ensure that its local variables get properly destroyed before execution is allowed to leave scope. This will require adding extra code to "bar"; in most systems, some of that code will have to execute even if no exception is thrown.
BTW, on some ARM processors like the Cortex M3, or like the Arm7 running in ARM mode, if the caller is also going to be running in ARM mode, one could allow for exceptions without any execution-time cost by having a "normal" subroutine return go to LR+4 (four bytes beyond the normal return address) and have an exceptional exit go to LR (which would then be a 4-byte branch instruction). Such behavior would be contrary to normal practice on the ARM, though, and such a design would not port nicely to the Cortex M0.
I am programming in C++ on Linux platform.
My program terminates with this (unhandled???) exception:
"terminate called after throwing an instance of 'long'"
Aborted
The code that is throwing the exception is inside try-catch block, then why should this happen??
The exception is thrown while returning from a function.
I am used to C programming and have very little experience in C++ (which is the main problem). I don't know how to debug this issue. I don't expect a solution but a direction/pointer for debugging this problem.
Thanks in advance.
You can run your application under gdb (having built it with debug info using -g) and get it to break when an exception is thrown using the command:
(gdb) catch throw
This will take you to the origin of the exception. Some more info is available in this question:
Run an application in GDB until an exception occurs
Note that it is somewhat unusual to throw an ordinal type (such as a long). It may be in some temporary code, so grepping around might find it quickly enough.
It there anywhere on the call-stack with a exception specification or here? If there is then you might have this problem - you probably want to remove all of them.
If you are using gcc, then you can add this code first thing in main():
#ifdef __GNUC__
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
#endif // ifdef __GNUC__
(More details at http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html)
Which will give you a better traceback from such exceptions.
you are probably catching the wrong exception type
use
catch(long)
or
catch(...)
Normally, I would recommend to set a breakpoint in the constructor of the thrown type -- but in this case ... I must admit to never have experienced that somebody has thrown a long like
throw 42;
That seems to me strange. Some debuggers might be able to catch an exception when it is thrown.
Is the called function yours?
Use set_terminate to break GDB
Example for set_terminate() is here
When it trigged - use bt command in GDB to see backtrace
I have a program failing with:
terminate called after throwing an instance of 'std::bad_alloc'
what(): St9bad_alloc
I imagine it's something to do with malloc/free, but I don't know which one.
What breakpoint can I in gdb set that will break on the error so that I can view a stack trace?
The program is a combination of C and C++, compiled with gcc 3.4.2.
It is not really malloc/free which causes the exception, it is "new" which is definitely in C++ part of your application. It looks like you are providing a parameter which is too big for "new" to allocate.
'std::bad_alloc' is caused by the following code for example:
int * p = new int[50000000];
What does backtrace says when you load crash dump into gdb?
If you cannot generate dump, you can ask GDB to stop when exception is thrown or caught.
Unfortunately, some versions of GDB support only the following syntax:
catch throw
which allows you to break application when any exception is thrown.
However, in help you see that it should be possible to run
catch throw std::bad_alloc
in newer versions.
And don't forget that:
(gdb) help catch
is a good source for other useful information.
It's quite possible that this happens due to some memory being overwritten, thus corrupting the memory allocation system's state (which is generally kept either before or after the memory blocks returned to the application).
If you have the possibility (i.e., you're on x86 Linux), run your program in Valgrind, it can often show you exactly where the corruption happens.
I have had this when trying to read in a file that doesn't exist... I'd try to create an internal buffer for the file contents, but because the file didn't exist, my creation of the buffer screwed up.
int lenth_bytes;
length_bytes = in_file.tellg();
new char [length_bytes]; // length_bytes hadn't been initialised!!!!
Remember kids, always initialise your variables :D and check for zero cases.
While running my program I get this error:
terminate called after throwing an instance of 'std::length_error'
what(): basic_string::_S_create
Abort trap
I know that you can't do much without the code but I think that this error is too deep in the code to copy all of it. Maybe I can figure it out if I understand what this error means.
Is this a sign for an issue with reading or writing at the wrong memory address?
Is there something I can do to get more information about the problem from my program?
It means you tried to create a string bigger than std::string::max_size().
http://msdn.microsoft.com/en-us/library/as4axahk(VS.80).aspx
An exception of type length_error Class
is thrown when an operation produces a
string with a length greater than the
maximum size.
I know this is a old question but I just ran into the same issue.
Using Linux with gcc.
Disassembling the function showed a lot of jumps in the code, where the exception was thrown, which shouldn't be there.
In the end, a Clean Build resolved the issue for me.
This is an error in debug mode with VS2005. When I change it to release mode, everything works.
Well, the vc debug runtime causes this, that's all.