All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Wincent Colaiuta <win@wincent.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] status: read submodule process output before calling wait()
Date: Sun, 22 Mar 2015 04:07:08 -0400	[thread overview]
Message-ID: <20150322080708.GA3456@peff.net> (raw)
In-Reply-To: <20150322074455.GA1303@peff.net>

On Sun, Mar 22, 2015 at 03:44:55AM -0400, Jeff King wrote:

> The status code tries to read the output of "git submodule
> summary" over a pipe by waiting for the program to finish
> and then reading its output, like this:
> 
>   run_command(&sm_summary);
>   len = strbuf_read(&cmd_stdout, sm_summary.out, 1024);

By the way, I spotted this code as bogus immediately upon seeing it
(though certainly it helped to know there was a deadlock in the area,
which had me thinking about such things). So I wondered if it could have
been easy to catch in review, but its introduction was a little bit
subtle.

The original run_command invocation came in ac8d5af (builtin-status:
submodule summary support, 2008-04-12), which just let the sub-process
dump its stdout to the same descriptor that the rest of the status
output was going to. So the use of run_command there was fine. It was
later, in 3ba7407 (submodule summary: ignore --for-status option,
2013-09-06), that we started post-processing the output and it became
buggy. But that's harder to see in review.

> Besides being a violation of the run-command API (which
> makes no promises about the state of the struct after
> run_command returns),

This may be overly harsh of me. Certainly we make no guarantees (and
things like the dynamic "args" and "env_array" are cleaned up
automatically after finish_command returns), but I would not be
surprised if there are other spots that treat "struct child_process" as
transparent rather than as a black box.

It's really the run_command + pipe construct that is really the danger
here. I wonder if we should do something like this:

diff --git a/run-command.c b/run-command.c
index 3afb124..78807de 100644
--- a/run-command.c
+++ b/run-command.c
@@ -557,7 +557,12 @@ int finish_command(struct child_process *cmd)
 
 int run_command(struct child_process *cmd)
 {
-	int code = start_command(cmd);
+	int code;
+
+	if (cmd->out < 0)
+		die("BUG: run_command with a pipe can cause deadlock");
+
+	code = start_command(cmd);
 	if (code)
 		return code;
 	return finish_command(cmd);

It seems to catch at least one other dubious construct.

-Peff

  reply	other threads:[~2015-03-22  8:07 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-22  5:56 status hangs trying to get submodule summary Wincent Colaiuta
2015-03-22  7:44 ` [PATCH] status: read submodule process output before calling wait() Jeff King
2015-03-22  8:07   ` Jeff King [this message]
2015-03-22  9:59   ` [PATCH 0/7] introduce strbuf_read_cmd to avoid deadlocks Jeff King
2015-03-22 10:00     ` [PATCH 1/7] wt-status: don't flush before running "submodule status" Jeff King
2015-03-22 10:00     ` [PATCH 2/7] wt_status: fix signedness mismatch in strbuf_read call Jeff King
2015-03-22 10:07     ` [PATCH 3/7] strbuf: introduce strbuf_read_cmd helper Jeff King
2015-03-22 19:36       ` Eric Sunshine
2015-03-22 22:54         ` Junio C Hamano
2015-03-22 23:40           ` Junio C Hamano
2015-03-23  3:53             ` [PATCH v2 0/7] introduce capture_command to avoid deadlocks Jeff King
2015-03-23  3:53               ` [PATCH v2 1/7] wt-status: don't flush before running "submodule status" Jeff King
2015-03-23  3:53               ` [PATCH v2 2/7] wt_status: fix signedness mismatch in strbuf_read call Jeff King
2015-03-23  3:53               ` [PATCH v2 3/7] run-command: introduce capture_command helper Jeff King
2015-03-23  3:53               ` [PATCH v2 4/7] wt-status: use capture_command Jeff King
2015-03-23  3:53               ` [PATCH v2 5/7] submodule: " Jeff King
2015-03-23  3:54               ` [PATCH v2 6/7] trailer: " Jeff King
2015-03-23  3:54               ` [PATCH v2 7/7] run-command: forbid using run_command with piped output Jeff King
2015-03-23  4:40               ` [PATCH v2 0/7] introduce capture_command to avoid deadlocks Junio C Hamano
2015-03-22 23:34         ` [PATCH 3/7] strbuf: introduce strbuf_read_cmd helper Jeff King
2015-03-22 23:22       ` Junio C Hamano
2015-03-22 23:36         ` Jeff King
2015-03-22 10:08     ` [PATCH 4/7] wt-status: use strbuf_read_cmd Jeff King
2015-03-22 10:08     ` [PATCH 5/7] submodule: " Jeff King
2015-03-22 10:09     ` [PATCH 6/7] trailer: " Jeff King
2015-03-22 10:10     ` [PATCH 7/7] run-command: forbid using run_command with piped output Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150322080708.GA3456@peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=win@wincent.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.