diff options
author | Josh Steadmon <steadmon@google.com> | 2022-06-07 21:21:57 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-06-07 22:48:19 +0300 |
commit | ce3986bb224067ecdb372d7cb7a56d22682e9a31 (patch) | |
tree | 8c0a684e215180869dd519e7c3255d187de2956a /run-command.c | |
parent | 6cd33dceed60949e2dbc32e3f0f5e67c4c882e1e (diff) |
run-command: don't spam trace2_child_exit()
In rare cases[1], wait_or_whine() cannot determine a child process's
status (and will return -1 in this case). This can cause Git to issue
trace2 child_exit events despite the fact that the child may still be
running. In pathological cases, we've seen > 80 million exit events in
our trace logs for a single child process.
Fix this by only issuing trace2 events in finish_command_in_signal() if
we get a value other than -1 from wait_or_whine(). This can lead to
missing child_exit events in such a case, but that is preferable to
duplicating events on a scale that threatens to fill the user's
filesystem with invalid trace logs.
[1]: This can happen when:
* waitpid() returns -1 and errno != EINTR
* waitpid() returns an invalid PID
* the status set by waitpid() has neither the WIFEXITED() nor
WIFSIGNALED() flags
Signed-off-by: Josh Steadmon <steadmon@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'run-command.c')
-rw-r--r-- | run-command.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/run-command.c b/run-command.c index a8501e38ce..e0fe2418a2 100644 --- a/run-command.c +++ b/run-command.c @@ -983,7 +983,8 @@ int finish_command(struct child_process *cmd) int finish_command_in_signal(struct child_process *cmd) { int ret = wait_or_whine(cmd->pid, cmd->args.v[0], 1); - trace2_child_exit(cmd, ret); + if (ret != -1) + trace2_child_exit(cmd, ret); return ret; } |