4

Why sem_wait cannot be used inside a signal handler (particularly SIGSEGV signal which is per thread)? Can someone give me an example scenario where it will crash the application? I guess sem_wait is both reentrant and thread safe, so what is the problem here? Why is it not async safe?

MetallicPriest
  • 29,191
  • 52
  • 200
  • 356
  • I suggest you add which type of operations (threads, interrupts, exceptions,...) the semaphore should protect you from. This makes a big difference. – gnometorule Dec 13 '11 at 17:42
  • Related: https://stackoverflow.com/questions/14421951/guaranteeing-mutex-safety-with-async-signals/47304426 . I think `sem_wait(&x)` clashing with a `sem_wait(&x)` on the same `x` is obviously an issue, but it should be doable with a different semaphore, even though that's technically still undefined behavior. – Petr Skocik Nov 15 '17 at 10:26

3 Answers3

4

Async safe is a much stricter requirement than thread safe. You can write thread safe code using primitives to protect global data with critical sections. Signal handlers can't rely on this. For example, you could be inside a critical section within sem_wait, and simultaneously do something that causes a segfault. This would break the thread-safe protections of sem_wait.

TJD
  • 11,800
  • 1
  • 26
  • 34
2

sem_wait cannot be used in a signal handler for this reason:

Thread A is calls sem_wait on sem1. When thread A is done, it posts to sem1. However, before it can finish the signal is received and then handler is entered, calling sem_wait on sem1. Since A is the one that would post to sem1, the handler will never return and you will have deadlock. This is why it is a good rule to never wait on anything in a signal handler. The problem, ASFAIK, has more to do with deadlock than crashing.

Also, this violates the ideal purpose of a signal handler, which is to handle an external interrupt and then get back to what you were doing quickly.

Lastly, isn't it a better goal to rid yourself of the SIGSEGV instead of handling it?

dbeer
  • 6,963
  • 3
  • 31
  • 47
1

What if the application receives a signal while the value of the semaphore is zero, and the thread that receives the signal happens to be the one which is supposed to increment the semaphore value (sem_post)? If you then call sem_wait in the signal handler, the process will deadlock, no?

Another argument could of course be that if sem_wait is not on the list of async-signal-safe functions, the implementation is free to invoke nasal demons.

janneb
  • 36,249
  • 2
  • 81
  • 97