SIgnal chaining, JVM_handle_(linux|bsd|aix)_signal, and backward compatibility

David Holmes david.holmes at oracle.com
Tue Nov 3 08:55:52 UTC 2020


On 3/11/2020 3:42 pm, Thomas Stüfe wrote:
> Hi David,
> 
> On Tue, Nov 3, 2020 at 4:27 AM David Holmes <david.holmes at oracle.com 
> <mailto:david.holmes at oracle.com>> wrote:
> 
>     Hi Thomas,
> 
>     On 2/11/2020 5:40 pm, Thomas Stüfe wrote:
>      > Hi,
>      >
>      > While working on some signal handler fixes and cleanups ([1]), I
>     noticed
>      > that we export JVM_handle_(linux|bsd)_signal() on all POSIX
>     platforms.
>      >
>      > I wondered why we do this. See also my first question at
>     runtime-dev [2] -
>      > the initial reaction was "probably no reason anymore".
>      >
>      > But then, I see a carefully crafted comment in [3]:
>      >
>      > <quote>
>      > // This routine may be used by user applications as a "hook" to catch
>      > signals.
>      > // The user-defined signal handler must pass unrecognized signals
>     to this
>      > // routine
>      > ...
>      > </quote>
>      >
>      > and I also found some bug reports [4], [5], from 2001 and 2004:
>      > JDK-4864136 : "JVM_handle_linux_signal is private in 1.4.2-beta"
>      > JDK-4408646 : "JVM_handle_solaris_signal must be a global function"
>      >
>      > So, to me this looks like JVM_handle_xxx_signals() was an
>     official, or at
>      > least deliberate, interface for foreign code to interact with our
>     signal
>      > handling. Specifically, this reads like a third party could
>     install its
>      > signal handlers over ours, and as long as it queried our signal
>     handler
>      > first by calling JVM_handle_xxx_signal(), we still could coexist
>     with it.
> 
>     Did you see this comment:
> 
>     https://bugs.openjdk.java.net/browse/JDK-4361067?focusedCommentId=12425956&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12425956
> 
>     This is tied to AllowUserSignalHandlers so we'd have to go through the
>     deprecation process to make any changes in this area.
> 
> 
> Excellent point. Thanks for digging that up. Would love to know who 
> wrote this code + comment.
> 
> (Note that I believe this comment uses the term "signal chaining" to 
> describe a general concept, not the solution implemented in hotspot 
> today via the UseSignalChaining + libjsig).

Right.


> Looked at this and a cursory glance through github sources shows that 
> this flag is used quite a lot, and I think it is useful too (I remember 
> Florian Weimers question about it here: 
> https://mail.openjdk.java.net/pipermail/discuss/2019-April/005046.html - 
> and this is exactly the answer, this would be the alternative).
> 
> But man, this raises so many questions. I see that 
> AllowUserSignalHandlers had been implemented by just refusing to install 
> the central hotspot signal handler. But it's not honored for the 
> installation of the SR handler, nor for anything which gets installed 
> via os::signal(). So we have bitrot right there already. Then, it never 
> can have worked on AIX since we have a day zero bug in our port. And so 
> on...

I wouldn't classify it like that. Hotspot commandeers very specific 
signals for internal purposes eg SEGV. If an application has its own 
custom SEGV handling then you need to coordinate between them. In 
contrast SR_signum is by default a user-defined signal and if that use 
conflicts with an app then it can redefine SR_signum. os::signal is for 
application defined signal handlers so again not specifically related to 
internal hotspot uses. There are a number of different aspects to signal 
handling. I think AllowUserSignalHandlers is fundamentally for things 
like SEGV handling.

>      > But now we have signal chaining [6], which achieves the same by
>     preloading
>      > the libjsig library. Which some consider to be ewww [7] :-), but
>     still
>      > seems to me like the official solution to that problem. Using signal
>      > chaining there would be no need to manually call
>     JVM_handle_xxx_signal()
>      > from outside since the interposed sigaction() in libjsig would
>     take care of
>      > all this stuff automatically.
> 
>     Aren't the two mechanisms complementary in that they work in opposite
>     ways? Signal chaining keeps the VM in control and allows it to call
>     application handlers.  AllowUserSignalHandlers keeps the app in control
>     and requires it to call VM handlers.
> 
> 
> I don't believe so. I do not have the means to check it, but would not 
> be surprised if signal chaining was actually the later invention.

Yes later but the two still operate in opposite ways.

> We have three mechanisms:
> A) AllowUserSignalHandlers, which just refuses to install signal 
> handlers (thereby effectively disabling UseSignalChaining), but user 
> handler needs to call our handler

Yes this puts the application in charge and they have to know what 
signals the VM wants to know about and call our handlers.

> B) UseSignalChaining, which handles the case where we come after the 
> user handler - we install our handlers, but remember the user handler 
> and later invoke it
> C) libjsig interposition, which handles the case where the user handler 
> gets installed over our handler - libjsig prevents this and we end up 
> with the same signal handler chain as in (B)
> 
> (B) and (C) (together termed "signal chaining" now) are a complete 
> replacement for (A). (A) is somewhat simpler, especially with the 
> interposition stuff, and gives the user handler more control, since it 
> can decide to handle signals before we get to see them. Whether or not 
> that's wise is another thing.
> 
> Very probably (A) should not be used together with (C) or (B).

(A) puts the host app in charge.

(B) and (C) should be used together to let the application handlers take 
a subserviant role to the hotspot handlers. The JVM is in charge.

If you had an existing application that performed signal management and 
then wanted to also embed a JVM you want to use (A), not have to rewrite 
your application so that (B)+(C) work. But in addition if you also allow 
native code that might have its own signal handling requirements then 
that part may require signal-chaining to work as well - so these 
mechanisms are not mutually exclusive.

> 
>      > My question is:
>      > - if JVM_handle_xxx_signal() is (had been?) an official
>     interface, should
>      > there not be some official documentation and regression tests?
>     Was there? I
>      > could not find anything.
>      > - if it is not an official interface, would it be okay to lay it
>     to rest?
>      >    - Pro: it is made obsolete by signal chaining, and removing it
>     would
>      > reduce complexity of signal handling somewhat
>      >    - Con: applications may exist out there which use that
>     interface, and I'd
>      > hate to break them. We give customers enough reasons to cling to
>     old JDK
>      > versions as it is.
>      >       Also, arguably, this interface is useful. Not everyone likes
>      > preloading libjsig, and the signal chaining mechanism is also a
>     whole lot
>      > more fragile.
>      >
>      > However, if we let it live on, should we not document and test it?
> 
>     It is not well documented that is for sure.
> 
>     Not sure about testing ... I tend to see this more a "best effort"
>     mechanism. If someone reports it stops working, or doesn't work, then
>     we'll make a best effort to fix it.
> 
> 
> If it is "best effort", can I just stub them out and let them return 0 
> always then?
> :-) Just kidding. This is the same argument as in "int random()  { 
> return 0; } is technically valid".
> 
> But seriously, tests would give me some measure of safety while working 
> with this code, as well as preventing bitrot or accidental removal. Just 
> look at the people queuing up to change or remove those handlers - see 
> e.g. https://github.com/openjdk/jdk/pull/636.

8253742 is supposed to be about cleanup/consolidation not removal!

Yes tests would do what you say. But writing applications that exercise 
these different signal management aspects would be rather complicated 
and always potentially incomplete. How would you write such a test? A 
customer launcher that acts as a hosting app which sets 
-XX:-AllowUserSignalHandlers and then installs its own handler that 
calls the JVM handler would not exactly prove anything. To see if it was 
working correctly you'd need to run all the regular tests under this 
hosting application.

Cheers,
David
-----

> 
>      > I am really interested in the history of this. Was this just a
>     solution for
>      > a single customer?
> 
>     Not sure of specific details but it was for hosting the VM in native
>     applications that already did their own signal management.
> 
>     Cheers,
>     David
> 
> 
> Thanks for the infos!
> 
> ..Thomas
> 
>      >
>      > Thanks, Thomas
>      >
>      >
>      > [1] https://bugs.openjdk.java.net/browse/JDK-8255711
>      > [2]
>      >
>     https://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2020-October/043145.html
>      > [3]
>      >
>     https://github.com/openjdk/jdk/blob/64feeab70af61a52ffe4c64df87a33c16754de18/src/hotspot/os/posix/signals_posix.cpp#L411
>      > [4] https://bugs.openjdk.java.net/browse/JDK-4864136
>      > [5] https://bugs.openjdk.java.net/browse/JDK-4408646
>      > [6]
>      >
>     https://docs.oracle.com/javase/8/docs/technotes/guides/vm/signal-chaining.html
>      > [7]
>     https://mail.openjdk.java.net/pipermail/discuss/2019-April/005042.html
>      >
> 


More information about the jdk-dev mailing list