Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Jun 2008 23:14:41 +0400
From:      Eygene Ryabinkin <rea-fbsd@codelabs.ru>
To:        Chuck Robey <chuckr@telenix.org>
Cc:        FreeBSD-Hackers <freebsd-hackers@freebsd.org>
Subject:   Re: git problems
Message-ID:  </scUy64GiZyfP5%2Bj5TO0oVAo2tE@tuQFyl9pqXYkbrygWcrojXcyvbA>
In-Reply-To: <4846B40A.4010309@telenix.org>
References:  <4845AC84.6040407@telenix.org> <TbQi51CAu4j4cFDkKULTI53ON0k@8ZdGo3QYE5K669Y/W2Z6ZKf2XtY> <4846A77B.9060603@telenix.org> <L4F%2B2AmHcL4Uix8Rch4QiSpqQwc@RzJPyOBFuChtvuf1tf1krA3%2BwkI> <4846B40A.4010309@telenix.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Chuck,

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);
 	atexit(unlock_pack);
-	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;
 }
-- 
Eygene



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?/scUy64GiZyfP5%2Bj5TO0oVAo2tE>