Samstag, 13. September 2008

ZSH Patch gegen fieses Memory Leak

Ich bin neulich auf einen unschönen Bug in ZSH gestoßen. Bei aktiviertem compinit wird bei jeder Vervollständigung ein Segment anonymer Speicher angelegt und nicht wieder richtig freigegeben. Ein kleines dtrace Skript hat das Problem entlarvt.

#!/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();
stack();
exit(0);
}

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

Danke an das ZSH-Team für das Überprüfen meines Patches.

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;

ZSH: IPS Completion Skript

So ich hab mich mal hingesetzt und ein Vervollständigungsskript für IPS in der ZSH geschrieben. Das ganze ist noch relativ frisch und deswegen klappt vielleicht noch nicht alles so wie es soll, also gilt wie immer: PATCHES WELCOME ;)

IPS Completion

Um es zu nutzen: einfach als _pkg in /usr/share/zsh/site-functions speichern (compinit muss dafür aktiviert sein)

Gegebenenfalls werde ich das Skript natürlich aktualisieren. Ich habe leider noch nicht rausbekommen wie man Google Docs verbieten kann die Einrückung einfach zu verschlucken, also sieht das ganze dementsprechend schrecklich aus. Ich hoffe mal das es trotzdem noch ohne Probleme funktionieren wird.