Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signals not getting caught on Linux #14

Closed
isaacs opened this issue Dec 26, 2015 · 7 comments
Closed

Signals not getting caught on Linux #14

isaacs opened this issue Dec 26, 2015 · 7 comments

Comments

@isaacs
Copy link
Member

isaacs commented Dec 26, 2015

It looks like it's catching the signal, but then failing to un-hook itself and re-kill or something?

> [email protected] test /home/isaacs/signal-exit
> standard && nyc tap --timeout=240 ./test/*.js

./test/all-integration-test.js ...................... 31/56
  all-signals-integration-test > exits properly: SIGABRT
  not ok AssertionError: null == true
    at:
      file: test/all-integration-test.js
      line: 43
      column: 38
    name: AssertionError
    actual: null
    expected: true
    operator: ==
    generatedMessage: true
    test: 'exits properly: SIGABRT'
    message: 'AssertionError: null == true'
    source: |
      if (!process.env.TRAVIS) assert(err.signal)
    stack: |
      test/all-integration-test.js:43:38
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGALRM
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGALRM'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGBUS
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGBUS'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGFPE
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGFPE'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGHUP
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGHUP'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGILL
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGILL'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGINT
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGINT'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGIOT
  not ok AssertionError: null == true
    at:
      file: test/all-integration-test.js
      line: 43
      column: 38
    name: AssertionError
    actual: null
    expected: true
    operator: ==
    generatedMessage: true
    test: 'exits properly: SIGIOT'
    message: 'AssertionError: null == true'
    source: |
      if (!process.env.TRAVIS) assert(err.signal)
    stack: |
      test/all-integration-test.js:43:38
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGPIPE
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGPIPE'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGPROF
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGPROF'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGQUIT
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGQUIT'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGSEGV
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGSEGV'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGSYS
  not ok AssertionError: null == true
    at:
      file: test/all-integration-test.js
      line: 43
      column: 38
    name: AssertionError
    actual: null
    expected: true
    operator: ==
    generatedMessage: true
    test: 'exits properly: SIGSYS'
    message: 'AssertionError: null == true'
    source: |
      if (!process.env.TRAVIS) assert(err.signal)
    stack: |
      test/all-integration-test.js:43:38
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGTERM
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGTERM'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGTRAP
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGTRAP'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGUSR1
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGUSR1'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGUSR2
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGUSR2'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGVTALRM
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGVTALRM'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGXCPU
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGXCPU'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGXFSZ
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGXFSZ'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGIO
  not ok AssertionError: null == true
    at:
      file: test/all-integration-test.js
      line: 43
      column: 38
    name: AssertionError
    actual: null
    expected: true
    operator: ==
    generatedMessage: true
    test: 'exits properly: SIGIO'
    message: 'AssertionError: null == true'
    source: |
      if (!process.env.TRAVIS) assert(err.signal)
    stack: |
      test/all-integration-test.js:43:38
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGPOLL
  not ok AssertionError: null == true
    at:
      file: test/all-integration-test.js
      line: 43
      column: 38
    name: AssertionError
    actual: null
    expected: true
    operator: ==
    generatedMessage: true
    test: 'exits properly: SIGPOLL'
    message: 'AssertionError: null == true'
    source: |
      if (!process.env.TRAVIS) assert(err.signal)
    stack: |
      test/all-integration-test.js:43:38
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGPWR
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGPWR'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGSTKFLT
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/all-integration-test.js
      line: 41
      column: 48
    test: 'exits properly: SIGSTKFLT'
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal(sig)
    stack: |
      test/all-integration-test.js:41:48
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  all-signals-integration-test > exits properly: SIGUNUSED
  not ok AssertionError: null == true
    at:
      file: test/all-integration-test.js
      line: 43
      column: 38
    name: AssertionError
    actual: null
    expected: true
    operator: ==
    generatedMessage: true
    test: 'exits properly: SIGUNUSED'
    message: 'AssertionError: null == true'
    source: |
      if (!process.env.TRAVIS) assert(err.signal)
    stack: |
      test/all-integration-test.js:43:38
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

./test/signal-exit-test.js .......................... 10/11
  signal-exit > removes handlers when fully unwrapped
  not ok TypeError: Cannot read property 'should' of null
    at:
      file: test/signal-exit-test.js
      line: 89
      column: 42
    test: removes handlers when fully unwrapped
    message: "TypeError: Cannot read property 'should' of null"
    source: |
      if (!process.env.TRAVIS) err.signal.should.equal('SIGHUP')
    stack: |
      test/signal-exit-test.js:89:42
      ChildProcess.exithandler (child_process.js:220:5)
      maybeClose (internal/child_process.js:818:16)
      Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

total ............................................... 41/67


  41 passing (15s)
  26 failing

npm ERR! Test failed.  See above for more details.
@isaacs
Copy link
Member Author

isaacs commented Dec 26, 2015

It looks like this might be a node bug? (Or at least a node os difference that libuv doesn't handwave away.)

On Linux, I see this error in the exec result:

{ [Error: Command failed: /bin/sh -c /home/isaacs/.nave/installed/4.0.0/bin/node /home/isaacs/signal-exit/test/fixtures/exiter.js SIGABRT
  Aborted (core dumped)
  ]
    killed: false,
    code: 134,
    signal: null,
    cmd: '/bin/sh -c /home/isaacs/.nave/installed/4.0.0/bin/node /home/isaacs/signal-exit/test/fixtures/exiter.js SIGABRT' }

But on OS X it looks like:

{ [Error: Command failed: /bin/sh -c /usr/local/bin/node /Users/isaacs/dev/js/signal-exit/test/fixtures/exiter.js SIGABRT
  ]
    killed: false,
    code: null,
    signal: 'SIGABRT',
    cmd: '/bin/sh -c /usr/local/bin/node /Users/isaacs/dev/js/signal-exit/test/fixtures/exiter.js SIGABRT' }

It looks like the child_process.exec function on Linux isn't doing the thing where exit codes >127 are interpreted as signal codes.

@isaacs
Copy link
Member Author

isaacs commented Dec 26, 2015

Note that the exit code is 134, and:

> require('constants').SIGABRT + 128
134

@isaacs
Copy link
Member Author

isaacs commented Dec 26, 2015

It does work when sh is not in the way, though.

Maybe this is an sh-vs-bash issue?

@isaacs
Copy link
Member Author

isaacs commented Dec 26, 2015

Yes, indeed, using bash instead of sh makes this work as expected on Linux.

Now to figure out why sh doesn't behave like bash here. :\

@bcoe
Copy link
Member

bcoe commented Dec 26, 2015

@isaacs interesting, it does seem like we have enough information that we can start to create a shim for bash, perhaps we can map the code to a signal for each test.

@isaacs
Copy link
Member Author

isaacs commented Dec 26, 2015

nodejs/node#4432

I think this is something that signal-exit should probably transparently fix.

bcoe pushed a commit that referenced this issue Dec 26, 2015
@isaacs
Copy link
Member Author

isaacs commented Dec 26, 2015

Oh, I guess this isn't really a problem with signal-exit, but rather just with signal-exit's tests.

Foreground-child is the one that gets most badly dinged by this, I guess.

isaacs added a commit to isaacs/signal-exit that referenced this issue Dec 28, 2015
Fix tapjs#14 by avoiding Dash on Ubuntu systems.

As it happens, this module was working just fine, but the exec shell was
exiting in a way that didn't match the exit of its last job.
@bcoe bcoe closed this as completed in #16 Dec 28, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants