Reading shared data inside a signal handler

I am in a situation where I need to read the binary search tree (BST) inside the signal handler (the signal handler is SIGSEGV , which, according to my knowledge, refers to the stream base). BST can be modified by other threads in the application.

Now, since the signal handler cannot use semaphores, mutexes, etc., and therefore cannot access shared data, how to solve this problem? Please note that my application is multithreaded and runs on a multi-core system.

+8
c linux mutex signals signal-handling
source share
4 answers

You should not access general data from a signal handler. You can find more information about signals in the following articles:

Linux Signals for an Application Programmer

Linux Signal Processing Model

All About Linux Signals

It seems that the safest way to process signals in Linux is still a signal.

+4
source share

Assuming SH cannot access shared data directly, perhaps you can do it indirectly:

  • Have some global variable that only signal handlers can write, but can be read from other sources (even if they are only inside the same stream).
  • SH sets a flag when called
  • A survey on the topics of this flag when they are not in the middle of a BST change; when they find, they perform the processing that the original signal requires (using any necessary synchronization), and then pick up another signal (for example, SIGUSR1) to indicate that the processing is completed
  • SH signal for THAT resets the flag

If you are worried about SIGSEGV overlapping, add a counter to the mix for tracking. (Hey, you just built your own semaphore!)

The weak link here is obviously a survey, but its beginning.

+3
source share

I see two pretty clean solutions:

  • Linux-specific: create custom streaming processing signals. Catch signals using signalfd () . This way you will process the signals in a regular thread, and not in any limited handler.
  • Portable: also use a dedicated thread that is sleeping until a signal is received. You can use the channel to create a pair of file descriptors. The stream can read (2) from the first descriptor and in the signal handler, which you can write (2) to the second descriptor. Using write () in a signal handler is legal according to POSIX . When a stream reads something from a pipe, it knows that it must perform some action.
+3
source share

You can consider mmap -in fuse (in user space).

In fact, you'll be happier at Gnu Hurd , which supports external pagers.

And perhaps your hack of reading the binary search tree in your signal handler can often work in practice, not portable and depending on the kernel version. Perhaps serialization of access with low-level non-portable tricks (e.g. futexes and atomic gcc built-in functions ). Reading the (specific) NPTL source code, i.e. current Linux pthread routines should help.

It could probably be pthread_mutex_lock , etc. can actually be used inside the Linux signal handler ... (because it probably only does futex and atomic instructions).

+1
source share

All Articles