Let's say I compiled using gcc --stack,4194304
Next in my program I do something like char what_is_wrong_with_me[8000000];
This will result in a segmentation fault, but the weird thing is I have a working segv_handler, where if I do something stupid like char *stupid=0; *stupid='x'; it will print an error message.
My question is, how do I handle the out of stack space segfault as well?
You can handle this but you've exhausted your primary stack. You need to set an alternate stack for your signal handler. You can do this with a sigaltstack syscall
When installing your segfault handler with sigaction, you'll also need the SA_ONSTACK option
So, your process exhausted its allocated stack space (intentionally, in your case, but it doesn't matter whether it's intentional or not). As soon as an attempt is made to write the next stack frame into the unallocated page occurs, a SIGSEGV signal gets sent to the process.
An attempt is then made to invoke your installed signal handler. Now, lets remember that SIGSEGV is just like any other signal. And, as you know, when a signal handler gets invoked upon receipt of a signal, when the signal handler returns the process continues to execute.
In other words, the signal handler gets invoked as if it were a function call, and when the function call returns, the original execution thread resumes running.
Of course, you know what needs to happen for a function call, right? A new call frame gets pushed on the stack, containing the return address, and a few other things. You know, so when the function call returns, the original execution thread resumes running where it left off (in case of a signal you also get an entire register dump in there, and the rest of the CPU state, but that's an irrelevant detail).
And now, perhaps, you can figure out, all by yourself, the answer to your own question, why your signal handler does not get invoked in this situation, when the stack space has been exhausted...
Related
This question already has an answer here:
Qt, How to pause QThread immediately
(1 answer)
Closed 5 years ago.
I would like to know how to properly stop a QThread. I havea infinite loop in a thread, and I would like to stop it when I do a specific action :
I have tried :
if (thread->isRunning()){
worker->stop();
thread->terminate();
}
the stop() method set a value to false to go out of my infinite loop.
Furthermore, I don't really understand the difference between quit(), terminate() or wait(). Can someone explain me ?
Thanks.
A proper answer depends on how you actually use QThread and how you've implemented stop().
An intended use case in Qt assumes following model:
You create an object that will do some useful work in response to Signals
You create a `QThread` and move your object to this thread
When you send a signal to your object, it's processed in `QThread` you've created
Now you need to understand some internals of how this is actually implemented. There are several "models" of signals in Qt and in some cases when you "send a signal" you effectively simply call a "slot" function. That's a "direct" slot connection and in this case slot() will be executed in caller thread, one that raised a signal. So in order to communicate with another thread, Qt allows another kind of signals, queued connections. Instead of calling a slot(), caller leaves a message to object that owns this slot. A thread associated with this object will read this message (at some time later) & perform execution of slot() itself.
Now you can understand what's happening when you create and execute QThread. A newly created thread will execute QThread::run() that, by default, will execute QThread::exec() which is nothing, but an infinite loop that looks for messages for objects associated with thread and transfers them to slots of these objects. Calling QThread::quit() posts a termination message to this queue. When QThread::exec() will read it, it will stop further processing of events, exit infinite loop and gently terminate the thread.
Now, as you may guess, in order to receive termination message, two conditions must be met:
You should be running `QThread::exec()`
You should exit from slot that is currently running
The first one is typically violated when people subclass from QThread and override QThread::run with their own code. In most cases this is a wrong usage, but it's still very widely taught and used. In your case it seems that you're violating the second requirement: your code runs infinite loop and therefore QThread::exec() simply doesn't get a control and don't have any chance to check that it needs to exit. Drop that infinite loop of yours to recycle bin, QThread::exec() is already running such loop for you. Think how to re-write your code so it does not running infinite loops, it's always possible. Think about your program in terms of "messages-to-thread" concept. If you're checking something periodically, create a QTimer that will send messages to your object and implement a check in your slot. If you processing some large amount of data, split this data to smaller chunks and write your object so it will process one chunk at a time in response to some message. E.g. if you are processing image line-by-line, make a slot processLine(int line) and send a sequence of signals "0, 1, 2... height-1" to that slot. Note that you will also have to explicitly call QThread::quit() once done processing because event loop is infinite, it doesn't "know" when you processed all the lines of your image. Also consider using QtConcurrent for computationally-intensive tasks instead of QThread.
Now, the QThread::terminate() does stop a thread in a very different manner. It simply asks OS to kill your thread. And OS will simply abruptly stop your thread at arbitrary position in the code. Thread stack memory will be free'd, but any memory this stack pointed to won't. If a thread was owning some resource (such as file or mutex), it won't ever release it. An operation that involve writing data to memory can be stopped in the middle and leave memory block (e.g. object) incompletely filled and in invalid state. As you might guess from this description, you should never, ever call ::terminate() except for very rare cases where keeping running of thread is worse than getting memory & resource leaks.
QThread::wait() is just a convenience function that waits until QThread ceases to execute. It will work both with exit() and terminate().
You can also implement a threading system of your own subclassed from QThread and implement your own thread termination procedure. All you need to exit a thread is, essentially, just to return from QThread::run() when it becomes necessary and you can't use neither exit() nor terminate() for that purpose. Create your own synchronization primitive and use it to signal your code to return. But in most cases it's not a good idea, keep in mind that (unless you work with QEventLoop by yourself), Qt signal and slots won't be working properly in that case.
Background
In my C++ program I have a SIGALRM handler in which I want to convert the signal into an exception by doing a throw (I understand that in general this is not good practice, but in the system I am working on it's probably the only option). My problem here is that SIGALRM handler could be invoked when we are doing a malloc, while throw will call __cxa_allocate_exception which does another malloc. The two malloc calls can hit a deadlock in glibc 2.12. I tried pre-allocating the exception, but the call to __cxa_allocate_exception still happened. I checked the source code of gcc and there doesn't seem to be any condition of putting the __cxa_allocate_exception call.
Additional Background
I install signal handler right before a try block and uninstall it after the catch. I'm throwing from the signal handler and this way I think it will be inside the try block (Let's not consider the case where the signal is received when we are in the catch logic) and can be caught correctly.
I think I'm hitting the malloc deadlock described here: https://sourceware.org/bugzilla/show_bug.cgi?id=13699 and here https://sourceware.org/ml/libc-alpha/2012-02/msg00272.html .
Question
My question is: is there anyway I can prevent throw from calling malloc? (Also, I understand that I can block the SIGALRM signal when I'm doing a malloc, but I'm afraid that there are too many places to block).
Thanks in advance. Any help/reference is high appreciated.
The general problem is that if your signal handler is called while in ANY async-unsafe library function (such as malloc or printf), jumping out of the signal handler (via longjmp or exception) will likely leave the glibc in an inconsistent state, which will crash or otherwise misbehave the next time you call anything.
So even if you were able to avoid the call to malloc in the exception setup, and throw the exception and catch and handle it, your program would stiil crash the next time it called malloc afterwards.
The only way to avoid this is to ensure that the signal handler cannot be called while in an async-unsafe library function. You can do that by using sigblock to block and unblock the signal around EVERY call to a signal-unsafe function ANYWHERE in your program:
oldmask = sigblock(SIGALRM);
...call to malloc or printf or whatever...
setsetmask(oldmask);
This is possible, but not terribly practical.
The manual states that malloc is "AS-Unsafe", which means it's not safe to call it inside asychronous signal handlers. If you do, your program has undefined behavior.
I'm presently moving back to C++ from Java. There are some areas of C++ where higher performance can be achieved by doing more computation on the stack.And some recursive algorithms operate more efficiently on the stack than on the heap.
Obviously the stack is a resource, and if I am going to use it, I should ensure that I do not consume too much (to the point of crashing my program).
I'm running Xcode, and wrote the following simple program:
#include <csignal>
static bool interrupted = false;
long stack_test(long limit){
if((limit>0)&&(interrupted==false))
return stack_test(limit-1)+1; // program crashes here with EXC_BAD_ACCESS...
else
return 0;
}
void signal_handler(int sig){
interrupted = true;
}
int main(char* args[]){
signal(SIGSEGV,&signal_handler);
stack_test(1000000);
signal(SIGSEGV,SIG_DFL);
}
The documentation states that running on BSD, stack limits can be checked by using getrlimit() and that when the stack limit is being reached, a SIGSEGV event is issued. I tried installing the above event handler for this event, but instead, my program stops at the next iteration with EXT_BAD_ACCESS (code=2, ...).
Am I taking the wrong approach here, or is there a better way?
This has the same problem in Java as it does in c++. You are way over-committing to the stack.
And some recursive algorithms operate more efficiently on the stack than on the heap.
Indeed, and they are commonly of the divide and conquer type.
The usefulness of recursion is to reduce the computation to a more manageable computation with each call. limit - 1 is not such a candidate.
If your question is only about the signal, I unfortunately can't offer you any advice on your system.
Your signal handler can't do much to fix the stack overflow. Setting your interrupted flag doesn't help. When your signal handler returns, the instruction that tried to write to an address beyond the end of the stack resumes and it's still going to attempt to write beyond the end of the stack. Your code won't get back to the part which checks your interrupted flag.
With great care and a lot of architecture-specific code, your signal handler could potentially change the context of the thread which encountered the signal such that, when it resumes, it will be at a different point in the code.
You could also use setjmp() and longjmp() to accomplish this at a coarser granularity.
A different approach would be to set up a thread to use a stack that your code allocated, using pthread_attr_setstackaddr() and pthread_attr_setstacksize() prior to pthread_create(). You would run your code in that secondary thread and not the main one. You could set the last page or two of the stack you allocated to be non-writable using mprotect(). Then, your signal handler could set the interrupted flag and also set those pages to be writable. That should give you enough headroom that the resumed code can execute without re-raising the signal, get far enough to check the flag, and return gracefully. Note that this is a one-time last resort, unless you can find a good point to set those guard pages non-writable again.
I am using mprotect to set some memory pages as write protected. When any writing is tried in that memory region, the program gets a SIGSEGV signal. From the signal handler I know in which memory address the write was tried, but I don't know the way how to find out which instruction causes write protection violation. So inside the signal handler I am thinking of reading the program counter(PC) register to get the faulty instruction. Is there a easy way to do this?
If you install your signal handler using sigaction with the SA_SIGINFO flag, the third argument to the signal handler has type void * but points to a structure of type ucontext_t, which in turn contains a structure of type mcontext_t. The contents of mcontext_t are implementation-defined and generally cpu-architecture-specific, but this is where you will find the saved program counter.
It's also possible that the compiler's builtins (__builtin_return_address with a nonzero argument, I think) along with unwinding tables may be able to trace across the signal handler. While this is in some ways more general (it's not visibly cpu-arch-specific), I think it's also more fragile, and whether it actually works may be cpu-arch- and ABI-specific.
So I realize that in fact I really do not need to do what I am about to explain but I am very picky about making sure my programs cleans up everything before exiting so I still want to do it...
I have a QApplication that I connect a single shot timer to the quit slot on. (in the future imagine this quit is really going to be generated from the UI on a user click so this is just for debugging) I have noticed that at first I was just allocating the qApp in the main function on the stack. The problem is in doing some research it seems the exec function does NOT HAVE to return. This means the main function stack does not get cleaned up. (Or well at least not until the program exits and the system reclaims that memory...) So in valgrind I have some QCoreApplication::init() memory "issues". Once again more just me being picky then really affecting things...
Anyways so I decided to malloc the QApplication and then try to free it just before the program closes. I can do this for signals but how about on the quit signal? I'm tied into the aboutToQuit signal but I feel like that's not the right stage to blow away the qApp. So my question is, IS there a right place to delete the qApp and if yes where?
The problem is in doing some research it seems the exec function does NOT HAVE to return.
Well, yeah, it doesn't "have" to return if your process is crashing and burning anyway, i.e. if you've called - directly or indirectly - std::terminate(), ::abort(), ::exit(), etc. Those library functions are used to quickly terminate the process and your problems aren't limited to the QApplication instance. Every object on the call stack, in every thread, will be leaked, and some of those objects you have neither access to nor any control of - the runtime and the libraries create them - and there's nothing you can do about it. The case of non-returning exec() is an exception, not the normal way your program should be ending. In terms of "what to do when exec() doesn't return: nothing. It's too late by then.
Hence - don't throw uncaught exceptions, don't ::exit() nor ::abort(), and don't worry about it. In every well-behaved Qt program, QCoreApplication::exec() returns.