I am trying to handle an exception in Visual Studio Community 2019, note that I am not sure if I have an error with my settings or it is because of my code.
The exception that I am trying to handle is out_of_range. In order to do it I put it within a try block and catch, but I am unable to handle.
When the program runs it prompts a window : Debug Assertion Failed!
Expression vector subscript out of range
#include <iostream>
#include <vector>
#include <stdexcept>
using namespace std;
int main() {
try {
cout << "throwing exception: \n";
throw 1;
}
catch (int i) {
cout << "exception happended!\n";
}
cout << "out of exception\n";
vector<int> v;
try {
cout << "throwing exception2: \n";
v[2];
}
catch (out_of_range e) {
cout << "Exception out of range\n";
cout << e.what();
}
catch (exception& d) {
cout << "General Exception\n";
cout << d.what();
}
catch (...) {
cout << "special excpetinon\n";
}
cout << "Exception handled!";
}
The first exception I am able to handle and the programs continues whereas in the second one the program is stopped and its showing the window Error.
I run the program in debug mode, with the default settings:
I would like to handle the second exception the same way as the first one.
Thanks!
Debug Assertion Failed! Expression vector subscript out of range
isn't an exception. That's the debugger telling you your program went out of bounds and stopped you so you could inspect the program and learn how it happened in order to prevent the program going out of bounds. You can't catch this. You need to fix the bug that allowed the program to access invalid memory.
C++ has a policy of not making a program pay for anything that isn't explicitly asked for. In this case, the checking necessary to allow a catch-able exception to be thrown slows down the program, so the [] operator doesn't perform any checks1. You get a faster program, but you-the-programmer have to promise that the program will never go out of bounds.
The std::vector::at method does check and will throw an exception, but by using at you've opted-in for a slightly slower program.
1Doesn't require any checks is a better way to word this. In this case the vector implementation in the debug version of the MicroSoft standard library implementation does check by default and the "Debug Assertion Failed!" message is the direct result. Debug builds are optimized to make debugging easier and tend to be slow. This checking doesn't happen in the release library because the release builds are optimized for performance.
Related
I'm compiling the following code with Visual C++ 2017 (C++17 features are enabled)
int main() {
try {
// loot is some library that is linked as a dll
auto game = loot::CreateGameHandle(loot::GameType::fonv, "c:\\something\\invalid", "C:\\something\\invalid");
// throw std::invalid_argument("this works as expected");
}
catch (const std::exception &e) {
std::cout << "caught as exception " << e.what() << std::endl;
}
catch (const std::invalid_argument &e) {
std::cout << "caught as invalid_argument " << e.what() << std::endl;
}
catch (...) {
std::cout << "caught by ..." << std::endl;
}
}
The compiler reports, as expected:
warning C4286: 'const std::invalid_argument &': is caught by base class ('const stdext::exception &') on line 8
However, the application output is
caught as invalid_argument Given game path "c:\something\invalid" does not resolve to a valid directory.
And it's not just changing the catch order or something, if I remove the last 2 catch blocks, the application crashes because of the unhandled exception.
How is that even possible? I'm assuming this is somehow related to compiler settings that make my std::exception be a different type from the one std::invalid_argument inside the library inherits from - but why then is my std::invalid_argument the same type as theirs?
Is there a way to fix this? Because that library throws a lot of different exception types and I can't really catch each one individually.
Bloody hell, sorry for this.
It turns out the build system I was using added _HAS_EXCEPTIONS=0 to the preprocessor definitions. That's what's causing this.
There is a CRASH in Function() due to some exceptions so, throw X would not be called. In this case how to call catch block to handle exceptions?
NOTE: we can't modify the code in Function() definition
Sample code:
cout << "Before try \n";
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}
catch (...) {
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
So can anyone help me out for this?
A "CRASH" is not an exception. It is Undefined Behaviour. Absolutely anything could have happened. You are lucky that the system detected it. It could have formatted your disk or summoned daemons out of your nose. Instead the system is only shutting down the process to prevent further damage.
The system might even be so kind as to let you define what to do instead of shutting down the process. The way to define it is system specific. In Unix, you need to install signal handler (the advanced way), in Windows you use structural exceptions.
But the problem is that if the function crashed, there is no way to tell how big mess it left the memory of the process in. You really have to fix the crash. A crash is always a bug.
The fact that a crash is inside that function does not automatically mean the bug is in that function. Most crashes I've seen happened in standard library functions, but they were not bugs in standard library. They were caused by incorrect use of those functions, or sometimes incorrect use of something different much earlier in the program. Because when you invoke Undefined Behaviour, there's no telling when it will cause a crash. Especially buffer overruns and writes to uninitialized pointers tend to cause crashes eventually when some unrelated code wants to use the variable that was overwritten.
That said if the bug is indeed in that function and you can't modify it, you will have to get somebody who can or find an alternative that works better. Because there's no way the program is going to work correctly otherwise.
There's an aditional '}' in the try block in your code. Not sure whether that was an error in typing the code or from another higher level block.
The catch(...){} block will be executed when any unhandled exception is thrown inside the try {} block. It doesn't matter whether the exceptions are thrown directly under the block or somewhere deep down in other function calls in the block.
cout << "Before try \n";
try
{
abc->Function1(); //A potential for crash
abc->Function2(); //Another potential for crash
abc->Function3(); //Another potential for crash
// Do some checks and throw an exception.
throw x;
cout << "After throw (Never executed) \n";
}
catch (...)
{
// This will catch all unhandled exceptions
// within the try{} block. Those can be from
// abc->Function1(), abc->Function2(), abc->Function3(),
// or the throw x within the block itself.
cout << "Exception Caught \n";
}
cout << "After catch (Will be executed) \n";
Hope that is helpful.
Here us the meaning of try and catch
try {
//[if some ABC type exception occur inside this block,]
}catch (ABC) {
//[Then, Do the things inside this block.]
}
So
after the exception occur in your abc->Function(); flow will directly jump in to catch block so write there what you need to do. as example.
try {
abc->Function(); //Here is CRASH
throw x;
cout << "After throw (Never executed) \n";
}catch (Exception ex) {
cout << "Exception Caught \n";
throw ex;
}
actually throw x; doesn't have any use here. because if your abc->Function(); worked fine, then it will throw an exception. so just remove that line.
the code you have written works exactly true . the compiler when see the throw command every where in the try{} it will go to the catch(){} so the cout << "After throw (Never executed) \n"; won't execute and then the code after the catch(){} will execute
for reading more about this case here is the link trycatch
If you got exception ,
abc->Function(); //Here is CRASH
You will enter in catch(...) block.
If you are using Windows OS, for OS generated exceptions you also need to use __try/__catch
Suddenly my code started to throws an exception First-chance exception at 0x7731c41f in VideoPlayer.exe: Microsoft C++ exception: GenICam::RuntimeException at memory location 0x0018f5dc.. I could not find where exactly it throws from, so I commented all in main function and everything outside the main. I started to uncomment blocks of code one by one whilst the code in main remains commented. While doing it I noticed that there is function A that when it is commented there is no exception, but when it's uncommented it throws the exception above.
I don't understand how it can cause exeception if it's not called ( I placed breakpoint in it and code in main is commented)?
You function will be used during the static initialization.
Take the following example:
#include <iostream>
bool static_func()
{
std::cout << "Before main" << std::endl;
return true;
}
static const bool b = static_func();
int main()
{
std::cout << "We are main" << std::endl;
return 0;
}
Since you only see a first chance exception it will be caught and handled. I have seen such constructs in abstract factories for example, where the factory configures itself.
The reason why your breakpoint is not hit must be something else.
In VS, Debug menu, Exceptions... check the throw column for the matching type. Then start debugging and it will stop exactly where throw happens. And you can look around why.
Can an ellipsis try-catch be used to catch all the errors that can lead to a crash? Are there are any anomalies?
try
{
//some operation
}
catch(...)
{
}
No, it'll only catch C++ exceptions, not things like a segfault, SIGINT etc.
You need to read up about and understand the difference between C++ exceptions and for want of a better word, "C-style" signals (such as SIGINT).
If the code inside try/catch block crashed somehow, the program is anyway in a non-recoverable state. You shouldn't try to prevent the crash, the best that the program can do is just let the process crash.
The "anomaly" is in the fact that your code only catches the exceptions, and not the errors. Even if the code is exception-safe (which may be not the case, if you are trying to work-around its mistakes by a try/catch block), any other inner error may bring the program into irrecoverable state. There is simply no way to protect the program from it.
Addition: look at this article at "The Old New Thing" for some insights.
It is the Catch All handler.
It catches all the C++ exceptions thrown from the try block. It does not catch segfault and other signals that cause your program to crash.
While using it, You need to place this handler at the end of all other specific catch handlers or it all your exceptions will end up being caught by this handler.
It is a bad idea to use catch all handler because it just masks your problems and hides the programs inability by catching all(even unrecognized) exceptions. If you face such a situation you better let the program crash, and create a crash dump you can analyze later and resolve the root of the problem.
It catches everything that is thrown, it is not limited to exceptions. It doesn't handle things like windows debug asserts, system signals, segfaults.
TEST(throw_int) {
try {
throw -1;
} catch (std::exception &e) {
std::cerr << "caught " << e.what() << std::endl;
} catch (...) {
std::cerr << "caught ..." << std::endl;
}
}
Throwing an integer isn't really recommended though. It's better to throw something that inherits from std::exception.
You might expect to see something like this as a last ditch effort for documenting failure, though. Some applications aren't required to be very robust. Internal tools might cost more than they are worth if you went through the paces of making them better than hacked together crap.
int main(int argc, char ** argv) {
try {
// ...
} catch (std::exception &e) {
std::cerr << "error occured: " << e.what() << std::endl;
return 1;
}
return 0;
}
The below given simple exception program is giving Unhandled Exception "Microsoft C++ exception: int at memory location 0x0012fe94..". I am getting this error immediately after the function excep() is returned.
Please can anyone tell why this error is coming here. Also it will be helpful if all the possible mistakes in this code were explained/analysed. I am learning to code better.
I am using Visual C++ 2005.
#include <iostream>
using namespace std;
int main ()
{
int excep(int);
throw excep(20);
return 0;
}
int excep(int e)
{
cout << "An exception occurred. Exception Nr. " << e << endl;
return 0;
}
If you try to learn exception throwing/handling your code contains an error.
function excep must handle object that was thrown not to be thrown itself.
your code must be rewritten as follows:
using namespace std;
int excep(int e)
{
cout << "An exception occurred. Exception Nr. " << e << endl;
return 0;
}
int main ()
{
int excep(int);
try
{ // <--------- Begin of try block. required part of the exception handling
throw 20;
}
catch (const int &errCode) // <------- we are catching only ints
{
excep(errCode); // Function that handles exception
}
return 0;
}
It is good design not to throw int variables, but type that inherites std::exception. But this is more advanced exception using knowledge
What did you expect to happen?
You call a function which prints out "An exception occurred", plus the other text, and then you throw the resulting value as an exception, which you never catch, so the program reports than an uncaught exception was thrown. Which is true, because that's exactly what you just did.
The entire point in exceptions is that when you throw an exception, it will propagate out through the program, until it is either handled, or it reaches the top level and terminates the program. You don't handle the exception, so it terminates the program.
If you want to handle an exception, you need to wrap the throwing code in a try block, followed by a catch, as in:
try {
throw excep(20);
}
catch (int ex) {
// do something about the exception
}
In the line
throw excep(20);
excep(20) is called first, whose return value is then thrown, i.e. you throw an integer. It is roughly equivalent to:
const int i = excep(20);
throw i;
To get you an idea how exception-snytax looks:
#include <iostream>
#include <stdexcept>
using namespace std;
int main ()
{
try {
// do something
throw std::runtime_error("test");
} catch (const std::exception &e) {
std::cout << "exception: " << e.what() << std::endl;
}
}
In practive: NEVER throw anything that is not derived from std::exception.
Proposed Readings:
Introductory book on C++ (search stackoverflow for this)
C++ FAQ on Exception Handling
"Exceptional C++" (for advanced C++ users)