Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Jun 2008 23:14:41 +0400
From:      Eygene Ryabinkin <>
To:        Chuck Robey <>
Cc:        FreeBSD-Hackers <>
Subject:   Re: git problems
Message-ID:  </scUy64GiZyfP5+j5TO0oVAo2tE@tuQFyl9pqXYkbrygWcrojXcyvbA>
In-Reply-To: <>
References:  <> <TbQi51CAu4j4cFDkKULTI53ON0k@8ZdGo3QYE5K669Y/W2Z6ZKf2XtY> <> <L4F+2AmHcL4Uix8Rch4QiSpqQwc@RzJPyOBFuChtvuf1tf1krA3+wkI> <>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help

Wed, Jun 04, 2008 at 11:26:02AM -0400, Chuck Robey wrote:
> Looking at the top stack frame (main), that frame and the next are deeply
> involved in inspecting argv 0 thru 2, and since it's full of garbage, that's
> what breaks things.  That's NOT malloc, that seems to be either a problem in
> process creation or (I think more likely) a problem in the creation of a
> process's environment, the crt0 stuff.  I'm getting out of my depth, here.

Sorry, I had thought about stack smashing, but it isn't it, so I
somewhat guided people to the wrong way (if they were listening to me ;))

The real problem was the doubled call to the transport_unlock_pack()
in the builtin-fetch.c.  And the stack frame with __cxa_finalize
was perfectly correct -- as I learned half an hour ago, it is the
function that calls all handlers, registered with atexit().

So, the problem was the following: static function unlock_pack()
in the builtin-fetch.c is the cleanup routine for the static variable
'transport'.  And it calls transport_unlock_pack() if the 'transport'
variable isn't NULL.  But do_fetch() calls free(transport), so
atexit's unlock_pack() tries to use already freed memory.

The below patch works for me, although I should think about it
once more to see if it handles all cases.  Please, try the patch.

--- builtin-fetch.c.orig	2008-06-04 22:49:05.000000000 +0400
+++ builtin-fetch.c	2008-06-04 23:07:51.000000000 +0400
@@ -598,7 +598,7 @@
 int cmd_fetch(int argc, const char **argv, const char *prefix)
 	struct remote *remote;
-	int i;
+	int i, retval;
 	static const char **refs = NULL;
 	int ref_nr = 0;
@@ -654,6 +654,14 @@
 	signal(SIGINT, unlock_pack_on_signal);
-	return do_fetch(transport,
+	retval = do_fetch(transport,
 			parse_fetch_refspec(ref_nr, refs), ref_nr);
+	/*
+	 * Set transport to NULL, because its contents are already
+	 * freed in do_fetch(), so we mustn't deinitialize it in
+	 * unlock_pack().
+	 */
+	transport = NULL;
+	return retval;

Want to link to this message? Use this URL: <>