Exception not caught after signal - c++

I try to catch a termination signal to my code to write a restart file before exiting. My solution is based on this answer.
#include <exception>
#include <csignal>
#include <iostream>
class InterruptException : public std::exception
{
public:
InterruptException(int _s) : signal_(_s) { }
int signal() const noexcept
{
return this->signal_;
}
private:
int signal_;
};
/// method to throw exception at signal interrupt
void sig_to_exception(int s)
{
throw InterruptException(s);
}
int main()
{
// activate signal handling
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = sig_to_exception;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
try
{
for (std::size_t i = 0; i < 100000000; ++i)
{
std::cout << i << std::endl;
}
}
catch (const InterruptException& e)
{
std::cout << "Received signal " << e.signal() << std::endl;
std::exit(1);
}
catch(...)
{
std::cout << "Other catch!" << std::endl;
}
}
The exception gets thrown fine, however, my catch block does not catch it. The program terminates with an uncaught exception InterruptException. I tried with clang and gcc on MacOS. Any idea why the exception is not caught correctly?
Thanks
Output when compiled with g++ 7.3.0:
terminate called after throwing an instance of 'InterruptException'
what(): std::exception
Abort trap: 6
Output when compiled with Apple LLVM 9.0.0
libc++abi.dylib: terminating with uncaught exception of type InterruptException: std::exception
PS: It seems when I compile with Apple LLVM the exception gets caught sometimes, but not all the time, which makes this even weirder.

There is very little that you can reliably do in a signal handler. In particular, you cannot throw an exception. The code in the question (and the "answer" that it links to) relies, at best, on compiler/OS-specific behavior. For the limits on what you can do in a signal handler, see this.
Note that the link above refers to signal, which is standard C. sigaction is not standard C, it's POSIX, and the C++ language definition doesn't impose any requirements on a program that uses it.

On most system the stack frame used by the signal handler is not a standard function stack frame as defined by the compiler for function calls.
So throwing out of a sig handler is not supported.
Stack frame for signal handling in the Linux Kernel
From the discussion in the linked question, on a linux system they are not even using the same stack for the stack frame and returning requires jumping back to a system function to restore the original user stack.
Unless the OS is specifically designed to handle exceptions then this is not going to work.
The rule of thumb for signal handlers is to do as little as possible in a signal handler. Set a global flag that can be detected by your normal code then check that flag periodically in your normal code to see when the signal has happened.

Related

How to cause C++ throw to dump core if the exception would be handled by a particular catch block

Is there a way to cause a throw in C++ to dump core at the throw site if the thrown exception would be handled by a certain catch block? I would like something similar to what happens with g++ when an exception reaches the top level.
For example, I would like something like this:
try {
bar();
try {
foo();
} catch(...) {
# pragma dump_at_throw_site
}
} catch(...) {
std::cerr << "There was a problem" << std::endl;
}
This way, if any exception thrown from foo() or its callee's that reaches the call-site of foo() would cause a core dump at the throw site so one can see who threw the exception that made it to the to this level.
On the other hand, exceptions thrown by bar() would be handled normally.
Yes,it can in Windows. I don't know Linux, suppose it can also.
We can register a Exception Handler function to response the throw before the catch
Here is the code example:
#include <iostream>
#include "windows.h"
#define CALL_FIRST 1
LONG WINAPI
VectoredHandler(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
std::cout <<"VectoredHandler"<<std::endl;
return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
PVOID handler;
handler = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler);
try {
throw 1;
}catch(...)
{
std::cout <<"catch (...)"<< std::endl;
}
RemoveVectoredExceptionHandler(handler);
std::cout << "end of main"<<std::endl;
return 0;
}
The outputs of code are:
VectoredHandler
catch (...)
end of main
So,you can dump core int the function VectoredHandler.
The VectoredHandler is called after the debugger gets a first chance notification, but before the system begins unwinding the stack.
And if your purpose is just to debug the problem issue, then you can rely on the debugger feature to handle the first chance exception, don't need dump the application.
For your information, you may need know What is a First Chance Exception? in windows to understand how windows dispatch the exception.

How to write signal handler for sigabrt signal?

I am trying to delete an already deleted object and I am getting a SIGABRT signal.
I know this signal aborts my program, but I want to catch this signal in a signal handler and display the message that I am deleting an already deleted object...
Here is the code I have tried, but it doesn't seem to work.
Please help me figure out what's wrong in it?
using namespace std;
class myclass
{
public:
myclass() { cout <<"myclass constructed\n"; }
~myclass() { cout <<"myclass destroyed\n"; }
};
void func(int);
int main (void)
{
signal(SIGABRT,func);
myclass * pt;
pt = new myclass[3];
delete[] pt;
delete[] pt;
return 0;
}
void func(int)
{
signal(SIGABRT,func);
cout << "trying to delete unallocated memory, exiting....\n";
exit(0);
}
The C standard says (section 7.14, paragraph 4 of both C99 and C11):
An implementation need not generate any of these signals, except as a result of explicit
calls to the raise function.
The C++ standard doesn't give any additional additional guarantees.
POSIX says:
The abort() function shall cause abnormal process termination to occur, unless the signal SIGABRT is being caught and the signal handler does not return.
The abnormal termination processing shall include the default actions defined for SIGABRT and may include an attempt to effect fclose() on all open streams.
The SIGABRT signal shall be sent to the calling process as if by means of raise() with the argument SIGABRT.
The status made available to wait() or waitpid() by abort() shall be that of a process terminated by the SIGABRT signal. The abort() function shall override blocking or ignoring the SIGABRT signal.
So, yeah, you have no basis for expecting to see a SIGABRT at all; you're lucky you aren't encountering nasal demons!

How can some code be run each time an exception is thrown in a Visual C++ program?

If an exception is thrown in a C++ program control is either transferred to the exception handler or terminate() is called.
Even if the program emits some diagnostics from inside the handler (or from terminate() handler) that can be too late - the most value is in the call stack at the point where the exception is thrown, not in the handler.
On Windows a call stack can be obtained using [StackWalk64()]1 function. The key is how to call that function at the right moment.
Is there a way to make a Visual C++ program execute some user code each time an exception (or an exception for which no handler is set) is thrown?
If you want to do stuff when an SEH exception is thrown, such as when an access violation occurs, then you can simply catch the SEH exception (either with a __finally, or with a conversion to a C++ exception (see here)) and access the context within the exception which is the context at the time the exception was thrown. You can then generate either a callstack using StackWalker or a mini dump. IMHO it's better to produce a mini dump.
If you want to catch C++ exceptions at the point they're thrown and you don't have access to the source to the C++ exception classes then you need to get a bit craftier. I deal with this problem by running the target process under a custom debugger - use the Debug API (see here) which gets notifications of when an exception is thrown. At that point you can create a mini dump or call stack of the target process.
On Windows I'm using SetUnhandledExceptionFilter and MiniDumpWriteDump to produce a minidump.
__try, __except are very helpful.
Is there a way to make a Visual C++ program execute some user code each time an exception (or an exception for which no handler is set) is thrown?
Put that code into the constructor of your exception base class.
When the language doesn't support it, and you can't live without it, hack... :-/
#include <iostream>
#include <stdexcept>
namespace Throw_From
{
struct Line
{
Line& set(int x) { x_ = x; return *this; }
int x_;
template <typename T>
void operator=(const T& t) const
{
throw t;
}
};
Line line;
}
#define throw Throw_From::line.set(__LINE__) =
void fn2()
{
throw std::runtime_error("abc");
}
void fn1()
{
fn2();
}
int main()
{
try
{
fn1();
}
catch (const std::runtime_error& x)
{
std::cout << Throw_From::line.x_ << '\n';
}
}
This is a great article on how to catch all different types of exceptions in Visual C++.
It also provides you with a crash dump that comes useful for debugging.

C++ unhandled exceptions

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.

Inject runtime exception to pthread sometime fails. How to fix that?

I try to inject the exception to thread using signals, but some times the exception is not get caught. For example the following code:
void _sigthrow(int sig)
{
throw runtime_error(strsignal(sig));
}
struct sigaction sigthrow = {{&_sigthrow}};
void* thread1(void*)
{
sigaction(SIGINT,&sigthrow,NULL);
try
{
while(1) usleep(1);
}
catch(exception &e)
{
cerr << "Thread1 catched " << e.what() << endl;
}
};
void* thread2(void*)
{
sigaction(SIGINT,&sigthrow,NULL);
try
{
while(1);
}
catch(exception &e)
{
cerr << "Thread2 catched " << e.what() << endl; //never goes here
}
};
If I try to execute like:
int main()
{
pthread_t p1,p2;
pthread_create( &p1, NULL, &thread1, NULL );
pthread_create( &p2, NULL, &thread2, NULL );
sleep(1);
pthread_kill( p1, SIGINT);
pthread_kill( p2, SIGINT);
sleep(1);
return EXIT_SUCCESS;
}
I get the following output:
Thread1 catched Interrupt
terminate called after throwing an instance of 'std::runtime_error'
what(): Interrupt
Aborted
How can I make second threat catch exception?
Is there better idea about injecting exceptions?
G++ assumes that exceptions can only be thrown from function calls. If you're going to violate this assumption (eg, by throwing them from signal handlers), you need to pass -fnon-call-exceptions to G++ when building your program.
Note, however that this causes G++ to:
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'.
This means that exceptioning out from the middle of some random code is NEVER safe. You can only except out of SIGSEGV, SIGBUS, and SIGFPE, and only if you pass -fnon-call-exceptions and they were triggered due to a fault in the running code. The only reason this worked on thread 1 is because, due to the existence of the usleep() call, G++ was forced to assume that it might throw. With thread 2, G++ can see that no trapping instruction was present, and eliminate the try-catch block.
You may find the pthread cancellation support more akin to what you need, or otherwise just add a test like this somewhere:
if (*(volatile int *)terminate_flag) throw terminate_exception();
In Boost.thread a thread can be interrupted by invoking the interrupt() member function of the corresponding boost::thread object. It uses pthread condition variables to communicate with the thread and allows you to define interruption points in the thread code. I would avoid use of pthread_kill in C++. The fact that boost thread doesn't use pthread_kill anywhere in their code confirms this I think.