Skip to content

Commit 4229c48

Browse files
committed
[GR-17457] Fix handling of KillException thrown on thread enter
PullRequest: truffleruby/3729
2 parents 39114ba + 5157a04 commit 4229c48

File tree

3 files changed

+15
-10
lines changed

3 files changed

+15
-10
lines changed

src/main/java/org/truffleruby/core/thread/RubyThread.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public final class RubyThread extends RubyDynamicObject implements ObjectGraphNo
6262
/** Either nil or long */
6363
public volatile Object nativeThreadId = Nil.INSTANCE;
6464
volatile RubyException exception = null;
65-
volatile Object value = null;
65+
volatile Object value = Nil.INSTANCE;
6666
public final AtomicBoolean wakeUp = new AtomicBoolean(false);
6767
volatile int priority = Thread.NORM_PRIORITY;
6868
ThreadLocalBuffer ioBuffer;

src/main/java/org/truffleruby/core/thread/ThreadManager.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@ private Thread createJavaThread(Runnable runnable, RubyThread rubyThread, String
212212
private static Thread.UncaughtExceptionHandler uncaughtExceptionHandler(RubyFiber fiber) {
213213
assert fiber != null;
214214
return (javaThread, throwable) -> {
215+
if (throwable instanceof KillException) {
216+
// The exception killed the thread, as expected, do not print anything.
217+
// We cannot just catch (KillException e) in threadMain() because it can also happen
218+
// on the poll() done just after the thread enters the context and
219+
// *before* running the Runnable, i.e. before running threadMain().
220+
return;
221+
}
222+
215223
printInternalError(throwable);
216224
try {
217225
fiber.uncaughtException = throwable;
@@ -307,28 +315,25 @@ public void initialize(RubyThread rubyThread, Node currentNode, String info, Str
307315
}
308316

309317
/** {@link RubyLanguage#initializeThread(RubyContext, Thread)} runs before this, and
310-
* {@link RubyLanguage#disposeThread(RubyContext, Thread)} runs after this. */
318+
* {@link RubyLanguage#disposeThread(RubyContext, Thread)} runs after this. Note this is NOT guaranteed to run, an
319+
* exception might happen in the poll() done when the thread enters the context. */
311320
private void threadMain(RubyThread thread, Node currentNode, Supplier<Object> task) {
312321
try {
313322
final Object result = task.get();
314323
setThreadValue(thread, result);
315324
// Handlers in the same order as in FiberManager
316-
// Each catch must either setThreadValue() (before rethrowing) or setException()
317-
} catch (KillException e) {
318-
setThreadValue(thread, Nil.INSTANCE);
319-
} catch (ThreadDeath e) { // Context#close(true)
320-
setThreadValue(thread, Nil.INSTANCE);
325+
} catch (KillException e) { // handled in uncaughtExceptionHandler()
326+
throw e;
327+
} catch (ThreadDeath e) { // Context#close(true), handled by Truffle
321328
throw e;
322329
} catch (RaiseException e) {
323330
setException(thread, e.getException(), currentNode);
324331
} catch (DynamicReturnException e) {
325332
setException(thread, context.getCoreExceptions().unexpectedReturn(currentNode), currentNode);
326333
} catch (ExitException e) {
327-
setThreadValue(thread, Nil.INSTANCE);
328334
rethrowOnMainThread(currentNode, e);
329335
} catch (Throwable e) {
330336
final RuntimeException runtimeException = printInternalError(e);
331-
setThreadValue(thread, Nil.INSTANCE);
332337
rethrowOnMainThread(currentNode, runtimeException);
333338
} finally {
334339
assert thread.value != null || thread.exception != null;

src/main/java/org/truffleruby/language/control/KillException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public final class KillException extends AbstractTruffleException {
2424

2525
@TruffleBoundary
2626
private static RuntimeException javaStacktrace() {
27-
return new RuntimeException();
27+
return new RuntimeException("stacktrace:");
2828
}
2929

3030
public KillException(Node location) {

0 commit comments

Comments
 (0)