rea-fbsd at codelabs.ru
Wed Jun 4 19:14:44 UTC 2008
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 @@
- 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;
More information about the freebsd-hackers