git problems

Eygene Ryabinkin rea-fbsd at codelabs.ru
Wed Jun 4 19:14:44 UTC 2008


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


More information about the freebsd-hackers mailing list