From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20643 invoked by alias); 5 Mar 2007 17:53:47 -0000 Received: (qmail 20632 invoked by uid 22791); 5 Mar 2007 17:53:46 -0000 X-Spam-Check-By: sourceware.org Received: from w099.z064220152.sjc-ca.dsl.cnc.net (HELO bluesmobile.specifix.com) (64.220.152.99) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 05 Mar 2007 17:53:35 +0000 Received: from fishpond.diveadx.com (bluesmobile.corp.specifix.com [192.168.1.32]) by bluesmobile.specifix.com (Postfix) with ESMTP id 5DD1B3B8D1; Mon, 5 Mar 2007 09:53:28 -0800 (PST) From: Fred Fish Reply-To: fnf@specifix.com To: gdb-patches@sources.redhat.com Subject: [RFC] - Patch for 32-bit x86 corefiles read by 64 bit gdb Date: Mon, 05 Mar 2007 17:53:00 -0000 User-Agent: KMail/1.9.6 Cc: fnf@specifix.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200703051053.25514.fnf@specifix.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-03/txt/msg00041.txt.bz2 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;