This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] - Patch for 32-bit x86 corefiles read by 64 bit gdb


On an x86_64 linux system, if you compile and run the following program to generate a core file:

    main ()
    {
        abort ();
    }

and try to load it into gdb, you get:

    GNU gdb 6.5.50.20060923-cvs
    Copyright (C) 2006 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 "x86_64-unknown-linux-gnu"...
    Using host libthread_db library "/lib64/libthread_db.so.1".
    
    warning: Can't read pathname for load map: Input/output error.
    Reading symbols from /lib/libc.so.6...done.
    Loaded symbols for /lib/libc.so.6
    Reading symbols from /lib/ld-linux.so.2...done.
    Loaded symbols for /lib/ld-linux.so.2
    
    warning: Lowest section in system-supplied DSO at 0xffffe000 is .hash at ffffe0b4
    Core was generated by `./abort32'.
    Program terminated with signal 6, Aborted.
    #0  0xffffe405 in __kernel_vsyscall ()
    (gdb) 
    

Notice the warning:

    warning: Can't read pathname for load map: Input/output error.

The problem here is that there is an extra shared object referenced in
the dynamic linker's list, for which the actual name string is located
in the address space of one of the other two libraries that haven't
been loaded yet.  So gdb doesn't know how to find the name string.  It
gives I/O error as it's generic response to being asked to read an
unmapped address.

Interestingly, once you've loaded libc and ld-linux.so, you can access
that address, but there is a null string there.  The address is also
the same address as the first entry in the list, which is for the
main program, and is skipped during the building of gdb's internal
list of shared objects.

I've not dug far enough to know what this extra unnamed object is.
But is seems intuitive that if it has the same address for the name
string as the first (skipped) object, it should probably be skipped
also.

Here's a patch that does that.

Comments (and enlightenment about that extra object) would be 
appreciated.

-Fred

Index: solib-svr4.c
===================================================================
RCS file: /services/cvs/cvsroot/latest/gdb/gdb/solib-svr4.c,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 solib-svr4.c
--- solib-svr4.c	19 May 2006 20:13:12 -0000	1.1.1.6
+++ solib-svr4.c	5 Mar 2007 17:51:27 -0000
@@ -679,6 +679,7 @@ svr4_current_sos (void)
   struct so_list *head = 0;
   struct so_list **link_ptr = &head;
   CORE_ADDR ldsomap = 0;
+  CORE_ADDR ignore_name_addr = 0;
 
   /* Make sure we've looked up the inferior's dynamic linker's base
      structure.  */
@@ -700,6 +701,7 @@ svr4_current_sos (void)
       struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
       struct so_list *new = XZALLOC (struct so_list);
       struct cleanup *old_chain = make_cleanup (xfree, new);
+      CORE_ADDR name_addr;
 
       new->lm_info = xmalloc (sizeof (struct lm_info));
       make_cleanup (xfree, new->lm_info);
@@ -716,9 +718,23 @@ svr4_current_sos (void)
          inferior executable, so we must ignore it.  For some versions of
          SVR4, it has no name.  For others (Solaris 2.3 for example), it
          does have a name, so we can no longer use a missing name to
-         decide when to ignore it. */
+         decide when to ignore it.  Corefiles for 32 bit linux executables
+	 produced by 64 bit kernels contain a second entry that has the
+	 same name as the first, so ignore that also.  The name is actually
+	 found in the dynamic linker, which may not have been loaded yet,
+	 and attempting to read it will produce an I/O error. */
+
+      name_addr = LM_NAME (new);
       if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0)
-	free_so (new);
+	{
+	  ignore_name_addr = name_addr;
+	  free_so (new);
+	}
+      else if (name_addr == ignore_name_addr)
+	{
+	  /* Found a second entry with same name as ignored first entry */
+	  free_so (new);
+	}
       else
 	{
 	  int errcode;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]