vt could allocate more than 2MB thus running over it's 2MB reserved heap and stepping on the shared segment. testcase: ; vt ; aux/write draw: events: ecanread stat error: segments overlap the executable is actually allocating 2.8MB: ; ps -a|grep vt quanstro 4235 0:00 0:00 2824K Pwrite vt quanstro 4236 0:00 0:00 168K Pread vt quanstro 4237 0:00 0:00 168K Pread vt quanstro 4238 0:00 0:00 172K Pread vt quanstro 4240 0:00 0:00 172K Pread vt quanstro 4250 0:00 0:00 156K Pread grep vt the solution is to let the system place the shared segment. the rest of the patch is to make all the errors consctl fatal; only a random subset had been. i think that telnetd/telnet have similar code, though i don't see with grep that they call malloc. Reference: /n/sources/patch/applied/vtlongline Date: Wed Jan 30 22:12:29 CET 2008 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/vt/consctl.c Wed Jan 30 22:04:21 2008 +++ /sys/src/cmd/vt/consctl.c Wed Jan 30 22:04:20 2008 @@ -4,27 +4,6 @@ #include "cons.h" /* - * create a shared segment. Make is start 2 meg higher than the current - * end of process memory. - */ -static void* -share(ulong len) -{ - uchar *vastart; - - vastart = sbrk(0); - if(vastart == (void*)-1) - return 0; - vastart += 2*1024*1024; - - if(segattach(0, "shared", vastart, len) == (void*)-1) - return 0; - memset(vastart, 0, len); - - return vastart; -} - -/* * bind a pipe onto consctl and keep reading it to * get changes to console state. */ @@ -38,27 +17,23 @@ Consstate *x; char *field[10]; - x = share(sizeof(Consstate)); - if(x == 0) - return 0; + x = segattach(0, "shared", 0, sizeof *x); + if(x == (void*)-1) + sysfatal("segattach: %r"); /* a pipe to simulate consctl */ if(bind("#|", "/mnt/cons/consctl", MBEFORE) < 0 - || bind("/mnt/cons/consctl/data1", "/dev/consctl", MREPL) < 0){ - fprint(2, "error simulating consctl\n"); - exits("/dev/consctl"); - } + || bind("/mnt/cons/consctl/data1", "/dev/consctl", MREPL) < 0) + sysfatal("bind: %r"); /* a pipe to simulate the /dev/cons */ if(bind("#|", "/mnt/cons/cons", MREPL) < 0 - || bind("/mnt/cons/cons/data1", "/dev/cons", MREPL) < 0){ - fprint(2, "error simulating cons\n"); - exits("/dev/cons"); - } + || bind("/mnt/cons/cons/data1", "/dev/cons", MREPL) < 0) + sysfatal("bind: %r"); switch(fork()){ case -1: - return 0; + sysfatal("fork: %r"); case 0: break; default: --- /sys/src/cmd/vt/event.c Wed Jan 30 22:04:27 2008 +++ /sys/src/cmd/vt/event.c Wed Jan 30 22:04:26 2008 @@ -26,10 +26,6 @@ int fd; cs = consctl(); - if(cs == 0){ - perror("consctl"); - exits("consctl"); - } switch((hostpid = rfork(RFPROC|RFNAMEG|RFFDG|RFNOTEG))) { case 0: