Skip to content

Commit 8157fdf

Browse files
committed
Print error message, restore default signal handler and re-raise signal when --single-threaded
* Fixes #2265 * TruffleLogger does not work when the context is not entered. * Exceptions from SignalHandler seem ignored by the JVM.
1 parent 636a713 commit 8157fdf

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Bug fixes:
1313
* Fix `Thread.handle_interrupt` to defer non-pure interrupts until the end of the `handle_interrupt` block (#2219).
1414
* Clear and restore errinfo on entry and normal return from methods in C extensions (#2227).
1515
* Fix extra whitespace in squiggly heredoc with escaped newline (#2238, @wildmaples and @norswap).
16+
* Fix handling of signals with `--single-threaded` (#2265).
1617

1718
Compatibility:
1819

src/main/java/org/truffleruby/core/VMPrimitiveNodes.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -252,18 +252,17 @@ protected boolean restoreDefault(Object signalString, Object action,
252252
@Specialization(guards = "libSignalString.isRubyString(signalString)")
253253
protected boolean watchSignalProc(Object signalString, RubyProc action,
254254
@CachedLibrary(limit = "2") RubyStringLibrary libSignalString) {
255-
if (getContext().getThreadManager().getCurrentThread() != getContext().getThreadManager().getRootThread()) {
255+
final RubyContext context = getContext();
256+
257+
if (context.getThreadManager().getCurrentThread() != context.getThreadManager().getRootThread()) {
256258
// The proc will be executed on the main thread
257259
SharedObjects.writeBarrier(getLanguage(), action);
258260
}
259261

260-
final RubyContext context = getContext();
261-
262-
String signalName = libSignalString.getJavaString(signalString);
262+
final String signalName = libSignalString.getJavaString(signalString);
263263
return registerHandler(signalName, signal -> {
264264
if (context.getOptions().SINGLE_THREADED) {
265-
RubyLanguage.LOGGER.severe(
266-
"signal " + signal + " caught but can't create a thread to handle it so ignoring");
265+
warnRestoreAndRaise(context, signalName, signal, "create a thread");
267266
return;
268267
}
269268

@@ -276,16 +275,7 @@ protected boolean watchSignalProc(Object signalString, RubyProc action,
276275
try {
277276
prev = truffleContext.enter(this);
278277
} catch (IllegalStateException e) { // Multi threaded access denied from Truffle
279-
// Not in a context, so we cannot use TruffleLogger
280-
context.getEnvErrStream().println(
281-
"[ruby] SEVERE: signal " + signal +
282-
" caught but can't attach a thread to handle it so restoring the default handler and re-raising the signal");
283-
Signals.restoreDefaultHandler(signalName);
284-
try {
285-
Signal.raise(signal);
286-
} catch (IllegalArgumentException illegalArgumentException) {
287-
illegalArgumentException.printStackTrace(context.getEnvErrStream());
288-
}
278+
warnRestoreAndRaise(context, signalName, signal, "attach a thread");
289279
return;
290280
}
291281
try {
@@ -299,6 +289,19 @@ protected boolean watchSignalProc(Object signalString, RubyProc action,
299289
});
300290
}
301291

292+
private static void warnRestoreAndRaise(RubyContext context, String signalName, Signal signal, String failure) {
293+
// Not in a context, so we cannot use TruffleLogger
294+
context.getEnvErrStream().println(
295+
"[ruby] SEVERE: signal " + signal + " caught but can't " + failure +
296+
" to handle it so restoring the default handler and re-raising the signal");
297+
Signals.restoreDefaultHandler(signalName);
298+
try {
299+
Signal.raise(signal);
300+
} catch (IllegalArgumentException illegalArgumentException) {
301+
illegalArgumentException.printStackTrace(context.getEnvErrStream());
302+
}
303+
}
304+
302305
@TruffleBoundary
303306
private boolean restoreDefaultHandler(String signalName) {
304307
if (getContext().getOptions().EMBEDDED) {

0 commit comments

Comments
 (0)