Subject: kern/6356: linux-emulation has problems w/ pipes
To: None <gnats-bugs@gnats.netbsd.org>
From: Hubert Feyrer <feyrer@rfhs8012.fh-regensburg.de>
List: netbsd-bugs
Date: 10/25/1998 09:43:25
>Number:         6356
>Category:       kern
>Synopsis:       linux-emulation has problems w/ pipes
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Oct 25 01:50:00 1998
>Last-Modified:
>Originator:     Hubert Feyrer
>Organization:
-- 
Hubert Feyrer <hubert.feyrer@rz.uni-regensburg.de>
>Release:        1.3H
>Environment:
	
System: NetBSD miyu 1.3H NetBSD 1.3H (MIYU) #32: Sat Oct 24 22:56:50 MEST 1998 feyrer@miyu:/data/cvs/src/sys/arch/i386/compile/MIYU i386


>Description:
	NetBSD's Linux emulation seems to have problems with programs
	using pipes, and dumps core.

>How-To-Repeat:
	1. Try to get Oracle running
	2. Compile the following on a Linux/i386 box, and try running the
	   resulting binary on a NetBSD/i386 machine:

	    #include <stdio.h>
	    #include <fcntl.h>
	
	    main()
	    {
	            FILE *file1;
	            file1 = popen("gzip > file1.gz", "w");
	            fprintf(file1, "This is a test\n");
	            pclose(file1);
	    }

	(FreeBSD has the same problem, btw, and the above code is based
	 on an example sent to me by sos@freebsd.org)

	miyu% ktrace -id ./freebsd-pipes2-linux
	Segmentation fault (core dumped)
	miyu% kdump | tail
	   868 freebsd-pipes2-l CALL  brk(0)
	   868 freebsd-pipes2-l RET   brk 134520832/0x804a000
	   868 freebsd-pipes2-l CALL  brk(0x804a088)
	   868 freebsd-pipes2-l RET   brk 134520968/0x804a088
	   868 freebsd-pipes2-l CALL  brk(0x804b000)
	   868 freebsd-pipes2-l RET   brk 134524928/0x804b000
	   868 freebsd-pipes2-l CALL  pipe(0xefbfd44c)
	   868 freebsd-pipes2-l RET   pipe 0
	   868 freebsd-pipes2-l PSIG  SIGSEGV SIG_DFL
	   868 freebsd-pipes2-l NAMI  "freebsd-pipes2-l.core"

	I've tried looking at what's in popen, using libg++'s iopopen.c,
	function _IO_proc_open following line 77. The code there is:

	  if (_IO_pipe(pipe_fds) < 0) 
	    return NULL;
	  if (mode[0] == 'r')
	    { 
	      parent_end = pipe_fds[0];
	      child_end = pipe_fds[1];
	      read_or_write = _IO_NO_WRITES;
	    }   
	  else
	    {
	      parent_end = pipe_fds[1];
	      child_end = pipe_fds[0];
	      read_or_write = _IO_NO_READS;
	    }
	  ((_IO_proc_file*)fp)->pid = child_pid = _IO_fork();

	The _IO_pipe is a #define for pipe(2), the _IO_fork is #define'd
	as vfork(2). comparing ktrace- and strace-output, the SEGV seems
	to happen after the pipe() call but before the vfork() call.

	I have no clue why this would happen.

	(The debugging was done native under Linux, as I didn't get any
	debugger to work under NetBSD, neither NetBSD's native gdb, nor
	a Linux-gdb running in emulation mode)


>Fix:
	Yes, please!
>Audit-Trail:
>Unformatted: