git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Johannes Sixt <j.sixt@viscovery.net>
Cc: Brandon Casey <drafnel@gmail.com>,
	"git@vger.kernel.org" <git@vger.kernel.org>
Subject: [PATCH v2 0/2] avoid bogus "recursion detected in die handler" message
Date: Tue, 16 Apr 2013 15:44:18 -0400	[thread overview]
Message-ID: <20130416194418.GA7187@sigill.intra.peff.net> (raw)
In-Reply-To: <516D5CA4.7000500@viscovery.net>

On Tue, Apr 16, 2013 at 04:13:56PM +0200, Johannes Sixt wrote:

> > I'm not clear on what you are suggesting. That we protect only the main
> > thread from recursion, or that we drop the check entirely? Or that we
> > implement thread-local storage for this case without using pthread_once?
> 
> Anything(*) that does not require pthread_once. A pthread_once
> implementation on Windows would be tricky and voluminous and and on top of
> it very likely to be done differently for gcc and MSVC. I don't like to go
> there if we can avoid it.

We don't need to use pthread_once, as we can just do the initialization
of the thread-local storage along with starting the first thread (where
we already do similar initialization).  Patch series to follow:

  [1/2]: usage: allow pluggable die-recursion checks
  [2/2]: run-command: use thread-aware die_is_recursing routine

> (*) That includes doing nothing, but does not include ripping out the
> recursion check, as it protects us from crashes.

I don't think doing nothing is a good idea. The recursion-detection is
triggering erroneously, blocking real error messages and replacing them
with the scary red-herring "recursion detected in die handler".

The absolute simplest thing I think we could do is basically:

diff --git a/run-command.c b/run-command.c
index 765c2ce..3b0ad44 100644
--- a/run-command.c
+++ b/run-command.c
@@ -599,11 +599,14 @@ static NORETURN void die_async(const char *err, va_list params)
 	return (void *)ret;
 }
 
+extern int dying;
+
 static NORETURN void die_async(const char *err, va_list params)
 {
 	vreportf("fatal: ", err, params);
 
 	if (!pthread_equal(main_thread, pthread_self())) {
+		dying = 0; /* undo counter */
 		struct async *async = pthread_getspecific(async_key);
 		if (async->proc_in >= 0)
 			close(async->proc_in);
diff --git a/usage.c b/usage.c
index 40b3de5..cf8a968 100644
--- a/usage.c
+++ b/usage.c
@@ -6,7 +6,7 @@
 #include "git-compat-util.h"
 #include "cache.h"
 
-static int dying;
+int dying;
 
 void vreportf(const char *prefix, const char *err, va_list params)
 {

Obviously it would help to wrap it in a "clear_die_counter()" function,
but it would still suffer from the problem that there is no
synchronization. In the moment between incrementing and resetting the
dying counter, another thread (including the main program) could check
it. In practice, this does not happen in the current code, because we
do not start many async threads (and we only die in the main thread once
the async thread dies). But it seems unnecessarily flaky and prone to
future problems.

It would also be possible to use mutexes to make it work reliably, but
I'd be very concerned about increasing the complexity of the die code
path.  We would never want a hung thread to prevent the main program
from successfully exiting, for example.

So I think the right solution is just a per-thread counter.

-Peff

  reply	other threads:[~2013-04-16 19:44 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 ` [PATCH 1/3] usage: refactor die-recursion checks Jeff King
2013-04-15 23:45   ` 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                 ` Jeff King [this message]
2013-04-16 19:46                   ` [PATCH v2 1/2] usage: allow pluggable " 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=20130416194418.GA7187@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=drafnel@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=j.sixt@viscovery.net \
    /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).