RFR: 8286182: C2: crash with SIGFPE when executing compiled code

Martin Doerr mdoerr at openjdk.java.net
Tue May 17 14:32:03 UTC 2022


On Mon, 16 May 2022 12:36:43 GMT, Martin Doerr <mdoerr at openjdk.org> wrote:

> The bug is not assigned to me, but I have seen that the C2 code which checks for div by 0 is not aware of the new nodes from [JDK-8284742](https://bugs.openjdk.java.net/browse/JDK-8284742).
> This fixes the VM to pass the reproducer. I'm not sure if more opcode checks are required to get added.

Right, I had forgotten that x86 also raises SIGFPE in case of overflow.

Catching SIGFPE is possible. I had experimented with

--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
@@ -278,6 +278,15 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
                                               pc,
                                               SharedRuntime::
                                               IMPLICIT_DIVIDE_BY_ZERO);
+        if (stub == nullptr) {
+          int op = pc[0];
+          // TODO: make sure to handle all variants used by C2!
+          if (op == 0xF7) {
+            // ignore SIGPFE by speculative div
+            uc->uc_mcontext.gregs[REG_PC] += 4;
+            return true;
+          }
+        }
 #else
       if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) {
         // HACK: si_code does not work on linux 2.2.12-20!!!
diff --git a/src/hotspot/share/code/compiledMethod.cpp b/src/hotspot/share/code/compiledMethod.cpp
index 83c33408ea3..1c5e197511d 100644
--- a/src/hotspot/share/code/compiledMethod.cpp
+++ b/src/hotspot/share/code/compiledMethod.cpp
@@ -746,7 +746,7 @@ address CompiledMethod::continuation_for_implicit_exception(address pc, bool for
   int exception_offset = pc - code_begin();
   int cont_offset = ImplicitExceptionTable(this).continuation_offset( exception_offset );
 #ifdef ASSERT
-  if (cont_offset == 0) {
+  if (cont_offset == 0 && !for_div0_check) {
     Thread* thread = Thread::current();
     ResourceMark rm(thread);
     CodeBlob* cb = CodeCache::find_blob(pc);

This works and behaves like PPC64. However, we need to make sure it doesn't show up on any hot path. Otherwise, performance will be terrible.

Feel free to create a new PR if you want to propose a solution. I only opened this one to show my findings and can close it again if we decide for something else.

-------------

PR: https://git.openjdk.java.net/jdk/pull/8726


More information about the hotspot-compiler-dev mailing list