diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/stack/JavaStackWalker.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/stack/JavaStackWalker.java index 84ab46d13600..a8923223c386 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/stack/JavaStackWalker.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/stack/JavaStackWalker.java @@ -45,6 +45,7 @@ import com.oracle.svm.core.heap.RestrictHeapAccess; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.thread.VMOperation; +import com.oracle.svm.core.thread.VMThreads.SafepointBehavior; import com.oracle.svm.core.util.VMError; /** @@ -134,6 +135,11 @@ public static boolean initWalk(JavaStackWalk walk, IsolateThread thread) { assert thread.notEqual(CurrentIsolate.getCurrentThread()) : "Cannot walk the current stack with this method, it would miss all frames after the last frame anchor"; assert VMOperation.isInProgressAtSafepoint() : "Walking the stack of another thread is only safe when that thread is stopped at a safepoint"; + if (SafepointBehavior.isCrashedThread(thread)) { + /* Skip crashed threads because they may no longer have a stack. */ + return false; + } + JavaFrameAnchor anchor = JavaFrameAnchors.getFrameAnchor(thread); boolean result = anchor.isNonNull(); Pointer sp = WordFactory.nullPointer(); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java index 154ede835acb..49ed1d06b494 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java @@ -876,42 +876,7 @@ public UnsignedWord getSafepointId() { return safepointId; } - /** A sample method to execute in a VMOperation. */ public static class TestingBackdoor { - - public static int countingVMOperation() { - final Log trace = Log.log().string("[Safepoint.Master.TestingBackdoor.countingVMOperation:").newline(); - int atSafepoint = 0; - int ignoreSafepoints = 0; - int notAtSafepoint = 0; - - for (IsolateThread vmThread = VMThreads.firstThread(); vmThread.isNonNull(); vmThread = VMThreads.nextThread(vmThread)) { - int safepointBehavior = SafepointBehavior.getSafepointBehaviorVolatile(vmThread); - int status = StatusSupport.getStatusVolatile(vmThread); - if (safepointBehavior == SafepointBehavior.PREVENT_VM_FROM_REACHING_SAFEPOINT) { - notAtSafepoint++; - } else if (safepointBehavior == SafepointBehavior.THREAD_CRASHED) { - ignoreSafepoints += 1; - } else { - assert safepointBehavior == SafepointBehavior.ALLOW_SAFEPOINT; - // Check if the thread is at a safepoint or in native code. - switch (status) { - case StatusSupport.STATUS_IN_SAFEPOINT: - atSafepoint += 1; - break; - default: - notAtSafepoint += 1; - break; - } - } - } - trace.string(" atSafepoint: ").signed(atSafepoint) - .string(" ignoreSafepoints: ").signed(ignoreSafepoints) - .string(" notAtSafepoint: ").signed(notAtSafepoint); - trace.string("]").newline(); - return atSafepoint; - } - @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static int getCurrentThreadSafepointRequestedCount() { return getSafepointRequested(CurrentIsolate.getCurrentThread()); 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 dc9b724b2fc9..f7557013a637 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 @@ -888,13 +888,13 @@ public static class SafepointBehavior { * The thread won't freeze at a safepoint, and will actively prevent the VM from reaching a * safepoint (regardless of the thread status). */ - static final int PREVENT_VM_FROM_REACHING_SAFEPOINT = 1; + public static final int PREVENT_VM_FROM_REACHING_SAFEPOINT = 1; /** * The thread won't freeze at a safepoint and the safepoint handling will ignore the thread. * So, the VM will be able to reach a safepoint regardless of the status of this thread. */ - static final int THREAD_CRASHED = 2; + public static final int THREAD_CRASHED = 2; @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static boolean ignoresSafepoints() { @@ -945,6 +945,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) {