-
Notifications
You must be signed in to change notification settings - Fork 3k
erts: kill spawned child processes on VM exit (unix only) #9453
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
e1f8731
f0d4da0
377236b
ae8d3c7
9c1b74a
2f6085b
6f9f611
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -183,6 +183,7 @@ static ssize_t write_all(int fd, const char *buff, size_t size) { | |
| return pos; | ||
| } | ||
|
|
||
| static void kill_all_children(void); | ||
| static int forker_hash_init(void); | ||
|
|
||
| static int max_files = -1; | ||
|
|
@@ -571,6 +572,7 @@ main(int argc, char *argv[]) | |
| tcsetattr(0,TCSANOW,&initial_tty_mode); | ||
| } | ||
| DEBUG_PRINT("erl_child_setup failed to read from uds: %d, %d", res, errno); | ||
| kill_all_children(); | ||
| _exit(0); | ||
| } | ||
|
|
||
|
|
@@ -579,6 +581,7 @@ main(int argc, char *argv[]) | |
| if (isatty(0) && isatty(1)) { | ||
| tcsetattr(0,TCSANOW,&initial_tty_mode); | ||
| } | ||
| kill_all_children(); | ||
| _exit(0); | ||
| } | ||
| /* Since we use unix domain sockets and send the entire data in | ||
|
|
@@ -662,6 +665,21 @@ main(int argc, char *argv[]) | |
| return 1; | ||
| } | ||
|
|
||
| static void kill_child(pid_t os_pid) { | ||
| if (os_pid > 0 && kill(os_pid, SIGTERM) != 0) { | ||
| DEBUG_PRINT("error killing process %d: %d", os_pid, errno); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should always work, but if it doesn't because of eg. a race condition between the child dying on its own and killing it, continue with trying to kill the other children. |
||
| } | ||
| } | ||
|
|
||
| static void fun_kill_foreach(ErtsSysExitStatus *es, void *unused) { | ||
| kill_child(es->os_pid); | ||
| } | ||
|
|
||
| static void kill_all_children(void) { | ||
| DEBUG_PRINT("cleaning up by killing all %d child processes", forker_hash->nobjs); | ||
| hash_foreach(forker_hash, (HFOREACH_FUN)fun_kill_foreach, NULL); | ||
| } | ||
|
|
||
| static int fcmp(void *a, void *b) | ||
| { | ||
| ErtsSysExitStatus *sa = a; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7475,6 +7475,11 @@ reported to the owning process using signals of the form | |
|
|
||
| The maximum number of ports that can be open at the same time can be configured | ||
| by passing command-line flag [`+Q`](erl_cmd.md#max_ports) to [erl](erl_cmd.md). | ||
|
|
||
| When the VM shuts down, spawned executables are sent `SIGTERM` on unix. The | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "unix" -> "POSIX"? Hopefully this can be reimplemented for win32 in later work, anyway. Is it okay to have divergent behavior on the platforms? |
||
| child may still outlive the VM if it traps the signal. Note that any processes | ||
| started under a shell using `spawn` will not terminate unless they respond to | ||
| stdin or stdout being closed. | ||
| """. | ||
| -doc #{ category => ports }. | ||
| -spec open_port(PortName, PortSettings) -> port() when | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be unreachable.
Actually, I'm uncertain about some of the
ABORTexits: my thinking is that these indicate pathological corner cases where we can no longer trust the internal tracking nor child pipes, so it would be useless or even risky to try "atexit"-like cleanup behaviors. This is supported by documentation for glibcabort:That's how I feel, too.