Earlier quoted context omitted.
OK there we go, then. A compiler that conforms to the ABI generates code which clears the flag, if necessary. Interrupts preserve the flag. Thus, the flag should not be surprisingly set on entry into memcpy. If so, there is a bug.
> A compiler that conforms to the ABI generates code which clears the flag, if necessary. I'm sorry, I do not follow. The conforming compiler expects that the functions are called with the clear flag. The non-conforming kernel on the other hand does not clear the flag before calling the signal handler which breaks it.
Why isn't memset() async-signal-safe?
91–98 of 98 posts
Re: Why isn't memset() async-signal-safe?
#92Earlier quoted context omitted.
For trapping memory accesses, either something like userfaultfd, or otherwise handling segfaults via a signalfd from another thread with its own independent stack. (I'd also eliminate limitations about using a signalfd only within the same process that would have received the signals.) Or, if you just need a "dirty page" bit, add a dedicated mechanism for that, which can use hardware features to run much faster witho…
>signalfd from another thread with its own independent stack. This has similar reentrancy issues to signals.
Re: Why isn't memset() async-signal-safe?
#93Earlier quoted context omitted.
>signalfd from another thread with its own independent stack. This has similar reentrancy issues to signals.
How so? The other thread would handle the signal from a well-defined point (reading the signalfd), and the thread that faulted would stop at the point of the fault until the thread processing the signal let it continue.
edit: technically of course full reentrancy (implied by async signal safety) is not strictly required, "only" a fully non-blocking implementation of every function called by the signalfd thread.
Re: Why isn't memset() async-signal-safe?
#94It isn't POSIX, but Linux does have the very useful signalfd, which creates a file descriptor that accepts signals. This is a good solution for some types of programs.
But as pointed in this old HN story it is useless in this case. https://news.ycombinator.com/item?id=9564975
Really all signalfd does is provide an easy way to handle signals in an epoll driven application. If you have a different kind of main loop, then you are probably back to stuffing messages into queues, or dealing with all of the async-safe BS.
Re: Why isn't memset() async-signal-safe?
#95Earlier quoted context omitted.
How so? The other thread would handle the signal from a well-defined point (reading the signalfd), and the thread that faulted would stop at the point of the fault until the thread processing the signal let it continue.
What if the stopped thread was holding a mutex? The thread handling the signalfd can only safely call async signal safe functions, exactly like a signal handler. edit: technically of course full reentrancy (implied by async signal safety) is not strictly required, "only" a fully non-blocking implementation of every function called by the signalfd thread.
Re: Why isn't memset() async-signal-safe?
#96Earlier quoted context omitted.
What if the stopped thread was holding a mutex? The thread handling the signalfd can only safely call async signal safe functions, exactly like a signal handler. edit: technically of course full reentrancy (implied by async signal safety) is not strictly required, "only" a fully non-blocking implementation of every function called by the signalfd thread.
Ah, I see your concern. Right, if you called a function that took locks and then faulted, the thread handling the fault can't attempt to take the same locks. That should result in far fewer restrictions than "async-signal-safe", though.
Async signal safety implies both reentrancy and non blocking algorithms [1]. You might not need reentrancy but you do need non-blocking. That's really a significant restriction as libraries with non-blocking guarantees are rare.
Re: Why isn't memset() async-signal-safe?
#97Earlier quoted context omitted.
Ah, I see your concern. Right, if you called a function that took locks and then faulted, the thread handling the fault can't attempt to take the same locks. That should result in far fewer restrictions than "async-signal-safe", though.
You do not know which lock it was holding though; when handling a segfault for example you need to be pessimistic and assume that you can't touch any lock (think of the allocator lock for example). Async signal safety implies both reentrancy and non blocking algorithms [1]. You might not need reentrancy but you do need non-blocking. That's really a significant restriction as libraries with non-blocking guarantees are…
Re: Why isn't memset() async-signal-safe?
#98Earlier quoted context omitted.
You do not know which lock it was holding though; when handling a segfault for example you need to be pessimistic and assume that you can't touch any lock (think of the allocator lock for example). Async signal safety implies both reentrancy and non blocking algorithms [1]. You might not need reentrancy but you do need non-blocking. That's really a significant restriction as libraries with non-blocking guarantees are…
Depending on the nature of your segfault handler, you could either make sure you have any data structures you need already allocated, or allocate out of a separate arena. Or, alternatively, handle the signal in another process entirely.
Out of process handling is a robust solution though.