-fno-exceptions for some libraries? - c++

This is somewhat similar to "Disabling C++ exceptions, how can I make any std:: throw() immediately terminate?." I would like my program to terminate whenever an exception is thrown out of the STL.
The problem is as follows: I am writing a library which is then loaded as a shared object and executed by a program I don't have control over. Unfortunately this program runs everything in a big try bock so that I don't get a stack trace/core dump if an error is thrown, rendering the ::at class of function's out of range error useless.
This sounds like the ideal use case for -fno-exceptions, but I can't just use -fno-exceptions, because boost_log and the program that calls me both have exception handling defined in their headers giving me compile errors with -fno-exceptions.
Is there a way to enable -fno-exceptions only for stl exceptions?

With C++11, the easiest way to do is to add noexcept to the signature of the top level function that is called from your shared library:
void called_func() noexcept;
This will cause any unhandled exceptions in the called_func stack frame (or below if they are not handled) to terminate the execution of the program.

Related

Convert NULL pointer access to C++ exception under Linux/GCC

Is there any way to convert a NULL pointer access into a C++ exception under Linux ? Something similar to the NullPointerException in Java. I hope the following program would return successfully, instead of crash (assume the compiler cannot figure out this NULL pointer access during compile time):
class NullPointerException {};
void accessNullPointer(char* ptr) {
*ptr = 0;
}
int main() {
try {
accessNullPointer(0);
} catch (NullPointerException&) {
return 1;
}
return 0;
}
I'm not expecting any standard way of doing it, since NULL pointer access under C++ is undefined-behavior, just want to know how to get it done under x86_64 Linux/GCC.
I did some very primitive research in this, it might be possible:
When a NULL pointer is access under Linux, a SIGSEGV will be generated.
Inside the SIGSEGV handler, the program's memory and register information will be available (if sigaction() is used to register the signal handler). The instruction which caused the SIGSEGV is also available if the program is disassembled.
Modify the program's memory and/or register, and create/fake an exception instance (maybe by invoking the low level unwind library functions, like _Unwind_RaiseException, etc.)
Finally return from the signal handler, hope the program would start a C++ stack unwinding process like a normal exception was thrown.
Here's a quote from GCC's man page (-fnon-call-exceptions):
Generate code that allows trapping instructions to throw exceptions. Note that this requires platform-specific runtime support that does not exist everywhere. Moreover, it only allows trapping instructions to throw exceptions, i.e. memory references or floating point instructions. It does not allow exceptions to be
thrown from arbitrary signal handlers such as "SIGALRM".
It seems this "platform-specific runtime" is exactly what I want. Anyone knows such a runtime for Linux/x86_64 ? Or give me some information on how to implement such a runtime if no such runtime already exists ?
I want the solution to work in multi-threaded program as well.
No, there's no good way to do that, and there shouldn't be. Exceptions are thrown by a throw statement in source code. That's important for reasoning about exception safety: you can look at the code and see the places where exceptions can be thrown and, perhaps more important, you can look a the code and see the places where exceptions will not be thrown. If pretty much anything you do can throw an exception it becomes very difficult to write exception-safe code without cluttering it with catch clauses. Microsoft tried this in their early C++ compilers: they piggybacked C++ exception handling on top of their OS's structured exceptions, and the result was a disaster.
Register an alternative signal stack with signalaltstack().
The 3rd argument to a signal handler handler registered with the SA_SIGINFO is a pointer to a ucontext_t which contains the saved register. The signal handler should adjust this to simulate a call to a function. That function can then throw the exception.
Potential complications include the need to preserve the value of callee saved registers, the red-zone on x86-64 (which can be disabled) and the return address register on some ISAs, such as ARM.

In C++, Is it possible to force the user to catch exceptions?

In short, is it possible to get C++ to force the invoker of a method to put a try...catch block?
(To clarify:
I don't necessarily mean the immediate invoker, I mean forcing the fact that it's caught somewhere. Also, I'm talking about forcing at compile time.)
The long:
I've read that it not recommended to use exception specification and that it doesn't work properly anyway (http://4thmouse.com/mystuff/articles/UsingExceptionsEffectively.html)
But the general consensus seems to favor the use of exceptions to return errors over the user of writing methods that return error codes.
So if I'm writing say a library, what's to stop the user from calling my method without putting any try...catch blocks, and then getting his program crashing when my code throws an exception?
(To be clear, I only require the exception to be caught somewhere in the users stack, not necessarily in the immediate calling code, and the compiler to complain if this is not the case.)
No, it is not.
Indeed, there is no mechanism to force the caller of a function (anywhere in the call stack) to handle any kind of error. At least, not via a compilation failure. Return values can be discarded. Even bundling error codes with return values (via expected<T, E>) doesn't issue a compile-time error if the user doesn't actually check to see if the value is available before fetching it.
C++17 may give us the [[nodiscard]] attribute, which allows compilers to issue a warning if a return value (presumably an error code) is discarded by the caller. But a compile-time warning will be as close as you can get.
In short, is it possible to get C++ to force the invoker of a method
to put a try...catch block?
No. This would defeat the whole purpose of exceptions. Exceptions are specifically made for the use case of propagating errors across multiple layers without the intermediate layers being aware of them.
Let's say you have a call hierarchy like A -> B -> C -> D -> E, and an error occurs in E. A can handle the error. B, C and D do not need to be aware of the error at all. This is exactly what exceptions are good for!
If you want to return an error directly to the caller because handling the error is indeed the caller's concern, then an exception is often the wrong design and a return value might be the better choice.
"Enforced" exceptions of a certain form have been tried in Java, but I'd consider it a failed experiment, as it usually results in code like this:
try {
method();
} catch (SomeCheckedException ex) {
// ignore
}
That C++ does not encourage this should be considered a feature.
I've read that it not recommended to use exception specification and
that it doesn't work properly anyway
Exactly. The only exception specification which was ever useful and which worked was throw() to signal that no exception at all is thrown, and that one has been superseded in C++11 by noexcept.
But the general consensus seems to favor the use of exceptions to
return errors over the user of writing methods that return error
codes.
See above. It depends on whether you want an error to propagate or if the caller can and should handle it.
So if I'm writing say a library, what's to stop the user from calling
my method without putting any try...catch blocks, and then getting his
program crashing when my code throws an exception?
A library which requires its user to surround all function calls with try blocks has a bad interface and should be redesigned, accordingly.
Also... you assume that a "program" will use your library. But this assumption will not always be true. The library client may itself be a library. There may be a lot of different library layers between the program and your library. You use exceptions if you do not care which layer handles them.
There's a general consensus? Not that I'm aware of. As for the exceptions, no. The compiler cannot enforce that somebody catches the exception somewhere up the call stack. At compile time, the compiler has no idea who may be calling your function, and your function may throw any arbitrary exception, as may any function that your function calls. The linker might have a chance, but it would have to maintain a lot of extra information dealing with what exceptions a function may throw, as well as what exceptions a function may catch. This gets even uglier when you start to talk about dynamically loaded libraries (DLL/.so) as that would have to get resolved at runtime.

lldb - breaking before C++ exception thrown

In lldb I'd like to break before C++ throws the exception, on when the actual signal is generated. I'd like to do this for any type of exception.
The following command will break on the C++ throw catcher
break set -E c++
I'd like to break on the cause of the exception and ignore the C++ throw/catch as if the application was crashing. I'd also like to do this for applications without source.
Is there any lldb voodoo I can use here?
I'm not entirely sure what you are asking.
Exceptions throws in C++ do two things, create the exception object, and then directly call some runtime routine (__cxa_throw on most Unixen) to implement the unwinding. The latter is the point where the exception breakpoint stops. There isn't any more preliminary than this that you could hook onto.
You could try breaking when the exception object is allocated. On OS X & Linux this is __cxa_allocate_exception, but I don't know if that will always get called or if there are alternate ways to make the exception... I don't see how you would gain much from that, however, it's just a couple of instructions later that you'll see the call to the throw method.
But maybe if you describe the problem you are actually trying to solve, we can answer more helpfully...

How are runtime errors handled in a C library compiled in C++?

Suppose I have a C library that I'm linking into a C++ program on Windows using Visual Studio. This C library is black box. If a fatal error occurs in this library (such as dereferencing a null), how will this runtime error be handled by the program/OS? I know in C++ that there are null reference exceptions, so you can probably handle such errors with a try/catch, but since this is a C library it won't issue a throw, right? So what will happen? The program will terminate, but through what means if not a C++ exception?
You can never "handle" dereferencing a null pointer. Once you do this, your program is no longer in a well-defined state, and there is no way to continue deterministically. The only course of action is to terminate(), which the OS will kindly do on your behalf if you have not registered a SIGSEGV handler.
The word "error" has several meanings which could possibly be confusing: On the one hand, a function that is unable to perform its expected task may be said to have encountered an "error", and it would be expected to signal this, either through a suitable return value, or by throwing an exception. This behaviour might better be called a failure. A correct program must be prepared to handle all possible ways in which a function may return. On the other hand, there are programming errors which simply lead to an wrong or even an ill-formed program. A correct program must never have any programming errors.
For example, malloc() may fail (if it cannot find enough space), which it signals by returning a null pointer, but your program would be in error if it dereferenced the result of malloc() without checking.
You can never "catch" or "handle" programming errors with further programming. Instead, a correct program must correctly anticipate and handle all failure conditions of component functions, and recursively a correctly written function must always return in a well-defined manner and signal failure appropriately.
Dereferencing a null pointer in native code will cause an "access violation" on Windows, or a "segmentation fault" on Unix/Linux. Different names for the same thing. It's the CPU that detects the error, and it invokes a handler in the operating system, which terminates the process.
Dereferencing a null reference in a VM-based language (e.g. .NET or Java) will throw an exception that you can catch. That's possible because the VM sits between the program and the CPU, and it can detect the null before trying to actually dereference it.
A C library is native code, so you'll get an access violation. You'd get the same from a true C++ program, which is also compiled to native code. But if you're using Managed C++ or C++/CLI, those are variants which compile to CIL and run on the .NET runtime, so you get a NullReferenceException in that case.
Support for 'asynchronous' or 'structured' exceptions (such as an invalid memory access) to be caught using the C++ catch keyword is an MSVC extension to the C++ language.
You can catch such exceptions even if they originate from a C function as long as you use the correct compiler option, /EHa: http://msdn.microsoft.com/en-us/library/1deeycx5%28v=VS.100%29.aspx
You could also choose to use Microsoft's 'structured exception' handling language extension (also available in C), which uses the __try and __except keywords: http://msdn.microsoft.com/en-us/library/swezty51.aspx

MS Visual Studio 2005 C++ exception handling

I have a C++ application built in MS Visual Studio 2005 that links to a 3rd party library. For a certain input, the application crashes in the 3rd party library (apparently somewhere in realloc.c; so has to be a memory issue of some kind). I ran in release because the input is huge. So I ran until it crashes and then choose to debug. While I separately debug the guilty function, I was hoping to use some exception handling to prevent the application from crashing and instead exit cleanly. So I used something like:
try {
//- call 3rd party application function that fails
}
catch(...) {
//- handle exception or whatever
Logger::Fatal("Fatal error: Exiting...");
return false;
}
But to my surprise the application still crashes! I was expecting to see it display the error message since I've presumably caught all exceptions with the ellipsis (...); what am I missing here? I even tried setting /EHca (was /EHsc) in Project Properties -> C/C++ -> Code Configuration -> Enable Exception Handling. On a related note about what might be causing the problem, is the following usage correct?
my_class* mc[] = {nil, nil, nil};
for (int i = 0; i < 3; ++i) {
mc[i] = new my_class();
//-Do stuff with mc[i]
if (mc[i] != nil) {
delete mc[i];
mc[i] = nil;
}
}
The failure to get the exception handling working is rather puzzling. I would certainly appreciate ideas/insights from the C++ gurus out there. BTW, the same problem also occurs on Linux (RHEL5) but I am currently trying to get the exception handling to work on Windows.
NOTE: When I let it debug after the crash. I do get an "Access violation..unable to read location" message. With this updated info, I was hoping something in C++ would still work on both Windows & Linux for such crashes.
Have you tried catching the crash by calling SetUnhandledExceptionFilter?
As Miguel suggested, a correct way to solve your problem is probably to use SetUnhandledExceptionFilter. But I'd like to explain your phenomena in details nevertheless.
First of all, not all the program "crashes" are related to exceptions. For instance, CRT may trigger program termination upon errors, such as invalid element access in a vector, or a pure virtual destructor call. If you want to cover those cases as well - see set_unexpected, set_terminate and etc.
Besides of this, catch block may only catch exceptions thrown from the appropriate code block. OTOH there may be functions that are called elsewhere, such as window procedures (if applicable), other threads and etc.
Now, regarding your problem. Let's first realize why things like catch(...) may catch things like access violation, and etc, and why this does not always happen (like in your case).
Windows provides its own exception handling mechanism - SEH, structured exception handling. It's far superior to C++ exception handling. In addition hardware interrupts (caused by CPU) are automatically "converted" into SEH exceptions, so that the code that uses SEH handles both software exceptions and hardware failures.
Microsoft C++ compilers actually implement C++ exceptions via SEH. That is throw is implemented via RaiseException with specifying C++ - specific exception code and parameters, catch is a C++ - specific wrapper for __except, and for every object with destructor the compiler generates something similar to __finally block. And this also works vice-versa. When a non-C++ exception is raised - the same code generated for C++ exceptions is executed.
In addition there are so-called compiler exception handling options that affect both the compiler exception handling code generation, and its behavior in runtime. They are called exception handling models:
synchronous. The compiler generates a code that is guaranteed to work correctly only if exceptions are raised explicitly. This includes throw statments, and all the "foreign" functions whose code is not visible to the compiler (in some variations - only C++ foreign functions). In particular reading from memory is considered "safe".
asynchronous. The compiler is not allowed to assume anything about where exceptions may arise. Hence it generates the code that should work correctly even if exception is arises from accessing a memory address.
In addition, CRT code that's invoked in catch (...) deliberately ignores non-C++ exceptions, unless asynchronous EH model is choosen.
So that if you want catch (...) to catch non-C++ exceptions - you must choose the asynchronous EH model.
Once I've written an article on the codeproject, after I had a related problem in driver development. It explains all this in details.