On Sunday 07 September 2008, xRaich[o]²x wrote: > > Bart Schaefer wrote: > > On Sep 4, 1:04am, =?ISO-8859-1?Q?Bj=F6rn_Herzig?= wrote: > > } > > } I looked at the problem a little closer. Zsh does not call mmap to > > } allocate them and they dont get allocated when completion happens but > > } when the next command gets issued. > > > > If this is true, then this is something happening down in the library > > or kernel implementation of fork() and is out of zsh's control. > > > > Did you build zsh yourself? Can you check config.h for USE_MMAP ? > > If USE_MMAP is defined then anytime zsh parses a command it will have > > called mmap() to allocate zsh-heap space. You can try reconfiguring > > with --enable-zsh-mem and then check the pmap behavior again. > > > > } So in my example the new maps got added to the process' address space > > } when i executed pmap, but the same happens with any other programm. > > } Builtins however are an exception. So things start to go wrong when it > > } comes to forking. > > > > If you run pmap from another shell window rather than executing it > > from within the shell whose map you're examining, does the behavior > > change at all? > > > > My only guess goes something like this: > > > > Zsh has mapped memory for the heap during parsing etc. Those pages > > have had data written and therefore are marked "dirty". When fork() > > is called, those pages become shared address space with the child > > process. Zsh munmap()s them later but they aren't returned to the > > system because the child process is still using them. > > > > I'm not really happy with any of these explanations yet. > > > > > > Ok, i found it.... after wandering around in a few deadends and getting > some stuff wrong... but well. > > i did the following change to mem.c > > mod_export void > old_heaps(Heap old) > { > Heap h, n; > > queue_signals(); > for (h = heaps; h; h = n) { > n = h->next; > DPUTS(h->sp, "BUG: old_heaps() with pushed heaps"); > #ifdef USE_MMAP > //munmap((void *) h, sizeof(*h)); > munmap((void *) h, h->size); Good catch (it was obvious bug) > #else > //zfree(h, sizeof(*h)); > zfree(h, h->size); In most other places we are using zfree(h, HEAPSIZE); there is no guarantee heap is actually of size HEAPSIZE, but that does not matter (second argument is used only with enable-zsh-mem and serves as plausibility check only). Here is patch in proper format. It is using HEAPSIZE for consistency: Index: Src/mem.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/mem.c,v retrieving revision 1.16 diff -u -p -r1.16 mem.c --- Src/mem.c 17 May 2008 17:55:38 -0000 1.16 +++ Src/mem.c 7 Sep 2008 09:23:32 -0000 @@ -153,9 +153,9 @@ old_heaps(Heap old) n = h->next; DPUTS(h->sp, "BUG: old_heaps() with pushed heaps"); #ifdef USE_MMAP - munmap((void *) h, sizeof(*h)); + munmap((void *) h, h->size); #else - zfree(h, sizeof(*h)); + zfree(h, HEAPSIZE); #endif } heaps = old;