Enforce Visual Studio exception handling mode - c++

I'm using the Visual Studio /EHsc exception handling mode in my project. This means catch(...) won't catch structured exceptions. I've got a public header that does a catch(...) that can be included by consumer projects.
I'm concerned that a project consuming my header may have a different exception handling mode that will make my header misbehave.
Is there a way of static_asserting or #pragma error'ing or otherwise failing the build if the exception handling mode isn't as needed?
See: https://msdn.microsoft.com/en-us/library/1deeycx5.aspx

From https://msdn.microsoft.com/en-us/library/b0084kay.aspx
_CPPUNWIND Defined as 1 if one or more of the /GX (Enable Exception Handling), /clr (Common Language Runtime Compilation), or /EH
(Exception Handling Model) compiler options are set. Otherwise,
undefined.
It's not perfect, but it gives you a fighting chance to get them the same

Related

Visual Studio doesn't break on assert violation

I'm debugging a CMake target in Visual Studio 2019 for a project which is managed by CMake and built using MinGW.
However, when an assertion fails the debugger simply quits without giving me a call stack or letting me inspect the current state of the program. (Normal breakpoints do suspend execution as expected.)
I've enabled Break When Thrown for all C++ Exceptions in Debug > Windows > Exception Settings, but to no avail.
How can I make Visual Studio break execution when an assertion fails?
If your project is a "Console" application rather than a "Windows" application and you have used <assert.h> then according to the documentation:
The destination of the diagnostic message depends on the type of
application that called the routine. Console applications receive the
message through stderr. In a Windows-based application, assert calls
the Windows MessageBox function to create a message box to display the
message with three buttons: Abort, Retry, and Ignore
So a possible solution is to temporarily build your program as a "Windows" app by adding the WIN32 option to your executable definition:
add_executable(<name> WIN32 [source1] [source2 ...])
It is possible that the NDEBUG macro is enabled in your project and that stops VS from breaking on assertion failure.
From cppreference
If NDEBUG is defined as a macro name at the point in the source code
where is included, then assert does nothing.
If NDEBUG is not defined, then assert checks if its argument (which
must have scalar type) compares equal to zero. If it does, assert
outputs implementation-specific diagnostic information on the standard
error output and calls std::abort. The diagnostic information is
required to include the text of expression, as well as the values of
the standard macros FILE, LINE, and the standard variable
func (since C++11).

catch (...) across shared library boundary on gcc mingw

I am a Windows developer with some knowledge of C++ EH and SEH implementation in VC++ but new to MinGW. I have built an open source application on MinGW where a dll throws a C++ exception and a client .exe catches it with two catch clauses. One catch clause is "catch (std::exception &e)" and the subsequent one is "catch(...)".
My application terminates with a call to abort despite the latter catch handler.
From searching the web, I understand that gcc exception handling uses pointer comparison to determine whether that type of a thrown exception matches a catch clause. Which can cause problems if the RTTI type descriptor instance used in the throwing and the catching modules differ. In VC++ a catch handler with ellipsis type ("catch (...)") does not do any type matching. However, for my mingw application the ellipsis catch is not determined as handling the thrown exception. I tried to set a breakpoint on ___gxx_personality_v0 to debug this but gdb says that symbol is undefined even though "nm executable.exe" built with debugging shows the symbol as defined.
Any ideas about how "catch (...)" is handled by the personality routine ? Any pointers on how to debug and/or fix this would be appreciated. I really would like the app to terminate cleanly without a popup saying "The application has requested to be terminated in an unusual way".
Thanks for any help,
--Patrick
Update: I found the solution in another post here about the same issue: Exceptions are not caught in GCC program . It turns out that both the dll and the executable were built with "-static-libgcc". Changing that to "-shared-libgcc" fixed the issue.
The quote from the gcc manual from the above post:
... if a library or main executable is supposed to throw or catch exceptions, you must link it using the G++ or GCJ driver, as appropriate for the languages used in the program, or using the option -shared-libgcc, such that it is linked with the shared libgcc.

C++ Visual Studio- settings to catch exception caused from Boost library?

What settings must I set in Debug -> Exceptions so that my catch statement will catch an exception arising from a boost header file? I have try-catch statements but when an exception occurs it just highlights the line of the exception and asks whether I wish to break or continue.
In Debug->exceptions I have ticked both boxes for "C++"
(C++ user unhandled is ticked, but grayed-out)

Why is this exception not being caught across DLLs?

I have a DLL which throws an exception like so:
throw POMException(err, drvErr, errmsg);
The calling code is in a separate program, and has a try, catch block like so:
try
{
// function in separate DLL
}
catch (TXNPDO_Exception& e)
{
SR_PERFLOG_MSG(SR_PERFMASK_SELECT, "ERROR selectInStages");
TXNDBO_THROW(e);
}
Where TXNPDO_Exception is defined in an included file:
#define TXNPDO_Exception POMException
When running this in a debugger, it states that the POMException was unhandled. I even added a catch(...) clause and it still isn't handled.
I suspect that this has something to do with the Visual C++ compilation parameters, since the DLL library in question is a legacy library that is compiled separate to the program calling it. I am using Visual Studio 2003.
The DLL cpp files are compiled with the following (relevant) flags: /X /GR /Ob1 /Zi /GX /Od /MDd /LD. Other exceptions within the calling program are handled correctly.
Can anyone provide reasons why this exception isn't being propagated to the calling program?
Edit:
The DLL library was previously compiled with possible build environment and code changes that are not available to me. The previously compiled library propagates exceptions correctly.
I am compiling the client program using the same compiler, using mostly the same switches: -Od -W3 -Z7 -MDd -GX -GR -Zm800 (no /X or /Ob1 and /Z7 instead of /Zi).
I would assume that throwing exceptions across .dll boundaries could only be possible, when the various .dll and program executable are compiled against the same C++ runtime, thus sharing the same heap. I could be wrong, but this is my best guess.
Edit:
I guess I wasn't wrong.
I have finally figured out what the problem is, and in this particular case, it is nothing to do with throwing exceptions between DLLs.
The problem is occurring due to an exception handler hook being installed further up the call stack. I diagnosed this by adding try, catch(...) blocks to every level in the library until I found the point at which the exception wasn't propagated. When I commented out the exception handler hook registration code, the exception was successfully propagated.
I now have to figure out the workings of exception handler hooks, which is outside the scope of this question. Thanks to everyone who shared their answers.

using _set_se_translator and compilation flags

Documentation states that "You must use /EHa when using _set_se_translator.".
My question is: should /EHa be used for all files in project/ all files in project that catch exceptions or just in the file that calls _set_se_translator ?
You need it not just for functions that catch exceptions, but also functions that throw and propagate them. The actual call to _set_se_translator itself probably doesn't need to be compiled with /Eha, but why be inconsistent?
After checking I must disagree with what has been said before about all instances needed to be compiled with /EHa. I made a small program with:
crashing code
__declspec(dllexport) void crashMe() { *((int*)0)=0; }
in a DLL compiled without any exception handling at all
calling code elsewhere in a try/catch
Then
Unless the calling code is compiled with /EHa the program will crash
Without _set_se_translator the exception can only be caught in catch(...)