Mail Archives: djgpp-workers/2004/11/29/02:21:10
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;
- Raw text -