@@ -212,6 +212,14 @@ private Thread createJavaThread(Runnable runnable, RubyThread rubyThread, String
212
212
private static Thread .UncaughtExceptionHandler uncaughtExceptionHandler (RubyFiber fiber ) {
213
213
assert fiber != null ;
214
214
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
+
215
223
printInternalError (throwable );
216
224
try {
217
225
fiber .uncaughtException = throwable ;
@@ -307,28 +315,25 @@ public void initialize(RubyThread rubyThread, Node currentNode, String info, Str
307
315
}
308
316
309
317
/** {@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. */
311
320
private void threadMain (RubyThread thread , Node currentNode , Supplier <Object > task ) {
312
321
try {
313
322
final Object result = task .get ();
314
323
setThreadValue (thread , result );
315
324
// 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
321
328
throw e ;
322
329
} catch (RaiseException e ) {
323
330
setException (thread , e .getException (), currentNode );
324
331
} catch (DynamicReturnException e ) {
325
332
setException (thread , context .getCoreExceptions ().unexpectedReturn (currentNode ), currentNode );
326
333
} catch (ExitException e ) {
327
- setThreadValue (thread , Nil .INSTANCE );
328
334
rethrowOnMainThread (currentNode , e );
329
335
} catch (Throwable e ) {
330
336
final RuntimeException runtimeException = printInternalError (e );
331
- setThreadValue (thread , Nil .INSTANCE );
332
337
rethrowOnMainThread (currentNode , runtimeException );
333
338
} finally {
334
339
assert thread .value != null || thread .exception != null ;
0 commit comments