Browse Source

src: backport fix for SIGINT crash on FreeBSD

This is a backport of b64983d77c.

Original commit message:

  src: reset signal handler to SIG_DFL on FreeBSD

  FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO,
  that is in turn set for a libthr wrapper. This leads to a crash.
  Work around the issue by manually setting SIG_DFL in the signal
  handler.

  Fix: https://github.com/joyent/node/issues/9326
  PR-URL: https://github.com/iojs/io.js/pull/1218
  Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
  Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>

Fixes #9326.

Reviewed-By: Trevor Norris <trev.norris@gmail.com>
PR-URL: https://github.com/joyent/node/pull/14184
v0.12.2-release
Fedor Indutny 10 years ago
committed by Julien Gilli
parent
commit
61fe1fe21b
  1. 12
      src/node.cc
  2. 12
      test/simple/test-regress-GH-node-9326.js

12
src/node.cc

@ -2785,6 +2785,13 @@ static void AtExit() {
static void SignalExit(int signo) { static void SignalExit(int signo) {
uv_tty_reset_mode(); uv_tty_reset_mode();
#ifdef __FreeBSD__
// FreeBSD has a nasty bug, see RegisterSignalHandler for details
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
#endif
raise(signo); raise(signo);
} }
@ -3163,7 +3170,12 @@ static void RegisterSignalHandler(int signal,
struct sigaction sa; struct sigaction sa;
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler; sa.sa_handler = handler;
#ifndef __FreeBSD__
// FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
// in turn set for a libthr wrapper. This leads to a crash.
// Work around the issue by manually setting SIG_DFL in the signal handler
sa.sa_flags = reset_handler ? SA_RESETHAND : 0; sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
#endif
sigfillset(&sa.sa_mask); sigfillset(&sa.sa_mask);
CHECK_EQ(sigaction(signal, &sa, NULL), 0); CHECK_EQ(sigaction(signal, &sa, NULL), 0);
} }

12
test/simple/test-regress-GH-node-9326.js

@ -0,0 +1,12 @@
var assert = require('assert');
var child_process = require('child_process');
// NOTE: Was crashing on FreeBSD
var cp = child_process.spawn(process.execPath, [
'-e',
'process.kill(process.pid, "SIGINT")'
]);
cp.on('exit', function(code) {
assert.notEqual(code, 0);
});
Loading…
Cancel
Save