Skip to content

Commit

Permalink
Fix Thread.getStackTrace() right after Thread.start().
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-hofer committed Oct 17, 2023
1 parent 14ca57e commit 6ed33b8
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
import com.oracle.svm.core.thread.JavaVMOperation;
import com.oracle.svm.core.thread.LoomSupport;
import com.oracle.svm.core.thread.PlatformThreads;
import com.oracle.svm.core.thread.Target_java_lang_Thread;
import com.oracle.svm.core.thread.Target_jdk_internal_vm_Continuation;
import com.oracle.svm.core.thread.VMOperation;
import com.oracle.svm.core.thread.VirtualThreads;
Expand Down Expand Up @@ -113,6 +112,9 @@ public static StackTraceElement[] getStackTraceAtSafepoint(Thread thread) {

public static StackTraceElement[] getThreadStackTraceAtSafepoint(IsolateThread isolateThread, Pointer endSP) {
assert VMOperation.isInProgressAtSafepoint();
if (isolateThread.isNull()) { // recently launched thread
return NO_ELEMENTS;
}
BuildStackTraceVisitor visitor = new BuildStackTraceVisitor(false, SubstrateOptions.maxJavaStackTraceDepth());
JavaStackWalker.walkThread(isolateThread, endSP, visitor, null);
return visitor.trace.toArray(NO_ELEMENTS);
Expand Down Expand Up @@ -232,6 +234,10 @@ public static ClassLoader latestUserDefinedClassLoader(Pointer startSP) {
}

public static StackTraceElement[] asyncGetStackTrace(Thread thread) {
if (!thread.isAlive()) {
/* Avoid triggering a safepoint operation below if the thread is not even alive. */
return NO_ELEMENTS;
}
GetStackTraceOperation vmOp = new GetStackTraceOperation(thread);
vmOp.enqueue();
return vmOp.result;
Expand All @@ -248,11 +254,7 @@ private static class GetStackTraceOperation extends JavaVMOperation {

@Override
protected void operate() {
if (thread.isAlive()) {
result = getStackTraceAtSafepoint(thread);
} else {
result = Target_java_lang_Thread.EMPTY_STACK_TRACE;
}
result = getStackTraceAtSafepoint(thread);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ public static boolean walkThread(IsolateThread thread, ParameterizedStackFrameVi

@Uninterruptible(reason = "Prevent deoptimization of stack frames while in this method.")
public static boolean walkThread(IsolateThread thread, Pointer endSP, ParameterizedStackFrameVisitor visitor, Object data) {
assert thread.isNonNull();
JavaStackWalk walk = StackValue.get(JavaStackWalk.class);
if (initWalk(walk, thread)) {
walk.setEndSP(endSP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,12 @@ public static IsolateThread getIsolateThreadUnsafe(Thread t) {
* Returns the isolate thread associated with a Java thread. The caller must own the
* {@linkplain VMThreads#THREAD_MUTEX threads mutex} and release it only after it has finished
* using the returned {@link IsolateThread} pointer.
*
* This method can return {@code NULL} if the thread is not alive or if it has been recently
* started but has not completed initialization yet.
*/
public static IsolateThread getIsolateThread(Thread t) {
VMThreads.guaranteeOwnsThreadMutex("Threads mutex must be locked before accessing/iterating the thread list.");
VMError.guarantee(t.isAlive(), "Only running java.lang.Thread objects have a IsolateThread");
return getIsolateThreadUnsafe(t);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
public final class Target_java_lang_Thread {

// Checkstyle: stop
@Alias //
public static StackTraceElement[] EMPTY_STACK_TRACE;
@Delete //
static StackTraceElement[] EMPTY_STACK_TRACE;

@Alias //
static int NO_INHERIT_THREAD_LOCALS;
Expand Down

0 comments on commit 6ed33b8

Please sign in to comment.