Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Message-Id: <200110191945.f9JJjn506860@head-cfa.harvard.edu> To: cygwin AT cygwin DOT com Subject: Re: bug in 1.3.3 2000/NT (probably socket()) cc: eric AT head-cfa DOT harvard DOT edu Date: Fri, 19 Oct 2001 15:45:49 -0400 From: Eric Mandel On Oct 18, Christopher Faylor wrote: > >The program works correctly under Cygwin 1.3.2 (NT and 2000) but not > >under Cygwin 1.3.3 (NT or 2000). (It also works under Solaris 5.8). > >Under 1.3.3, select() returns an error each time it is called: > > > > select(): bad file number > > Try a snapshot. > > cgf As requested, we tried running the test server program (as well as our real software suite from which the test is culled) on both the 10/16 and 10/18 snapshots, but without success. I append our original e-mail containing a description of the problem and the test program. Eric **************************************************************************** To: cygwin AT cygwin DOT com Subject: bug in 1.3.3 2000/NT (probably socket()) cc: eric Date: Thu, 18 Oct 2001 15:55:29 -0400 From: Eric Mandel Content-Length: 5548 Dear Cygwin Developer(s), The appended test server program indicates a possible bug in one of the socket routines under Cygwin 1.3.3. The program creates a socket, listens for connections, accepts each connection, reads data from the connected socket, and writes that data to stdout (i.e., an echo server). The program works correctly under Cygwin 1.3.2 (NT and 2000) but not under Cygwin 1.3.3 (NT or 2000). (It also works under Solaris 5.8). Under 1.3.3, select() returns an error each time it is called: select(): bad file number Thus, no accept is ever completed and no data is read or written. However, it is unclear whether select() actually is the problem. A short program that simply performs the socket() call indicates that this latter call is destroying the heap. To see this, we debugged the short program using gdb: $ gdb -nw ./foo GNU gdb 5.0 (20010428-1) Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-cygwin"... (gdb) list 1 #include 2 #include 3 int main(int argc, char **argv) 4 { 5 int sock; 6 sock = socket(AF_INET, SOCK_STREAM, 0); 7 fprintf(stderr, "sock: %d\n"); 8 if( sock <0 ) 9 perror("socket"); 10 } (gdb) break main Breakpoint 1 at 0x40105e: file foo.c, line 4. (gdb) run Starting program: /home/joye/eric/xpa-2.1.0b5/./foo.exe Breakpoint 1, main (argc=1, argv=0xa011128) at foo.c:4 4 { (gdb) n 6 sock = socket(AF_INET, SOCK_STREAM, 0); (gdb) n warning: HEAP[foo.exe]: warning: Heap block at 0023E3F8 modified at 0023E65A past requested size of 25 Program received signal SIGTRAP, Trace/breakpoint trap. 0x77f9eeaa in ?? () (gdb) print/x 0x23e65a - 0x23e3f8 $1 = 0x262 (gdb) where #0 0x77f9eeaa in ?? () #1 0x77fcd942 in ?? () #2 0x77fb54c9 in ?? () #3 0x77fb4316 in ?? () #4 0x77fab4ab in ?? () #5 0x778834e2 in _libkernel32_a_iname () #6 0x77883019 in _libkernel32_a_iname () #7 0x77882ce7 in _libkernel32_a_iname () #8 0x77882b69 in _libkernel32_a_iname () #9 0x77f8bfcc in ?? () #10 0x77f8c618 in ?? () #11 0x77f889c0 in ?? () #12 0x77e87270 in _libkernel32_a_iname () #13 0x75033803 in _libkernel32_a_iname () #14 0x75033700 in _libkernel32_a_iname () #15 0x00000001 in ?? () (gdb) quit The program is running. Exit anyway? (y or n) y >From this evidence, it would appear that socket() might be writing 8 bytes more than it ought to into the heap. We very much would appreciate any help we can get in solving this problem -- and in turn will offer any help you might require of us in this matter. Regards, Eric Mandel /* ************************** foo.c ************************************** */ /* To compile: gcc -g -o foo foo.c (for Sun Solaris add: -lsocket) To Run: # start server window1: ./foo (waits for connect and then reads from socket and writes to stdout) # connect using telnet client in another window window2: telnet localhost 1234 (type characters and they should echo on the foo server machine) or # can also use hostname ... window2: telnet 1234 (type characters and they should echo on the foo server machine) */ #include #include #include #include #include #include #include #define SZ_BUF 1024 #define PORT 1234 #define MAXLISTEN 100 int main(int argc, char **argv) { char buf[SZ_BUF]; int got; int sock; int sock2; int width; int slen; int get=SZ_BUF-1; int reuse_addr=1; int keep_alive=1; fd_set readfds; struct sockaddr_in sock_in; struct sockaddr_in sock_in2; /* create socket */ if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){ perror("socket"); exit(1); } setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&keep_alive, sizeof(keep_alive)); memset((char *)&sock_in, 0, sizeof(sock_in)); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr, sizeof(reuse_addr)); sock_in.sin_family = AF_INET; sock_in.sin_addr.s_addr = htonl(INADDR_ANY); sock_in.sin_port = htons(PORT); /* bind to a port */ if( bind(sock, (struct sockaddr *)&sock_in, sizeof(sock_in)) < 0 ){ perror("bind()"); exit(1); } /* listen for connections */ if( listen(sock, MAXLISTEN) < 0 ){ perror("listen()"); exit(1); } /* make sure we close on exec */ fcntl(sock, F_SETFD, FD_CLOEXEC); /* init select parameters */ width = getdtablesize(); /* enter processing loop */ while( 1 ){ /* re-initialize select flags */ FD_ZERO(&readfds); FD_SET(sock, &readfds); /* wait for next request */ if( select(width, &readfds, NULL, NULL, NULL) > 0 ){ /* process request */ if( FD_ISSET(sock, &readfds) ){ slen = sizeof(struct sockaddr_in); /* accept new connection */ if( (sock2=accept(sock, (struct sockaddr *)&sock_in2, &slen)) >=0 ){ /* make sure we close on exec */ fcntl(sock2, F_SETFD, FD_CLOEXEC); /* echo to stdout */ while( (got = recv(sock2, buf, get, 0)) > 0 ) write(1, buf, got); close(sock2); } } } /* UNDER CYGWIN 1.3.3, THIS ERROR HAPPENS IMMEDIATELY */ else{ perror("select()"); exit(1); } } } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/