Skip to content

child_process.exec is not abortable in Linux #37518

Closed as not planned
Closed as not planned
@MadaraUchiha

Description

@MadaraUchiha
  • Version: 15.8.0 (but also 12.21.0, and 16.0.0-pre)
  • Platform: Linux madara-laptop-linux 5.4.0-65-generic The README is oriented towards Node #73-Ubuntu SMP Mon Jan 18 17:25:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
  • Subsystem: child_process

What steps will reproduce the bug?

  1. Create a script that will run forever eg. keep-alive.js: setInterval(() => {}, 10_000);
  2. Create a script that will exec that file and abort it within a few seconds:
// keep-alive-test.js
const { exec } = require('child_process');

const ac = new AbortController();
const { signal } = ac;
const child = child_process.exec(`${process.execPath} ./keep-alive.js`, { signal ), console.log);

setTimeout(() => ac.abort(), 10_000);
  1. Run node keep-alive-test.js &
  2. Examine running processes with ps awwx | grep alive | grep -v grep | cat
  3. You will note 3 running processes, node keep-alive-test.js, sh -c node keep-alive.js and node keep-alive.js
  4. After 10 seconds, the abort is invoked.
  5. Examine running processes again with ps awwx | grep alive | grep -v grep | cat
  6. You will note 2 running processes, node keep-alive-test.js and node keep-alive.js (sh was terminated).
  7. Both processes will live forever until explicitly terminated by the user (fg -> CTRL+C, or killall node etc)

How often does it reproduce? Is there a required condition?

Every time.

What is the expected behavior?

Expected behavior for ac.abort() was to abort the child process.

What do you see instead?

Child process does not get aborted, only the shell does.

Additional information

Internally, the abort handler for all child_process methods use child.kill() to terminate the underlying process. However, it is documented that this does not work "as expected" in Linux.

This makes ac.abort() quite useless on execed children, since none of them would actually get aborted at all.

This will probably happen if one uses child_process.spawn() to similarly spawn a shell to invoke a process, though I have not tested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    child_processIssues and PRs related to the child_process subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions