Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Fix reading solaris cores generated with gdb's own gcore.
@ 2009-10-09  0:58 Pedro Alves
  2009-10-09  1:01 ` Pedro Alves
  0 siblings, 1 reply; 2+ messages in thread
From: Pedro Alves @ 2009-10-09  0:58 UTC (permalink / raw)
  To: gdb-patches

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  <pedro@codesourcery.com>

	* 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));
     }


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Fix reading solaris cores generated with gdb's own gcore.
  2009-10-09  0:58 Fix reading solaris cores generated with gdb's own gcore Pedro Alves
@ 2009-10-09  1:01 ` Pedro Alves
  0 siblings, 0 replies; 2+ messages in thread
From: Pedro Alves @ 2009-10-09  1:01 UTC (permalink / raw)
  To: gdb-patches

Whooops, a typo sneaked in.  Fixed with this followup patch.

-- 
Pedro Alves

	* corelow.c (add_to_thread_list): Fix typo.

---
 gdb/corelow.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c	2009-10-09 01:57:27.000000000 +0100
+++ src/gdb/corelow.c	2009-10-09 01:57:41.000000000 +0100
@@ -260,7 +260,7 @@ add_to_thread_list (bfd *abfd, asection 
       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
+	 find a NT_PSTATUS note in the core, but do find NT_LWPSTATUS
 	 notes.  */
       if (pid == 0)
 	{


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-10-09  1:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-09  0:58 Fix reading solaris cores generated with gdb's own gcore Pedro Alves
2009-10-09  1:01 ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox