The program below forks a child which calls gethostbyname.  When using gdb
to debug it, the child seg faults in _dl_debug_state while calling
gethostbyname (run normally, it functions properly).  See the comments
below for more information.

Thanks,
David

[This may actually be a glibc bug, so CC'd to bug-gcc.  Not submitted to
Debian since it was also reproduced on a non-Debian build of gdb.]



/**

   This program forks a child which calls gethostbyname.  When using
   gdb to debug it, the child seg faults in _dl_debug_state while
   calling gethostbyname.

   I have:
     Linux 2.2.14
     glibc 2.1.3
     gdb 19990928 (Debian build)

   This problem has been verified on another machine with Linux
   2.2.14, glibc 2.1.2, and GDB 4.18.


   To compile:

     gcc -o test -g test.c

   To duplicate bug:

     gdb test
       > set args localhost     [or some other domainname]
       > run
       [child will now dump core]
       > core core

       Symbols already loaded for /lib/libc.so.6
       Symbols already loaded for /lib/ld-linux.so.2
       Reading symbols from /lib/libnss_files.so.2...done.

       > bt
       #0  0x4000a41d in _dl_debug_state () from /lib/ld-linux.so.2
       #1  0x4000a125 in _dl_catch_error () from /lib/ld-linux.so.2
       #2  0x400de4d0 in _dl_open () from /lib/libc.so.6
       #3  0x400c2959 in __nss_configure_lookup () from /lib/libc.so.6
       #4  0x4000a125 in _dl_catch_error () from /lib/ld-linux.so.2
       #5  0x400c2911 in __nss_configure_lookup () from /lib/libc.so.6
       #6  0x400c2cf8 in __nss_configure_lookup () from /lib/libc.so.6
       #7  0x400c2737 in __nss_database_lookup () from /lib/libc.so.6
       #8  0x400c376f in __nss_hosts_lookup () from /lib/libc.so.6
       #9  0x400c5d44 in gethostbyname_r () from /lib/libc.so.6
       #10 0x400c4d82 in gethostbyname () from /lib/libc.so.6
       #11 0x8048895 in gnet_gethostbyname (hostname=0xbffffa36
"junglemonkey.net", 
         sa=0xbffff800) at test.c:176


 */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <dlfcn.h>

#include <arpa/nameser.h>
#include <resolv.h>
#include <netdb.h>


int
main(int argc, char** argv)
{
  pid_t pid;

  if (argc != 2)
    {
      printf ("usage: %s <hostname>\n", argv[0]);
      exit (EXIT_FAILURE);
    }

  /* Fork to do DNS look up. */
 fork_again:
  if ((pid = fork()) == 0)
    {
      struct hostent* he;

#if 0   /* This will also cause a seg fault.  Compile with -ldl. */
      if (!dlopen ("/lib/libnss_files.so.2", RTLD_NOW))
        perror ("dlopen");
#endif


#if 0   /* This WON'T cause a seg fault.  Compile with -ldl. */
      if (!dlopen ("/lib/libm.so.6", RTLD_NOW))
        perror ("dlopen");
#endif


      he = gethostbyname(argv[1]);
      /* Core dumped.  This line not reached. */

      _exit(EXIT_SUCCESS);
    }

  /* Read from the pipe */
  else if (pid > 0)
    {
      /* Wait */
      if (waitpid (pid, NULL, 0) == -1)
        perror ("waitpid");
    }

  /* Try again */
  else if (errno == EAGAIN)
    {
      sleep(0); /* Yield the processor */
      goto fork_again;
    }

  /* Else there was an error */
  else
    {
      perror ("fork");
    }

  exit (EXIT_SUCCESS);
  return 0;
}


Reply via email to