zsh-workers
 help / color / mirror / code / Atom feed
From: "\"xRaich[o]²x\"" <raichoo@googlemail.com>
To: zsh-workers@sunsite.dk
Subject: [PATCH] compsys maps anonymous memory and never frees it
Date: Sun, 07 Sep 2008 10:23:36 +0200	[thread overview]
Message-ID: <48C38F88.9040202@gmail.com> (raw)
In-Reply-To: <080904072526.ZM12341@torch.brasslantern.com>

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);
#else
    //zfree(h, sizeof(*h));
    zfree(h, h->size);
#endif
    }
    heaps = old;
    fheap = NULL;
    unqueue_signals();
}

this might open up a can of worms. i don't know where this is going to 
blow up, but i'm pretty sure it will. but well... it seems to work.
old_heaps tried to unmap a 16384 bytes big segment by calling 
munmap(...,sizeof(h*)) which is 16 and left the rest in memory (which 
explains why the segments wasn't added explicitly).

Here is the dtrace script that finally caught the bug, if someone is 
interested:

#!/usr/sbin/dtrace -s

BEGIN
{
    printf("\nTarget is : %d\nSegement is %X\n",$target, $1);
}

syscall::mmap64:return
/arg1 == $1 && pid == $target/
{
    printf("mmap returns: %x",arg1);
    self->triggered = 1;
}

pid$target:zsh:dupstring:return
/self->triggered == 1/
{
    printf("Dupstring: %s",copyinstr(arg1));
    self->triggered = 0;
}

syscall::mmap64:entry
/pid == $target/
{
    printf("mmap size: %d",arg1);
}

syscall::munmap:entry
/arg0 == $1 && pid == $target/
{
    printf("munmap size: %d\n",arg1);
    ustack();
    self->munmapping = 1;
}

syscall::munmap:return
/self->munmapping/
{
    printf("Result of munmapping the segment in question was: %d",arg1);
    self->munmapping = 0;
}

fbt::as_removeseg:entry
/execname == "zsh" && ((struct seg*)arg1)->s_base == (caddr_t)$1/
{
    printf("\nGot removed");
    ustack(50);
    stack();
    exit(0);
}

fbt::as_addseg:entry
/execname == "zsh" && ((struct seg*)arg1)->s_base == (caddr_t)$1/
{
    printf("\nGot added");
    ustack();
    stack();
}

Regards,
Björn


       reply	other threads:[~2008-09-07  8:30 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <48BDF1EC.4050204@gmail.com>
     [not found] ` <080902200652.ZM9887@torch.brasslantern.com>
     [not found]   ` <682f90440809031604j5e349af2q8d40f24fc429dcc3@mail.gmail.com>
     [not found]     ` <080904072526.ZM12341@torch.brasslantern.com>
2008-09-07  8:23       ` "xRaich[o]²x" [this message]
2008-09-07  9:25         ` Andrey Borzenkov
2008-09-07 11:04         ` Andrey Borzenkov
2008-09-08 21:19           ` "xRaich[o]²x"

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48C38F88.9040202@gmail.com \
    --to=raichoo@googlemail.com \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).