summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-06-30 13:45:21 -0700
committerJunio C Hamano <gitster@pobox.com>2017-06-30 13:45:21 -0700
commitc7ee0baae7e874898032ab0c63600951eb7c2d18 (patch)
treecfa805e3c01c28f04d79cf91d0c097abaec944cc
parent545222471004cc3fd53c54ff53d40a8bbc3dabe6 (diff)
parent2d3c02f5db620af7169b651ff4afe625df3af156 (diff)
downloadgit-c7ee0baae7e874898032ab0c63600951eb7c2d18.tar.gz
Merge branch 'ab/die-errors-in-threaded'
Traditionally, the default die() routine had a code to prevent it from getting called multiple times, which interacted badly when a threaded program used it (one downside is that the real error may be hidden and instead the only error message given to the user may end up being "die recursion detected", which is not very useful). * ab/die-errors-in-threaded: die(): stop hiding errors due to overzealous recursion guard
-rw-r--r--usage.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/usage.c b/usage.c
index 2f87ca69a8..1ea7df9a20 100644
--- a/usage.c
+++ b/usage.c
@@ -44,7 +44,23 @@ static void warn_builtin(const char *warn, va_list params)
static int die_is_recursing_builtin(void)
{
static int dying;
- return dying++;
+ /*
+ * Just an arbitrary number X where "a < x < b" where "a" is
+ * "maximum number of pthreads we'll ever plausibly spawn" and
+ * "b" is "something less than Inf", since the point is to
+ * prevent infinite recursion.
+ */
+ static const int recursion_limit = 1024;
+
+ dying++;
+ if (dying > recursion_limit) {
+ return 1;
+ } else if (dying == 2) {
+ warning("die() called many times. Recursion error or racy threaded death!");
+ return 0;
+ } else {
+ return 0;
+ }
}
/* If we are in a dlopen()ed .so write to a global variable would segfault