Catch block being bypassed on boost exception - c++

Environment: Windows 10, Visual Studio 2015, x64, Unicode, boost 1.64
I'm having problems determining why a catch block is not being hit when a boost exception is purposely attempted. The point it to let boost tell me if a source string for a date is of the wrong format.
Here is the code in question:
std::string sDate("01/03/2017"); // purposely bad date format, should be 2017/01/03
bool bGoodDate(true);
try
{
boost::gregorian::date dtTemp(boost::gregorian::from_simple_string(sDate));
}
catch (const std::out_of_range& e)
{
bGoodDate = false;
}
catch (...)
{
bGoodDate = false;
}
When this code is in a stand-alone console program, it works. The out_of_range catch block is hit. But when the same code is in a Windows GUI app built with MFC in a static library (not sure that's relevant), the catch block is never hit. Instead, I see this boost exception wrapper referenced in an Unhandled Exception error thrown by the GUI app:
Unhandled exception at 0x00007FFC0BC09E08 in Journal.exe: Microsoft C++ exception: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::gregorian::bad_day_of_month> > at memory location 0x00000078A3DEB100.
I have compared the compiler, debugger and linker settings between the two projects, and there were no differences, other than the number of third party libraries being larger in the GUI project, and the few console-vs-gui settings needed to build the applications.
I found this seemingly related question/answer, but I'm not sure how I'd go about finding a solution based on that answer: Weird issue with catching trivial boost exception
Any ideas on how I could track down the cause of this behavior?
Thanks.

Related

Visual Studio Exception settings ignored C++

I'm testing the assert method in C++ in Visual Studio 2017 and am getting an assertion exception as I would have expected. But after turning off all(!) exception settings I still get an exception thrown before it can be handled by my catch block (see below for an example).
try {
assert(validate(1363821) == false);
assert(validate(3848238) == true);
printf("Validation correctly implemented.");
} catch ( exception & e ){
const string error = e.what();
printf("Validation failed!");
}
So my questions are:
Am I doing something wrong here?
Or does the assert method throw some sort of exception which can't be handled by a catch block and will always generate a fatal exception? If so, how can one implement an assert method without creating fatal errors?
My exception settings are not set as is shown below:
Any help is greatly appreciated!
Assertion failure is not supposed to throw any exceptions. Instead it performs some implementation-specific report actions (such as printing an error message into stderr or showing that dialog) and then calls std::abort. So catch block and / or exception handling settings in IDE won't do anything in this situation. If you want assertion to throw an exception then you will need to write your own assert macro substitution.
If you are looking for some sort verification checking then you better utilize some dedicated framework, such as boost::test. Then you can write simply:
BOOST_AUTO_TEST_CASE(Doc_Parse_Empty)
{
BOOST_TEST(validate(1363821) == false);
BOOST_TEST(validate(3848238) == true);
}
It will also handle success/failure reporting automatically and seamlessly integrates into VS.

How to trap an error in C++ when __try __except can't

I have code that uses a 3rd party library.
That library throws the occasional Access Violation exception. A basic try/catch didn't catch the error, and the program would hard crash.
I was able to use a __try __except instead, to catch the error, log it, and then gracefully exit the program.
The 3rd party has just updated their library, and now a small subset of the records that were causing the access violation errors just dies in production with "[program name] has stopped working"
In Visual Studio, when stepping thru I get "Microsoft Visual Studio C Runtime Library has detected a fatal error in [program name]."
I've updated my __except statement to catch everything (or so I believe), and it still happens.
Original __except:
__except (eps = GetExceptionInformation(), ((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH)) {
sprintf("error message");
result = 99;
}
New __except:
__except (eps = GetExceptionInformation(), ((1 == 1)
? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH)) {
sprintf("error message");
result = 99;
}
Just a friendly FYI, the first expression in your exception filter eps = GetExceptionInformation() appears to be unused.
Also, if you want to catch all exceptions then __except (EXCEPTION_EXECUTE_HANDLER) should be all you need. Although I would only recommend that for debugging purposes.
If this does not catch your exception, it is possible that the library is trying to handle the exception itself and something funky is going on in the library itself. I would check with the provider of the library and ask if this is a known issue.

c++ try/catch ignorance in iOS

In our app we have a c++ static library and I use Objective-C++ to work with it.
That c++ library utilizes rapidjson to parse XML data:
try {
rapidjson::Document document;
document.Parse(connection.data.description);
connection.openTime = document["openFrom"].GetInt();
connection.closeTime = document["openTo"].GetInt();
return true;
} catch (std::exception e) {
connection.openTime = 0;
connection.closeTime = 0;
return false;
}
The problem is that if document["openFrom"] cannot be converted into Int via GetInt() method, exception is not raised. Instead of that my app crashes with SIGABRT.
Assertion failed: (data_.f.flags & kIntFlag), function GetInt, file /Users/xxx/xxx/xx/ios/../src/rapidjson/document.h, line 1645.
On Android OS, btw, in the same case exception is raised successfully.
What could be the problem? I guess the issue is in Xcode's Swift compiler behavior.
As it clearly stated in the log you provided – it is not a crash, it is only a failed assert which internally calls abort() that results in SIGABRT which stands for 'signal abort'. Asserts are disabled in release mode so it should work fine there. Or you can disable asserts in rapidjson (by defining macro RAPIDJSON_ASSERT).

How is it possible to know what caused an exception

In the code I am implementing I have
__except(EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
And there is an execution path when the exception occurs
How can I know why the exception happened while debugging?
Use GetExceptionInformation?-Can it print the exception or give me exception`s data?
In Visual Studio, you can go to Debug > Exceptions (in the menu). There's a checkbox for each exception type which enables you to break execution when the exception is thrown.

How can I catch an invalid fgetpos call as a C++ exception on Windows?

In Visual C++ 2008, I want to "catch" an exception generated as shown here:
try {
int foo = 20;
::fgetpos(0, (fpos_t*)&foo);
}
//...
Here are adjustments I've made to attempt a successful catch:
SEH is activated (/eha)
I've added a catch(...)
I've added a _set_se_translator vector.
I've added/adjusted to SEH syntax: __try / __except(EXCEPTION_EXECUTE_HANDLER)
In short, I've tried "everything in the book" and I still can't catch the exception. If I replace the call to ::fgetpos with int hey = foo / 0 then suddenly all of the above techniques work as expected. So the exception I'm dealing with from ::fgetpos is somehow "extra special."
Can someone explain why this ::fgetpos error seems uncatchable, and how to work around it?
update When executed in the VS IDE, the output window doesn't name an exception. All it says is this:
Microsoft Visual Studio C Runtime Library has detected a fatal error in MyProgram.exe.
Not very helpful. When I run the console app from the command line, I get a crash dialogue. The "problem details" section of the dialogue includes this information:
Problem Event Name: BEX
Exception Offset:0002fd30
Exception Code: c0000417
Exception Data: 00000000
Additional Information 1:69ad
Additional Information 2:69addfb19767b2221c8e3e7a5cd2f4ae
Additional Information 3:b1ff
Additional Information 4:b1ffca30cadddc78c19f19b6d150997f
Since the code in your dump corresponds to STATUS_INVALID_CRUNTIME_PARAMETER, try _set_invalid_parameter_handler
Most likely, the runtime catches it for you and issues a debug dialog without returning or propagating the exception- that is a CRT call and they may add whatever exception catching code in there they like. It's well within Visual Studio's rights to catch a hardware exception inside a library function, especially if you are running from within the IDE or in debug mode, then it is expected of the runtime.
Of course, when you divide by zero, then there is no library call here to write that extra catching code.