I'm trying to make a Python program that interfaces with a different crashy process (that's out of my hands). Unfortunately the program I'm interfacing with doesn't even crash reliably! So I want to make a quick C++ program that crashes on purpose but I don't actually know the best and shortest way to do that, does anyone know what to put between my:
int main() {
crashyCodeGoesHere();
}
to make my C++ program crash reliably
The abort() function is probably your best bet. It's part of the C standard library, and is defined as "causing abnormal program termination" (e.g, a fatal error or crash).
Try:
raise(SIGSEGV); // simulates a standard crash when access invalid memory
// ie anything that can go wrong with pointers.
Found in:
#include <signal.h>
Dividing by zero will crash the application:
int main()
{
return 1 / 0;
}
*((unsigned int*)0) = 0xDEAD;
Well, are we on stackoverflow, or not?
for (long long int i = 0; ++i; (&i)[i] = i);
(Not guaranteed to crash by any standards, but neither are any of the suggested answers including the accepted one since SIGABRT could have been caught anyway. In practice, this will crash everywhere.)
throw 42;
Just the answer... :)
assert(false); is pretty good too.
According to ISO/IEC 9899:1999 it is guaranteed to crash when NDEBUG is not defined:
If NDEBUG is defined [...] the assert macro is defined simply as
#define assert(ignore) ((void)0)
The assert macro is redefined according to the current state of NDEBUG each time that is included.
[...]
The assert macro puts diagnostic tests into programs; [...] if expression (which shall have a scalar type) is false [...]. It
then calls the abort function.
Since a crash is a symptom of invoking undefined behaviour, and since invoking undefined behaviour can lead to anything, including a crash, I don't think you want to really crash your program, but just have it drop into a debugger. The most portable way to do so is probably abort().
While raise(SIGABRT) has the same effect, it is certainly more to write. Both ways however can be intercepted by installing a signal handler for SIGABRT. So depending on your situation, you might want/need to raise another signal. SIGFPE, SIGILL, SIGINT, SIGTERM or SIGSEGV might be the way to go, but they all can be intercepted.
When you can be unportable, your choices might be even broader, like using SIGBUS on linux.
The answer is platform specific and depends on your goals. But here's the Mozilla Javascript crash function, which I think illustrates a lot of the challenges to making this work:
static JS_NEVER_INLINE void
CrashInJS()
{
/*
* We write 123 here so that the machine code for this function is
* unique. Otherwise the linker, trying to be smart, might use the
* same code for CrashInJS and for some other function. That
* messes up the signature in minidumps.
*/
#if defined(WIN32)
/*
* We used to call DebugBreak() on Windows, but amazingly, it causes
* the MSVS 2010 debugger not to be able to recover a call stack.
*/
*((int *) NULL) = 123;
exit(3);
#elif defined(__APPLE__)
/*
* On Mac OS X, Breakpad ignores signals. Only real Mach exceptions are
* trapped.
*/
*((int *) NULL) = 123; /* To continue from here in GDB: "return" then "continue". */
raise(SIGABRT); /* In case above statement gets nixed by the optimizer. */
#else
raise(SIGABRT); /* To continue from here in GDB: "signal 0". */
#endif
}
The only flash I had is abort() function:
It aborts the process with an abnormal program termination.It generates the SIGABRT signal, which by default causes the program to terminate returning an unsuccessful termination error code to the host environment.The program is terminated without executing destructors for objects of automatic or static storage duration, and without calling any atexit( which is called by exit() before the program terminates)function. It never returns to its caller.
I see there are many answers posted here that will fall into lucky cases to get the job done, but none of them are 100% deterministic to crash. Some will crash on one hardware and OS, the others would not.
However, there is a standard way as per official C++ standard to make it crash.
Quoting from C++ Standard ISO/IEC 14882 §15.1-7:
If the exception handling mechanism, after completing the
initialization of the exception object but before the activation of a
handler for the exception, calls a function that exits via an
exception, std::terminate is called (15.5.1).
struct C {
C() { }
C(const C&) {
if (std::uncaught_exceptions()) {
throw 0; // throw during copy to handler’s exception-declaration object (15.3)
}
}
};
int main() {
try {
throw C(); // calls std::terminate() if construction of the handler’s
// exception-declaration object is not elided (12.8)
} catch(C) { }
}
I have written a small code to demonstrate this and can be found and tried on Ideone here.
class MyClass{
public:
~MyClass() throw(int) { throw 0;}
};
int main() {
try {
MyClass myobj; // its destructor will cause an exception
// This is another exception along with exception due to destructor of myobj and will cause app to terminate
throw 1; // It could be some function call which can result in exception.
}
catch(...)
{
std::cout<<"Exception catched"<<endl;
}
return 0;
}
ISO/IEC 14882 §15.1/9 mentions throw without try block resulting in implicit call to abort:
If no exception is presently being handled, executing a
throw-expression with no operand calls std::terminate()
Others include :
throw from destructor: ISO/IEC 14882 §15.2/3
*( ( char* ) NULL ) = 0;
This will produce a segmentation fault.
This one is missing:
int main = 42;
This crashes on my Linux system, because string literals are stored in read only memory:
0[""]--;
By the way, g++ refuses to compile this. Compilers are getting smarter and smarter :)
What about stack overflow by a dead loop recursive method call?
#include <windows.h>
#include <stdio.h>
void main()
{
StackOverflow(0);
}
void StackOverflow(int depth)
{
char blockdata[10000];
printf("Overflow: %d\n", depth);
StackOverflow(depth+1);
}
See Original example on Microsoft KB
This is a more guaranteed version of abort presented in above answers.It takes care of the situation when sigabrt is blocked.You can infact use any signal instead of abort that has the default action of crashing the program.
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
sigset_t act;
sigemptyset(&act);
sigfillset(&act);
sigprocmask(SIG_UNBLOCK,&act,NULL);
abort();
}
This is the snippet provided by Google in Breakpad.
volatile int* a = reinterpret_cast<volatile int*>(NULL);
*a = 1;
int i = 1 / 0;
Your compiler will probably warn you about this, but it compiles just fine under GCC 4.4.3
This will probably cause a SIGFPE (floating-point exception), which perhaps is not as likely in a real application as SIGSEGV (memory segmentation violation) as the other answers cause, but it's still a crash. In my opinion, this is much more readable.
Another way, if we're going to cheat and use signal.h, is:
#include <signal.h>
int main() {
raise(SIGKILL);
}
This is guaranteed to kill the subprocess, to contrast with SIGSEGV.
int* p=0;
*p=0;
This should crash too. On Windows it crashes with AccessViolation and it should do the same on all OS-es I guess.
Although this question already has an accepted answer...
void main(){
throw 1;
}
Or... void main(){throw 1;}
int main(int argc, char *argv[])
{
char *buf=NULL;buf[0]=0;
return 0;
}
Writing to a read-only memory will cause segmentation fault unless your system don't support read-only memory blocks.
int main() {
(int&)main = 0;
}
I have tested it with MingGW 5.3.0 on Windows 7 and GCC on Linux Mint. I suppose that other compilers and systems will give a similar effect.
Or another way since we're on the band wagon.
A lovely piece of infinite recursion. Guaranteed to blow your stack.
int main(int argv, char* argc)
{
return main(argv, argc)
}
Prints out:
Segmentation fault (core dumped)
void main()
{
int *aNumber = (int*) malloc(sizeof(int));
int j = 10;
for(int i = 2; i <= j; ++i)
{
aNumber = (int*) realloc(aNumber, sizeof(int) * i);
j += 10;
}
}
Hope this crashes. Cheers.
int main()
{
int *p=3;
int s;
while(1) {
s=*p;
p++;
}
}
A stylish way of doing this is a pure virtual function call:
class Base;
void func(Base*);
class Base
{
public:
virtual void f() = 0;
Base()
{
func(this);
}
};
class Derived : Base
{
virtual void f()
{
}
};
void func(Base* p)
{
p->f();
}
int main()
{
Derived d;
}
Compiled with gcc, this prints:
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
You can use of assembly in your c++ code BUT INT 3 is only for x86 systems other systems may have other trap/breakpoint instructions.
int main()
{
__asm int 3;
return 0;
}
INT 3 causes an interrupt and calls an interrupt vector set up by the OS.
Use __builtin_trap() in GCC or clang, or __debugbreak() in MSVC. Not handling these breakpoints/traps will lead to an unhandled breakpoint exception/crash.
Other suggestions that use abort() or exit(): those may be handled by other threads, making it more difficult to see the stack of the thread that propagated the crash.
#include <thread>
void intentionalCrash()
{
auto noop = [](){return;};
// Thread t1 is in a joinable state.
// When program returns t1 will be out of scope.
// Destructing a joinable thread creates a crash.
std::thread t1(noop);
}
int main()
{
intentionalCrash();
return 0;
}
Simple buffer overflow code that will cause the program to crash
int main()
{
int n[0];
n[2] = 0;
}
Related
I need to stop the program flow in the middle, and I am currently using an exception for this. This flow is the legal flow and I want to know if I can do it without using an exception.
This is an example of my code, and I cannot change func_2 and func_1:
#include "stdio.h"
void func_3()
{
printf("i am func_3\n");
throw 20;
printf("i am not supposed to be here\n");
}
void func_2()
{
printf("i am func_2\n");
func_3();
printf("i am not supposed to be here\n");
}
void func_1()
{
printf("i am func_1\n");
func_2();
printf("i am not supposed to be here\n");
}
int main()
{
try
{
func_1();
}
catch (int e)
{
printf("i am supposed to be here\n");
}
catch (...)
{
printf("i am not supposed to be here\n");
}
}
I assume that you want to handle an exceptional case and are looking for an alternative to exceptions. I.e. I hope you don't want to continue with the program "normally" after handling your exceptional case, which is possible but not recommended to implement with exceptions.
Possible but not recommended alternatives to exceptions are:
When you want to stop your whole application, then you can use std::exit(0);. You can implement your "catch"-code in a function which you call instead of your "throw"-statement, and call std::exit(0); at the end of that function (or use another exit code to indicate an "unsuccessful" exit). Or you implement an exit handler and register it using std::atexit(&handle_exit);.
Alternative to std::exit(<something>); is abort(); which throws the POSIX signal "SIGABRT" to indicate abnormal termination (which is the default behavior if your program throws and doesn't catch an exception). Your "catch"-code would then go in a signal handler which you register using the POSIX functions. Note that this requires a POSIX system and is thus not as portable as other solutions.
Another (similar) option is to use the "terminate" mechanism: Call std::terminate(); when you would normally throw your exception. Put your "catch"-code in a "terminate handler" function with signature void(*)(), i.e. no parameters and no return value, let's call the function void handle_terminate(). Install a terminate handler using std::set_terminate(&handle_terminate);. I didn't try that one, however, and it sounds damn ugly.
You could implement an exception-like behavior using assembly instructions, but please do not try this at home, as the behavior of such code is highly implementation defined (if not undefined), and way too ugly to implement.
In short, you can't (well ... you could, by using jumps instead, but then you would have two problems to solve).
The exception solution is the one to use, but do not throw a number (a number - especially a magical number in this case doesn't tell you anything).
Instead, define a struct func_3_interrupted {}; minimalistic structure, whose type name tells you it is an "interruption" of func_3, and catch that instead; The structure should be empty (or close to empty) and it should probably not inherit from the std::exception hierarchy.
Return can be used to return to the caller and stop the function being executed
int GLOBAL_FLAG = 1;
function called_function(){
printf("Inside Function")
if(/*some condition*/)
{
GLOBAL_FLAG = 0;
return;
}
/*Normal function code*/
}
int main(){
{
called_function();
if(GLOBAL_FLAG == 1)/*continue program execution*/
printf("Function had been executed.Back to normal flow")
}
So once the return statement is encountered it goes back to the caller that is main here and continues executing rest of the statements in main function.
Can some please explain why this exception isn't caught.
try {
// This will cause an exception
char *p = 0;
char x = 0;
*p = x;
}
catch (...) {
int a = 0;
}
When I run the program it dies on the line *p = x. I would expect that the catch block would cause this exception to be ignored.
I'm using the Qt Creator (2.2) with Qt 4.7.2 compiling with Visual Studios 2008 on Windows 7 32 bit.
There is no C++ exception being thrown here. You are causing undefined behavior because *p = x derefences a pointer with a null pointer value.
An exception is only propogated when you, or code you call, executes a throw expression. Undefined behaviour is not usually catchable.
Structured exception handling __try and __catch will catch system faults, see:
http://msdn.microsoft.com/en-us/library/swezty51(v=vs.80).aspx
Dereferencing a NULL pointer is undefined behaviour. In general, this will trigger a processor trap, and an OS level error. This may then be mapped to a signal, such as SIGSEGV, or to an Access Violation error, or it may abort your program, or do anything else.
On Windows, it is mapped to a "structured exception", which is a different beast to a C++ exception. Depending on how you've got MSVC configured, you may be able to catch this with catch(...), but not always.
If you want that you need to write a pointer test:
template<typename T>
inline T* ptr_test(T* test)
{
if (test == NULL)
{ throw std::runtime_error("Null Exceception");
}
return test;
}
Then your code looks like this:
try
{
// This will cause an exception
char* p = 0;
char x = 0;
*ptr_test(p) = x; // This is what java does.
// Fortunately C++ assumes you are smart enough to use pointers correctly.
// Thus I do not need to pay for this test.
//
// But if you want to pay for the test please feel free.
}
catch (...)
{
int a = 0;
}
You need to use the /EHa compiler option to switch on the (Microsoft compiler specific) feature which will enable SEH (Structured Exception Handling) exceptions (which is what your null access triggers) to be catchable by catch(...).
Having said that, I wouldn't recommend using /EHa. Better to use the __try/__except extension or the SEH API directly and keep your handling of "structured" exceptions separate from handling of C++ exceptions. Why ? Because C++ exceptions are just another perfectly legitimate well defined control flow mechanism, but most things which trigger SEH exceptions are likely to indicate your software has entered the realm of undefined behaviour and really the only sensible thing to do is exit gracefully. Using /EHa leads to this vital difference becoming unnecessarily blurred.
It's not caught because its not an exception - nothing is throwing. You're accessing null/unallocated memory which causes a segmentation fault which is a signal from the operating system itself.
Signals can only be caught by signal handlers, exceptions will not help you with those.
Exceptions only really help in areas where something might call throw(), like a library throwing an exception when you cause a divide-by-zero with the parameters you provided it.
All you're doing right now is dereferencing a null pointer, it is not an exception.
If you want this code to catch something, you have to throw something first. Say, something like:
try {
// This will cause an exception
char *p = 0;
char x = 0;
if (p == 0) throw 1;
*p = x;
}
catch (...) {
int a = 0;
}
Obviously, the catch block in the above example will always be executed.
Is there a line of code that will terminate the program?
Something like python's sys.exit()?
While you can call exit() (and may need to do so if your application encounters some fatal error), the cleanest way to exit a program is to return from main():
int main()
{
// do whatever your program does
} // function returns and exits program
When you call exit(), objects with automatic storage duration (local variables) are not destroyed before the program terminates, so you don't get proper cleanup. Those objects might need to clean up any resources they own, persist any pending state changes, terminate any running threads, or perform other actions in order for the program to terminate cleanly.
#include <cstdlib>
...
exit( exit_code );
There are several ways to cause your program to terminate. Which one is appropriate depends on why you want your program to terminate. The vast majority of the time it should be by executing a return statement in your main function. As in the following.
int main()
{
f();
return 0;
}
As others have identified this allows all your stack variables to be properly destructed so as to clean up properly. This is very important.
If you have detected an error somewhere deep in your code and you need to exit out you should throw an exception to return to the main function. As in the following.
struct stop_now_t { };
void f()
{
// ...
if (some_condition())
throw stop_now_t();
// ...
}
int main()
{
try {
f();
} catch (stop_now_t& stop) {
return 1;
}
return 0;
}
This causes the stack to be unwound an all your stack variables to be destructed. Still very important. Note that it is appropriate to indicate failure with a non-zero return value.
If in the unlikely case that your program detects a condition that indicates it is no longer safe to execute any more statements then you should use std::abort(). This will bring your program to a sudden stop with no further processing. std::exit() is similar but may call atexit handlers which could be bad if your program is sufficiently borked.
Yes! exit(). It's in <cstdlib>.
Allowing the execution flow to leave main by returning a value or allowing execution to reach the end of the function is the way a program should terminate except under unrecoverable circumstances. Returning a value is optional in C++, but I typically prefer to return EXIT_SUCCESS found in cstdlib (a platform-specific value that indicates the program executed successfully).
#include <cstdlib>
int main(int argc, char *argv[]) {
...
return EXIT_SUCCESS;
}
If, however, your program reaches an unrecoverable state, it should throw an exception. It's important to realise the implications of doing so, however. There are no widely-accepted best practices for deciding what should or should not be an exception, but there are some general rules you need to be aware of.
For example, throwing an exception from a destructor is nearly always a terrible idea because the object being destroyed might have been destroyed because an exception had already been thrown. If a second exception is thrown, terminate is called and your program will halt without any further clean-up having been performed. You can use uncaught_exception to determine if it's safe, but it's generally better practice to never allow exceptions to leave a destructor.
While it's generally always possible for functions you call but didn't write to throw exceptions (for example, new will throw std::bad_alloc if it can't allocate enough memory), it's often difficult for beginner programmers to keep track of or even know about all of the special rules surrounding exceptions in C++. For this reason, I recommend only using them in situations where there's no sensible way for your program to continue execution.
#include <stdexcept>
#include <cstdlib>
#include <iostream>
int foo(int i) {
if (i != 5) {
throw std::runtime_error("foo: i is not 5!");
}
return i * 2;
}
int main(int argc, char *argv[]) {
try {
foo(3);
}
catch (const std::exception &e) {
std::cout << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
exit is a hold-over from C and may result in objects with automatic storage to not be cleaned up properly. abort and terminate effectively causes the program to commit suicide and definitely won't clean up resources.
Whatever you do, don't use exceptions, exit, or abort/terminate as a crutch to get around writing a properly structured program. Save them for exceptional situations.
if you are in the main you can do:
return 0;
or
exit(exit_code);
The exit code depends of the semantic of your code. 1 is error 0 e a normal exit.
In some other function of your program:
exit(exit_code)
will exit the program.
This SO post provides an answer as well as explanation why not to use exit(). Worth a read.
In short, you should return 0 in main(), as it will run all of the destructors and do object cleanup. Throwing would also work if you are exiting from an error.
In main(), there is also:
return 0;
#include <cstdlib>
...
/*wherever you want it to end, e.g. in an if-statement:*/
if (T == 0)
{
exit(0);
}
throw back to main which should return EXIT_FAILURE,
or std::terminate() if corrupted.
(from Martin York's comment)
else if(Decision >= 3)
{
exit(0);
}
exit(0); // at the end of main function before closing curly braces
simple enough..
exit ( 0 );
}//end of function
Make sure there is a space on both sides of the 0. Without spaces, the program will not stop.
Does C++ offer a way to 'show' something visual if an unhandled exception occurs?
What I want to do is to make something like assert(unhandled exception.msg()) if it actually happens (like in the following sample):
#include <stdexcept>
void foo() {
throw std::runtime_error("Message!");
}
int main() {
foo();
}
I expect this kind of code not to terminate immediately (because exception was unhandled), rather show custom assertion message (Message! actually).
Is that possible?
There's no way specified by the standard to actually display the message of the uncaught exception. However, on many platforms, it is possible anyway. On Windows, you can use SetUnhandledExceptionFilter and pull out the C++ exception information. With g++ (appropriate versions of anyway), the terminate handler can access the uncaught exception with code like:
void terminate_handler()
{
try { throw; }
catch(const std::exception& e) { log(e.what()); }
catch(...) {}
}
and indeed g++'s default terminate handler does something similar to this. You can set the terminate handler with set_terminate.
IN short, no there's no generic C++ way, but there are ways depending on your platform.
Microsoft Visual C++ allows you to hook unhandled C++ exceptions like this. This is standard STL behaviour.
You set a handler via a call to set_terminate. It's recommended that your handler do not very much work, and then terminate the program, but I don't see why you could not signal something via an assert - though you don't have access to the exception that caused the problem.
I think you would benefit from a catch-all statement as follows:
int main() {
try {
foo();
catch (...) {
// Do something with the unhandled exception.
}
}
If you are using Windows, a good library for handling unhandled exceptions and crashes is CrashRpt. If you want to do it manually you can also use the following I wrote in this answer.
If I'm reading your question correctly, you're asking if you can overload throw (changing its default behavior) so it does something user-defined. No, you can't.
Edit: since you're insistent :), here's a bad idea™:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
void monkey() {
throw std::exception("poop!");
}
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
std::cout << "poop was thrown!" << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
int main() {
SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
monkey();
return 1;
}
Again, this is a very bad idea, and it's obviously platform-dependent, but it works.
Yes, its possible. Here you go:
#include <iostream>
#include <exception>
void foo()
{
throw std::exception("Message!");
}
int main()
{
try
{
foo();
}
catch (std::exception& e)
{
std::cout << "Got exception: " << e.what() << std::endl;
}
return 0;
}
The c++ standard is the terminate handler - as other have said
If you are after better traceablility for throws then this is what we do
We have a macro Throw that logs the file name and line number and message and then throws. It takes a printf style varargs message.
Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);
I get a nice log message
Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99
If you're really interested in what happened to cause your program to fail, you might benefit from examining the process image in a post-mortem debugger. The precise technique varies a bit from OS to OS, but the basic train is to first enable core dumping, and compile your program with debug symbols on. Once the program crashes, the operating system will copy its memory to disk, and you can then examine the state of the program at the time it crashed.
I have a C++ application that calls SQLite's (SQLite is in C) sqlite3_exec() which in turn can call my callback function implemented in C++. SQLite is compiled into a static library.
If an exception escapes my callback will it propagate safely through the C code of SQLite to the C++ code calling sqlite3_exec()?
My guess is that this is compiler dependent. However, throwing an exception in the callback would be a very bad idea. Either it will flat-out not work, or the C code in the SQLite library will be unable to handle it. Consider if this is some code in SQLite:
{
char * p = malloc( 1000 );
...
call_the_callback(); // might throw an exception
...
free( p );
}
If the exception "works", the C code has no possible way of catching it, and p will never be freed. The same goes for any other resources the library may have allocated, of course.
There is already a protocol for the callback to abort the API call. From the docs:
If an sqlite3_exec() callback returns
non-zero, the sqlite3_exec() routine
returns SQLITE_ABORT without invoking
the callback again and without running
any subsequent SQL statements.
I'd strongly recommend you use this instead of an exception.
SQLite is expecting you to return a SQLITE_ABORT on error and a 0 return code for no error. So you ought to wrap all your C++ callback in a try catch. Then in the catch return a SQLite SQLITE_ABORT error code, otherwise a zero.
Problems will occur if you bypass returning through SQLite as it will not free up/complete whatever code it does after you return back from your callback. This will cause untold problems potentially some of which maybe very obscure.
That was a really interesting question and I tested it out myself out of curiosity. On my OS X w/ gcc 4.2.1 the answer was YES. It works perfectly. I think a real test would be using gcc for the C++ and some other (MSVC?, LLVM?) for the C part and see if it still works.
My code:
callb.h:
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*t_callb)();
void cfun(t_callb fn);
#ifdef __cplusplus
}
#endif
callb.c:
#include "callb.h"
void cfun(t_callb fn) {
fn();
}
main.cpp:
#include <iostream>
#include <string>
#include "callb.h"
void myfn() {
std::string s( "My Callb Except" );
throw s;
}
int main() {
try {
cfun(myfn);
}
catch(std::string s) {
std::cout << "Caught: " << s << std::endl;
}
return 0;
}
If your callback called from sqlite is from the same thread from which you called sqlite3_exec() a throw somewhere in the callstack should be caught by a higher level catch.
Testing this yourself should be straightforward, no?
[edit]
After digging a little more myself I found out that the C++ standard is somewhat vague on what the behavior a c++ function called from c should have when throwing an exception.
You should definitely use the error handling mechanism the API expects. Otherwise you'll mostly the API itself in an undefined state and any further calls could potentially fail/crash.
Not a single answer mentioning building your C library with -fexceptions? Throw in a -fno-omit-framepointer and you are good to go. This works even across a shared library (written in C), as long as you throw from your main program, and catch in your main program again.