how to check if malloc holds the lock - c++

I am facing a problem in my code which is as follows:
1.A process was using malloc to allocate the memory.
2.While allocation process was interrupted and respective signal handler was
called.
3.in the signal handler again malloc was called, which leads to a hang.
Now after some googling i came to know that i am not supposed to allocate memory in signal handler.
Is there a way to handle this problem which does not require me to avoid using malloc in signal handler? for e.g. checking if a malloc is already in progress or holds lock.

Inside of signal handler you can only call async-signal-safe functions. malloc is not one of them. You may try preallocating memory to be used in signal handler in advance (before installing signal handler) though.

Related

Is there anyway I can prevent throw from calling malloc

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.

How do I handle out of stack space segmentation fault?

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...

Handling exception within thread function

I have multithreaded application using C++ (not C++11) using pthread. SO, I have couple of threads running in parallel with corresponding thread functions. In main thread block, I have try-catch block but within thread function, I don't. Each thread function (other than main) runs while(1) loop and breaks when a certain condition is set by main thread indicating to exit. The condition variable check and setting are all done within mutex guards to ensure mutual exclusion. However, within a thread function, some exception occurred and the thread became a zombie and the application crashed. pstack core could not show the stack trace properly, as that might have been corrupted. My question is: should I use try-catch block to handle exception with thread function too? Of course outside the try block should have while(1) block within and catch block should handle the exception gracefully and then probably gracefully end. Can I pass an exception from a child thread passed to the second thread? Ideally not. What should be the best practice?
should I use try-catch block to handle exception with thread function
too?
Yes, because exceptions are a stack-based mechanism. Since each thread has its own stack, it has its own exceptions.
If you have no language support for communicating exceptions, you will have to resort to 'manually' copying the exception obect in the catch and signaling to whatever thread needs to know about it with some inter-thread comms that are specific to your design.

Is there anyway to dynamically free thread-local storage in the Win32 APIs?

I need to make use of thread-local storage in a cross-platform project. Under *IX I am using pthreads and can avoid memory leaks thanks to the nice destructor function pointer passed as the second argument to pthread_key_create, but in Windows TlsAlloc has no such thing. Nor can I find a general place where any function is called on thread exit (otherwise I would homebrew some list of function pointers that get called at exit).
As it stands it seems that I have basically a situation where in order to actually use thread local storage I need to allocate my own space on the heap and pass a pointer to TlsSetValue, but if the thread exits ... I have no way of ensuring the memory was freed (other than someone explicitly calling TlsGetValue and delete/free/HeapFree/etc at the end of the thread function.
Does anyone know of a better way?
You can get yourself a nice "finalizer" to get rid of thread-specific resources, even if the thread is terminated: use RegisterWaitForSingleObject to wait on a copy (via DuplicateHandle) of the threads' handle - you have to use the cloned handle, cause registered waits can't handle handle {no pun intended} closing.
Use a heap allocated structure/record to hold the finalized resources, the handle waited for and the wait handle itself, cause the finalizer will run in the system threadpool, NOT the finalized thread (which will be already dead by the time). And don't forget to finalize the finalizer :)
The entry point of a DLL (DLLmain) is called on thread exit with a reason code of DLL_THREAD_DETACH. It is fairly straightforward to write a DLL that keeps track of functions to call on thread exit.
Alternatively, use Boost.Thread and the boost::this_thread::at_thread_exit function to register a function to be called on thread exit, or use boost::thread_specific_ptr to wrap the TLS usage entirely.

Vectored Exception Handling During StackOverflowException

If I've registered my very own vectored exception handler (VEH) and a StackOverflow exception had occurred in my process, when I'll reach to the VEH, will I'll be able to allocate more memory on the stack? will the allocation cause me to override some other memory? what will happen?
I know that in .Net this is why the entire stack is committed during the thread's creation, but let's say i'm writing in native and such scenario occurs ... what will i able to do inside the VEH? what about memory allocation..?
In the case of a stack overflow, you'll have a tiny bit of stack to work with. It's enough stack to start a new thread, which will have an entirely new stack. From there, you can do whatever you need to do before terminating.
You cannot recover from a stack overflow, it would involve unwinding the stack, but your entire program would be destroyed in the progress. Here's some code I wrote for a stack-dumping utility:
// stack overflows cannot be handled, try to get output then quit
set_current_thread(get_current_thread());
boost::thread t(stack_fail_thread);
t.join(); // will never exit
All this did was get the thread's handle so the stack dumping mechanism knew which thread to dump, start a new thread to do the dumping/logging, and wait for it to finish (which won't happen, the thread calls exit()).
For completeness, get_current_thread() looked like this:
const HANDLE process = GetCurrentProcess();
HANDLE thisThread = 0;
DuplicateHandle(process, GetCurrentThread(), process,
&thisThread, 0, true, DUPLICATE_SAME_ACCESS);
All of these are "simple" functions that don't require a lot of room to work (and keep in mind, the compiler will inline these msot likely, removing a function call). You cannot, contrarily, throw an exception. Not only does that require much more work, but destructors can do quite a bit of work (like deallocating memory), which tend to be complex as well.
Your best bet is to start a new thread, save as much information about your application as you can or want, then terminate.
No, you can't allocate memory in vectored exception handler.
MSDN says it explicitly:
"The handler should not call functions that acquire synchronization objects or allocate memory, because this can cause problems. Typically, the handler will simply access the exception record and return."
Stacks need to be contiguous, so you can't just allocate any random memory but have to allocate the next part of the address space.
If you are willing to preallocate the address space (i.e. just reserve a range of addresses without actually allocating memory), you can use VirtualAlloc. First you call it with the MEM_RESERVE flag to set aside the address space. Later, in your exception handler you can call it again with MEM_COMMIT to allocate physical memory to your pre-reserved address space.