From 885d0f0ce306aec229d924d31a4d20dd90ce67e6 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Fri, 8 Jul 2022 13:08:20 +0200 Subject: [PATCH] Ignore crashed threads. --- .../src/com/oracle/svm/core/genscavenge/GCImpl.java | 4 ++++ .../oracle/svm/core/genscavenge/StackVerifier.java | 4 ++++ .../svm/core/genscavenge/ThreadLocalAllocation.java | 4 ++++ .../svm/core/DumpThreadStacksOnSignalFeature.java | 4 ++++ .../src/com/oracle/svm/core/SubstrateDiagnostics.java | 4 ++++ .../com/oracle/svm/core/code/RuntimeCodeCache.java | 4 ++++ .../src/com/oracle/svm/core/deopt/Deoptimizer.java | 4 ++++ .../com/oracle/svm/core/thread/PlatformThreads.java | 5 +++++ .../src/com/oracle/svm/core/thread/VMThreads.java | 11 +++++++---- 9 files changed, 40 insertions(+), 4 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index 26d08386c654..350e3b235794 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -865,6 +865,10 @@ private void blackenStackRoots() { */ continue; } + if (VMThreads.SafepointBehavior.isCrashedThread(vmThread)) { + /* The Java frame anchors or the values on the stack may be corrupt. */ + continue; + } if (JavaStackWalker.initWalk(walk, vmThread)) { walkStack(walk); } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/StackVerifier.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/StackVerifier.java index abc53e03442b..8fe02cd8ddd3 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/StackVerifier.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/StackVerifier.java @@ -61,6 +61,10 @@ public static boolean verifyAllThreads() { if (vmThread == CurrentIsolate.getCurrentThread()) { continue; } + if (VMThreads.SafepointBehavior.isCrashedThread(vmThread)) { + /* The Java frame anchors or the values on the stack may be corrupt. */ + continue; + } JavaStackWalker.walkThread(vmThread, STACK_FRAME_VISITOR); } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java index 3bfd58aa59e9..fb0eed65ea5b 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java @@ -418,6 +418,10 @@ static void disableAndFlushForAllThreads() { if (SubstrateOptions.MultiThreaded.getValue()) { for (IsolateThread vmThread = VMThreads.firstThread(); vmThread.isNonNull(); vmThread = VMThreads.nextThread(vmThread)) { + if (VMThreads.SafepointBehavior.isCrashedThread(vmThread)) { + /* Ignore crashed threads because the TLAB can be corrupt. */ + continue; + } disableAndFlushForThread(vmThread); } } else { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java index c687f82162d1..87d10e9b3f83 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java @@ -92,6 +92,10 @@ protected void operate() { /* Skip the signal handler stack */ continue; } + if (VMThreads.SafepointBehavior.isCrashedThread(vmThread)) { + /* The Java frame anchors or the values on the stack may be corrupt. */ + continue; + } try { dumpStack(log, vmThread); } catch (Exception e) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java index 540b5912123d..b714d19a67cd 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java @@ -906,6 +906,10 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev if (vmThread == CurrentIsolate.getCurrentThread()) { continue; } + if (VMThreads.SafepointBehavior.isCrashedThread(vmThread)) { + /* The Java frame anchors or the values on the stack may be corrupt. */ + continue; + } if (printed >= MAX_THREADS_TO_PRINT) { log.string("... (truncated)").newline(); break; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeCache.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeCache.java index 761b404a6c7d..f154a2da54e9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeCache.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeCache.java @@ -302,6 +302,10 @@ public boolean verify(CodeInfo info) { if (vmThread == CurrentIsolate.getCurrentThread()) { continue; } + if (VMThreads.SafepointBehavior.isCrashedThread(vmThread)) { + /* The Java frame anchors or the values on the stack may be corrupt. */ + continue; + } JavaStackWalker.walkThread(vmThread, this); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java index 60ba0bf0ae5d..ada3171c5ae8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java @@ -319,6 +319,10 @@ private static void deoptimizeInRangeOperation(CodePointer fromIp, CodePointer t if (vmThread == CurrentIsolate.getCurrentThread()) { continue; } + if (VMThreads.SafepointBehavior.isCrashedThread(vmThread)) { + /* The Java frame anchors or the values on the stack may be corrupt. */ + continue; + } StackFrameVisitor deoptVisitor = getStackFrameVisitor((Pointer) fromIp, (Pointer) toIp, deoptAll, vmThread); JavaStackWalker.walkThread(vmThread, deoptVisitor); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java index 359c03d0aa29..f753f7e99a66 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java @@ -1069,6 +1069,11 @@ private static class GetAllThreadsOperation extends JavaVMOperation { @Override protected void operate() { for (IsolateThread cur = VMThreads.firstThread(); cur.isNonNull(); cur = VMThreads.nextThread(cur)) { + if (VMThreads.SafepointBehavior.isCrashedThread(cur)) { + /* The Java frame anchors or the values on the stack may be corrupt. */ + continue; + } + Thread thread = PlatformThreads.fromVMThread(cur); if (thread != null) { result.add(thread); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMThreads.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMThreads.java index dc33f44de177..fcd75badc5d4 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMThreads.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMThreads.java @@ -869,13 +869,11 @@ public static int getSafepointBehaviorVolatile(IsolateThread vmThread) { * thread status). * * NOTE: Be careful with this method and make sure that this thread does not allocate any - * Java objects as this could result deadlocks. This method will only work prevent - * safepoints reliably if it is called from a thread with - * {@link StatusSupport#STATUS_IN_JAVA}. + * Java objects as this could result deadlocks. This method will only prevent safepoints + * reliably if it is called from a thread with {@link StatusSupport#STATUS_IN_JAVA}. */ @Uninterruptible(reason = "Called from uninterruptible code.", callerMustBe = true) public static void preventSafepoints() { - // It would be nice if we could retire the TLAB here but that wouldn't work reliably. safepointBehaviorTL.setVolatile(PREVENT_VM_FROM_REACHING_SAFEPOINT); } @@ -898,6 +896,11 @@ public static void markThreadAsCrashed() { safepointBehaviorTL.setVolatile(THREAD_CRASHED); } + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) + public static boolean isCrashedThread(IsolateThread thread) { + return safepointBehaviorTL.getVolatile(thread) == THREAD_CRASHED; + } + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static String toString(int safepointBehavior) { switch (safepointBehavior) {