From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27296 invoked by alias); 19 Apr 2002 07:45:54 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 27256 invoked from network); 19 Apr 2002 07:45:48 -0000 Received: from unknown (HELO violet.setuza.cz) (194.149.118.97) by sources.redhat.com with SMTP; 19 Apr 2002 07:45:48 -0000 Received: from ADMIN.satuza.cz (ADMIN.setuza.cz [2.2.2.21]) by violet.setuza.cz (Postfix) with ESMTP id 2F59873D11 for ; Fri, 19 Apr 2002 07:45:48 +0000 (UTC) Subject: Problems debugging forked processes From: Frank Schaefer To: gdb@sources.redhat.com Content-Type: multipart/mixed; boundary="=-BoND4oHXJj7R9x/lQphR" Date: Fri, 19 Apr 2002 00:45:00 -0000 Message-Id: <1019202349.3213.5.camel@ADMIN> Mime-Version: 1.0 X-SW-Source: 2002-04/txt/msg00326.txt.bz2 --=-BoND4oHXJj7R9x/lQphR Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 1869 Hi there, I've written a network daemon and client. The daemon forks to serve a client request. Everything runs fine outside of the debugger, but I want to trace the code at least once, before I release it. Here goes my problem: # gdb daemon GNU gdb 5.0 Copyright 2000 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-linux-gnu"... (gdb) b 13 Breakpoint 1 at 0x8048899: file daemon.c, line 13. (gdb) show follow-fork-mode Debugger response to a program call of fork or vfork is "parent". (gdb) set follow-fork-mode child (gdb) show follow-fork-mode Debugger response to a program call of fork or vfork is "child". (gdb) run Starting program: /v_dsk/home/p10209/Tests/daemon Breakpoint 1, main () at syncboot.c:15 15 int On = 1; (gdb) n ... (gdb) n 67 ChildPid = fork(); (gdb) n 69 sleep( 10 ); (gdb) print ChildPid $1 = 3700 So it seems, I'm tracing the parent process - don't it? The same happens, If I do: (gdb) set follow-fork-mode ask instead of child. I'm not asked anything and remain debugging the parent. If I use the attach method from a second instance of gdb ( there's the sleep() above for ), the child process exits on exceptions ( mostly segmentation fault and sometimes invalid operation ) on different (random???) lines in the code. This happens everytime in the fixup() from ld.linux.so. I'm using gdb 5.0, my compiler is gcc 2.95.3 on a glibc-2.2.4 linux-2.4.16 system. I have Binutils 2.11 installed. Furtheron I've attached reduced versions of the code, for which the fault still occurs. Any suggestions? Regards Frank --=-BoND4oHXJj7R9x/lQphR Content-Disposition: attachment; filename=daemon.c Content-Transfer-Encoding: quoted-printable Content-Type: text/x-c; charset=ISO-8859-1 Content-length: 2779 #include #include #include #include #include #include #include #include #define PORT 1023 const char MESSAGE[] =3D "Hi there!\n"; int main( void ) { int SrvSocket, ChildPid; int On =3D 1; struct linger Linger =3D { 0 }; char Hostname[80]; struct hostent *pHostEnt =3D NULL; struct sockaddr_in ServerName =3D { 0 }; SrvSocket =3D socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); if( SrvSocket =3D=3D -1 ) { perror( "Can't create socket!\n" ); exit( 1 ); } if( setsockopt( SrvSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&On, s= izeof( On ) ) ) { perror( "Can't set reuse address on socket!\n" ); exit( 1 ); } Linger.l_onoff =3D 1; Linger.l_linger =3D 20; if( setsockopt( SrvSocket, SOL_SOCKET, SO_LINGER, (const char*)&Linger, = sizeof( Linger ) ) ) { perror( "Can't set lingering for socket!\n" ); exit( 1 ); } if( gethostname( Hostname, sizeof( Hostname ) ) ) { perror( " Can't get my own hostname!\n" ); exit( 1 ); } pHostEnt =3D gethostbyname( Hostname ); if( ! pHostEnt ) { perror( "Can't get hostentry!\n" ); exit( 1 ); } memset( &ServerName, 0, sizeof( ServerName ) ); memcpy( &ServerName.sin_addr, pHostEnt->h_addr, pHostEnt->h_length ); ServerName.sin_family =3D AF_INET; ServerName.sin_port =3D htons( PORT ); if( bind( SrvSocket, (struct sockaddr*)&ServerName, sizeof( ServerName )= ) ) { perror( "Can't bind socket!\n" ); exit( 1 ); } if( listen(SrvSocket, BACKLOG ) ) { perror( "Can't listen on socket!\n" ); exit( 1 ); } while( 1 ) { struct sockaddr_in ClientName; int SlaveSocket, ClientLength =3D sizeof( ClientName ); memset( &ClientName, 0, sizeof( ClientName ) ); SlaveSocket =3D accept( SrvSocket, (struct sockaddr*)&ClientName, &Cl= ientLength ); if( SlaveSocket =3D=3D -1 ) { perror( "Can't accept connection!\n" ); exit( 1 ); } ChildPid =3D fork(); sleep( 10 ); switch( ChildPid ) { case -1: perror( "Can't fork!\n" ); exit( 1 ); case 0: close( SrvSocket ); if( getpeername( SlaveSocket, (struct sockaddr*)&ClientName, &C= lientLength )) { perror( "Can't get peername!\n" ); } else { printf( "Connection request from %s\n", inet_ntoa( ClientNam= e.sin_addr) ); } write( SlaveSocket, MESSAGE, strlen( MESSAGE ) ); close( SlaveSocket ); exit( 0 ); default: close( SlaveSocket ); } } exit( 0 ); } --=-BoND4oHXJj7R9x/lQphR Content-Disposition: attachment; filename=client.c Content-Transfer-Encoding: quoted-printable Content-Type: text/x-c; charset=ISO-8859-1 Content-length: 1441 #include "syncboot.h" #include #include #include #include #include #include #include #include #include #include int main( int argc, char* argv[] ) { int CltSocket, Status =3D 0; char *RemHost =3D NULL; char *ProgName =3D basename( argv[0] ); char Buff[256] =3D ""; struct hostent *pHostEnt; struct sockaddr_in SrvName; RemHost =3D argv[1]; CltSocket =3D socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); if( CltSocket =3D=3D -1 ) { perror( "Can't create socket!\n" ); exit( 1 ); } pHostEnt =3D gethostbyname( RemHost ); if( ! pHostEnt ) { pHostEnt =3D gethostbyaddr( RemHost, strlen( RemHost ), AF_INET ); } if( ! pHostEnt ) { fprintf( stderr,"%s: Couldn't resolve remote host %s", ProgName, RemH= ost ); exit( 1 ); } SrvName.sin_family =3D AF_INET; SrvName.sin_port =3D htons( PORT ); memcpy( &SrvName.sin_addr, pHostEnt->h_addr, pHostEnt->h_length ); Status =3D connect( CltSocket, (struct sockaddr*)&SrvName, sizeof( SrvNa= me ) ); if( Status =3D=3D -1 ) { perror( "Can't connect!\n" ); exit( 1 ); } while( ( Status =3D read( CltSocket, Buff, sizeof( Buff) -1 ) ) > 0 ) { printf( "%d : %s\n", Status, Buff ); } if( Status =3D=3D -1 ){ perror( "Read error!\n" ); } close( CltSocket ); exit( 0 ); } --=-BoND4oHXJj7R9x/lQphR--