Why can't malloc be used in signal handlers? What can "happen wrong"?
Why is malloc not async signal safe?
A signal handler can be called at any time, including during times when another call to malloc
is in progress. If this happens, one of two things will occur:
- Your process will deadlock inside the signal handler, because
malloc
will be unable to acquire the heap lock. - Your process will corrupt its heap, because
malloc
does acquire the lock (or doesn't think it needs it), then proceeds to render the heap inconsistent, leading to a later crash.
Interesting. But can you explain why this cannot happen during normal thread context switching? The heap is also shared among all threads in a process. Is malloc() not pre-emptable except during signal handler invocation? –
Wharfinger
This is old, but it's worth answering: When a signal arrives, it is handled INSIDE a thread within the process. The most simple case I can think of involves a thread catching a signal when it is calling malloc (lets say, after it acquires a lock). Then, the signal handler calls malloc. When it tries to acquire the lock, it sees that the lock is already held, so it waits on the lock. The part of the thread that would eventually release the lock will NEVER run, because it's waiting for the signal handler to finish. The signal handler will never finish because it's waiting for the lock –
Eclampsia
That's the deadlock problem. The corruption problem occurs when the lock held is re-entrant. In this case, the signal handler is able to get the lock (since it is held by the same thread), and proceeds to screw up the heap since it is executing a completely new malloc request while the existing one (on the same thread) is already in progress. This can't happen without signals, since other threads use the lock to coordinate. –
Localism
It's worthwhile to note that implementations are allowed to implement
malloc()
in signal-safe fashion, and doing so would expand the ability of programs to recover from various conditions that might trigger asynchronous signals. The statement that malloc()
isn't signal safe isn't intended to mean that no implementations should be specified as signal-safe, but rather to avoid requiring that even implementations whose customers wouldn't need malloc()
signal-safe, running on platforms where such safety would be expensive, would need to provide it in order to be conforming. –
Shavon © 2022 - 2024 — McMap. All rights reserved.