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>