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
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to