git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Cc: Brandon Casey <drafnel@gmail.com>
Subject: [PATCH 1/3] usage: refactor die-recursion checks
Date: Mon, 15 Apr 2013 19:08:02 -0400	[thread overview]
Message-ID: <20130415230802.GA11267@sigill.intra.peff.net> (raw)
In-Reply-To: <20130415230651.GA16670@sigill.intra.peff.net>

When any git code calls die(), we chain to a custom
die_routine, which we expect to print a message and exit the
program. To avoid infinite loops, we detect a recursive call
to die() with a simple counter, and break out of the loop by
printing a message and exiting ourselves, without chaining
to the die_routine.

But the user does not get to see the message that would have
been fed to the die_routine, which makes debugging harder.
The user does not know if it was a true infinite loop, or
simply a single re-entrant call, since they cannot compare
the messages. Furthermore, if we are wrong about detecting
the recursion, we have blocked the user from seeing the
original message, which is probably the more useful one.

This patch teaches die() to print the original die message
to stderr before reporting the recursion. The custom
die_routine may or may not have put it the message to
stderr, but this is the best we can do (it is what most
handlers will do anyway, and it is where our recursion error
will go).

While we're at it, let's mark the "recursion detected"
message as a "BUG:", since it should never happen in
practice. And let's factor out the repeated code in die and
die_errno. This loses the information of which function was
called to cause the recursion, but it's important; knowing
the actual message fed to the function (which we now do) is
much more useful, as it can generally pin-point the actual
call-site that caused the recursion.

Signed-off-by: Jeff King <peff@peff.net>
---
This helped me debug the current problem. And factoring it out helps
with patch 3. :)

 usage.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/usage.c b/usage.c
index 40b3de5..c6b7ac5 100644
--- a/usage.c
+++ b/usage.c
@@ -6,8 +6,6 @@
 #include "git-compat-util.h"
 #include "cache.h"
 
-static int dying;
-
 void vreportf(const char *prefix, const char *err, va_list params)
 {
 	char msg[4096];
@@ -80,17 +78,24 @@ void NORETURN die(const char *err, ...)
 	usagef("%s", err);
 }
 
+static void check_die_recursion(const char *fmt, va_list ap)
+{
+	static int dying;
+
+	if (!dying++)
+		return;
+
+	vreportf("fatal: ", fmt, ap);
+	fputs("BUG: recursion detected in die handler\n", stderr);
+	exit(128);
+}
+
 void NORETURN die(const char *err, ...)
 {
 	va_list params;
 
-	if (dying) {
-		fputs("fatal: recursion detected in die handler\n", stderr);
-		exit(128);
-	}
-	dying = 1;
-
 	va_start(params, err);
+	check_die_recursion(err, params);
 	die_routine(err, params);
 	va_end(params);
 }
@@ -102,13 +107,6 @@ void NORETURN die_errno(const char *fmt, ...)
 	char str_error[256], *err;
 	int i, j;
 
-	if (dying) {
-		fputs("fatal: recursion detected in die_errno handler\n",
-			stderr);
-		exit(128);
-	}
-	dying = 1;
-
 	err = strerror(errno);
 	for (i = j = 0; err[i] && j < sizeof(str_error) - 1; ) {
 		if ((str_error[j++] = err[i++]) != '%')
@@ -126,6 +124,7 @@ void NORETURN die_errno(const char *fmt, ...)
 	snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, str_error);
 
 	va_start(params, fmt);
+	check_die_recursion(fmt_with_err, params);
 	die_routine(fmt_with_err, params);
 	va_end(params);
 }
-- 
1.8.2.8.g44e4c28

  reply	other threads:[~2013-04-15 23:08 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-15 23:06 [PATCH 0/3] avoid bogus "recursion detected in die handler" message Jeff King
2013-04-15 23:08 ` Jeff King [this message]
2013-04-15 23:45   ` [PATCH 1/3] usage: refactor die-recursion checks Eric Sunshine
2013-04-15 23:47     ` Jeff King
2013-04-16  0:11   ` Brandon Casey
2013-04-16  0:42     ` Jeff King
2013-04-16  1:41       ` Jonathan Nieder
2013-04-16  2:34       ` Brandon Casey
2013-04-16  2:50         ` Jeff King
2013-04-16  7:18           ` Johannes Sixt
2013-04-16 13:01             ` Jeff King
2013-04-16 14:13               ` Johannes Sixt
2013-04-16 19:44                 ` [PATCH v2 0/2] avoid bogus "recursion detected in die handler" message Jeff King
2013-04-16 19:46                   ` [PATCH v2 1/2] usage: allow pluggable die-recursion checks Jeff King
2013-04-16 19:50                   ` [PATCH v2 2/2] run-command: use thread-aware die_is_recursing routine Jeff King
2013-04-16 22:09                     ` Junio C Hamano
2013-04-17  0:49                   ` [PATCH v2 0/2] avoid bogus "recursion detected in die handler" message Jonathan Nieder
2013-04-17  1:37                     ` Jeff King
2013-04-23 21:27                   ` Erik Faye-Lund
2013-04-15 23:08 ` [PATCH 2/3] run-command: factor out running_main_thread function Jeff King
2013-04-16  1:45   ` Jonathan Nieder
2013-04-16  2:53     ` Jeff King
2013-04-15 23:09 ` [PATCH 3/3] usage: do not check die recursion outside main thread 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=20130415230802.GA11267@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=drafnel@gmail.com \
    --cc=git@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).