X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f From: "Juan Manuel Guerrero" Organization: Darmstadt University of Technology To: djgpp-workers AT delorie DOT com Date: Mon, 29 Nov 2004 08:19:37 +0200 MIME-Version: 1.0 Subject: Re: A fix for popen(). Message-ID: <41AADB99.14622.194D345@localhost> References: <41A5BBC6 DOT 18442 DOT 2294B0C AT localhost> In-reply-to: X-mailer: Pegasus Mail for Windows (v4.02a, DE v4.02 R1) Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Mail message body X-TUD-HRZ-MailScanner: Found to be clean X-MailScanner-From: st001906 AT hrz1 DOT hrz DOT tu-darmstadt DOT de Reply-To: djgpp-workers AT delorie DOT com On Fri, 26 Nov 2004, Esa Peuha wrote: > On Thu, 25 Nov 2004, Juan Manuel Guerrero wrote: > > > The failure of popen() is one reason why the eval test of the testsuite of sed 4.1.2 fails > > if the package has been compiled with djdev204 and partially works if compiled with djdev203. > > djdev203 does not contain this bug. Unfortunatly now that this bug has been fixed a new one > > appers. Now the e command dies with a SIGSEGV in free() of djdev204. This must still be > > investigated. > > I tried to build sed 4.1.2 on my machine, but I can't because the > configure script doesn't work; it just exits without printing anything > (and doesn't generate a makefile either). I'll try to find out why, but > in the meantime, could you build sed with popen.o from 203 and malloc.o > from 204, and vice versa? That should at least tell where to look next. Running the configure script directly is not the recommended way but it should work. I have tried it and it fails as reported. Something is broken with the PATH and PATH_SEPARATOR handling. This problem can be solved by replacing bsh204b.zip with bsh205bb.zip. That new bash port works as it should. I have applied Esa Peuha's patch to the cvs sources (2004-11-22). The testsuite of sed produces the following traceback: make.exe[3]: Entering directory `d:/_projekte_/sed/gnu/sed-4.1-2/testsuite' cat ./eval.inp > eval.in2 LC_ALL=C ../sed/sed -f ./eval.sed < ./eval.inp > eval.out Exiting due to signal SIGSEGV General Protection Fault at eip=00017eeb eax=00197374 ebx=000bfae0 ecx=000d8744 edx=00197374 esi=000bcf40 edi=00034778 ebp=000bceb8 esp=000bceb0 program=D:\_PROJEKT\SED\GNU\SED-4.1-2\SED\SED.EXE cs: sel=034f base=83c90000 limit=000dffff ds: sel=0357 base=83c90000 limit=000dffff es: sel=0357 base=83c90000 limit=000dffff fs: sel=032f base=0004aa20 limit=0000ffff gs: sel=0367 base=00000000 limit=0010ffff ss: sel=0357 base=83c90000 limit=000dffff App stack: [000bf118..0003f11c] Exceptn stack: [0003f03c..0003d0fc] Call frame traceback EIPs: 0x00017eeb free+77, file c:/__/malloc.c, line 377 0x00019c7b pclose+464, file c:/__/popen.c, line 251 0x000072e3 .debug_info+1731, file d:/_projekte_/sed/gnu/sed-4.1-2/sed/execute.c, line 1245 0x00002189 .comment+5 0x000157d4 __crt1_startup+660, file crt1.c make.exe[3]: *** [eval] Error -1 make.exe[3]: Leaving directory `d:/_projekte_/sed/gnu/sed-4.1-2/testsuite' FAIL: eval The reason for the failure is that free() tries to release memory that has never been allocated. Please look at the following code snipped from popen(): /* hold file pointer, command, mode, and the status of the command */ struct pipe_list { FILE *fp; int exit_status; char *command, mode[10]; struct pipe_list *next; }; /* static, global list pointer */ static struct pipe_list *pl = NULL; FILE *popen(const char *cm, const char *md) /* program name, pipe mode */ { struct pipe_list *l1; char *temp_name; /* make new node */ if ((l1 = malloc(sizeof(*l1))) == NULL) return NULL; /* if empty list - just grab new node */ l1->next = pl; pl = l1; [snip] int pclose(FILE *pp) { [snip] exit: if (l1->command) free(l1->command); free(l1); return retval; } As can be seen the FILE pointer *fp and the char pointer *command are never initialized to same sane default. For the first two calls of popen, the memory allocated for struct l1 is identical zero but with the third and later calls the allocated memory is no longer zero. If pclose is called, the function tries to deallocate the memory pointed by the *command pointer and this makes free crash. In conclusion, or calloc must be used to allocte the struct or all struct elements must be initialized to some sane default. If this is done the sed testsuite works as it should. Please note that I can only test on Win98 but I assume that with these issues fixed it should work on WinXP too. Regards, Juan M. Guerrero diff -aruU4 djgpp.orig/src/libc/posix/stdio/popen.c djgpp/src/libc/posix/stdio/popen.c --- djgpp.orig/src/libc/posix/stdio/popen.c 2004-11-28 23:40:24.000000000 +0000 +++ djgpp/src/libc/posix/stdio/popen.c 2004-11-29 00:04:10.000000000 +0000 @@ -78,8 +78,12 @@ /* make new node */ if ((l1 = malloc(sizeof(*l1))) == NULL) return NULL; + /* initialize pointers to sane default */ + l1->fp = NULL; + l1->command = NULL; + /* if empty list - just grab new node */ l1->next = pl; pl = l1;