www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2004/11/29/02:21:10

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
From: "Juan Manuel Guerrero" <st001906 AT hrz1 DOT hrz DOT tu-darmstadt DOT de>
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: <Pine.OSF.4.58.0411261154320.29400@sirppi.helsinki.fi>
X-mailer: Pegasus Mail for Windows (v4.02a, DE v4.02 R1)
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;
 

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019