From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28453 invoked by alias); 9 Oct 2009 00:58:33 -0000 Received: (qmail 28437 invoked by uid 22791); 9 Oct 2009 00:58:32 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Oct 2009 00:58:26 +0000 Received: (qmail 24720 invoked from network); 9 Oct 2009 00:58:24 -0000 Received: from unknown (HELO orlando) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 9 Oct 2009 00:58:24 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: Fix reading solaris cores generated with gdb's own gcore. Date: Fri, 09 Oct 2009 00:58:00 -0000 User-Agent: KMail/1.9.10 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200910090156.40778.pedro@codesourcery.com> X-IsSubscribed: yes 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: 2009-10/txt/msg00186.txt.bz2 Currently, gdb's own gcore isn't putting any NT_PSTATUS note on solaris core files, unlike /usr/bin/gcore. This note is where the pid the process had is found. Reading these core files back is tripping on a pid != 0 assertion on solib-svr4.c. This makes gdb cope with such core files again, and takes the opportunity to do things a tiny bit differently to avoid the need for the thread_change_ptid call. This fixed half a dozen or so gcore related failures on sparc solaris, and had no testresult changes on x86_64-linux-gnu. Applied to mainline. -- Pedro Alves 2009-10-09 Pedro Alves * corelow.c (core_has_fake_pid): New. (core_close): Clear it. (add_to_thread_list): Fake a pid if one is not found on a Solaris core. Add the inferior here. Always add the thread, don't use thread_change_ptid. (core_open): Don't add the main thread or the inferior here unless we find that the core had no .reg/NN sections. (get_core_register_section): Handle Solaris cores with fake pids. --- gdb/corelow.c | 80 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 24 deletions(-) Index: src/gdb/corelow.c =================================================================== --- src.orig/gdb/corelow.c 2009-10-07 19:21:20.000000000 +0100 +++ src/gdb/corelow.c 2009-10-08 00:38:30.000000000 +0100 @@ -75,6 +75,9 @@ struct gdbarch *core_gdbarch = NULL; unix child targets. */ static struct target_section_table *core_data; +/* True if we needed to fake the pid of the loaded core inferior. */ +static int core_has_fake_pid = 0; + static void core_files_info (struct target_ops *); static struct core_fns *sniff_core_bfd (bfd *); @@ -214,6 +217,7 @@ core_close (int quitting) xfree (core_data->sections); xfree (core_data); core_data = NULL; + core_has_fake_pid = 0; name = bfd_get_filename (core_bfd); if (!bfd_close (core_bfd)) @@ -239,32 +243,44 @@ static void add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg) { ptid_t ptid; - int thread_id; + int core_tid; + int pid, lwpid; asection *reg_sect = (asection *) reg_sect_arg; if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0) return; - thread_id = atoi (bfd_section_name (abfd, asect) + 5); + core_tid = atoi (bfd_section_name (abfd, asect) + 5); if (core_gdbarch && gdbarch_core_reg_section_encodes_pid (core_gdbarch)) { - uint32_t merged_pid = thread_id; - ptid = ptid_build (merged_pid & 0xffff, - merged_pid >> 16, 0); + uint32_t merged_pid = core_tid; + pid = merged_pid & 0xffff; + lwpid = merged_pid >> 16; + + /* This can happen on solaris core, for example, if we don't + find a NT_PRSTATUS note in the core, but do find NT_LWPSTATUS + notes. */ + if (pid == 0) + { + core_has_fake_pid = 1; + pid = CORELOW_PID; + } } else - ptid = ptid_build (ptid_get_pid (inferior_ptid), thread_id, 0); + { + core_has_fake_pid = 1; + pid = CORELOW_PID; + lwpid = core_tid; + } - if (ptid_get_lwp (inferior_ptid) == 0) - /* The main thread has already been added before getting here, and - this is the first time we hear about a thread id. Assume this - is the main thread. */ - thread_change_ptid (inferior_ptid, ptid); - else - /* Nope, really a new thread. */ - add_thread (ptid); + if (!in_inferior_list (pid)) + add_inferior_silent (pid); + + ptid = ptid_build (pid, lwpid, 0); + + add_thread (ptid); /* Warning, Will Robinson, looking at BFD private data! */ @@ -371,21 +387,14 @@ core_open (char *filename, int from_tty) push_target (&core_ops); discard_cleanups (old_chain); - add_inferior_silent (corelow_pid); - /* Do this before acknowledging the inferior, so if post_create_inferior throws (can happen easilly if you're loading a core file with the wrong exec), we aren't left with threads from the previous inferior. */ init_thread_list (); - /* Set INFERIOR_PTID early, so an upper layer can rely on it being - set while in the target_find_new_threads call below. */ - inferior_ptid = pid_to_ptid (corelow_pid); - - /* Assume ST --- Add a main task. We'll later detect when we go - from ST to MT. */ - add_thread_silent (inferior_ptid); + inferior_ptid = null_ptid; + core_has_fake_pid = 0; /* Need to flush the register cache (and the frame cache) from a previous debug session. If inferior_ptid ends up the same as the @@ -401,6 +410,25 @@ core_open (char *filename, int from_tty) bfd_map_over_sections (core_bfd, add_to_thread_list, bfd_get_section_by_name (core_bfd, ".reg")); + if (ptid_equal (inferior_ptid, null_ptid)) + { + /* Either we found no .reg/NN section, and hence we have a + non-threaded core (single-threaded, from gdb's perspective), + or for some reason add_to_thread_list couldn't determine + which was the "main" thread. The latter case shouldn't + usually happen, but we're dealing with input here, which can + always be broken in different ways. */ + struct thread_info *thread = first_thread_of_process (-1); + if (thread == NULL) + { + add_inferior_silent (CORELOW_PID); + inferior_ptid = pid_to_ptid (CORELOW_PID); + add_thread_silent (inferior_ptid); + } + else + switch_to_thread (thread->ptid); + } + post_create_inferior (&core_ops, from_tty); /* Now go through the target stack looking for threads since there @@ -496,9 +524,13 @@ get_core_register_section (struct regcac && gdbarch_core_reg_section_encodes_pid (core_gdbarch)) { uint32_t merged_pid; + int pid = ptid_get_pid (inferior_ptid); + + if (core_has_fake_pid) + pid = 0; merged_pid = ptid_get_lwp (inferior_ptid); - merged_pid = merged_pid << 16 | ptid_get_pid (inferior_ptid); + merged_pid = merged_pid << 16 | pid; section_name = xstrprintf ("%s/%s", name, plongest (merged_pid)); }