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]

[commit] core file lwp/pid encoding on solaris


Something I noticed while doing some across-all-targets changes.

Solaris encodes the pid of the cored inferior in regset section names,
like so:

 [LWPID << 16 | PID]

See:

 pedro@opensolaris:~/orlando/gdb/baseline/build-solaris/gdb$ objdump -h ./core
 
 ./core:     file format elf32-i386

 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
   0 note0         0000087c  00000000  00000000  000002d4  2**0
                   CONTENTS, READONLY
   1 .reg/145693   0000004c  00000000  00000000  00000564  2**2
      ^^^^^^^^^^
                   CONTENTS
   2 .reg          0000004c  00000000  00000000  00000564  2**2
                   CONTENTS
   3 .reg2/145693  0000017c  00000000  00000000  000005c4  2**2
      ^^^^^^^^^^^
                   CONTENTS
   4 .reg2         0000017c  00000000  00000000  000005c4  2**2
                   CONTENTS
   5 .reg/80157    0000004c  00000000  00000000  000008b8  2**2
      ^^^^^^^^^^
                   CONTENTS
   6 .reg2/80157   0000017c  00000000  00000000  00000918  2**2
      ^^^^^^^^^^
 (...)

The patch below teaches gdbarch.sh, the solaris tdep files, and corelow.c
about systems that do this.  I've chosen a gdbarch setting instead of
tweaking sol-thread.c:solaris_pid_to_str, because, first, I'm going
to clean up sol-thread.c, after which, there will be no
"solaris-core" target anymore.  Second, this patch is just a UI tweak
for now, but is actually necessary to be able to debug threaded
core files.  Third, this way works for cross-core debugging as well.

I had started out with gdbarch callbacks to do ptid_t <-> regset section
name conversion, but in the end, I considered that a boolean setting
would be better and simpler for now.  We can do something else if
we ever find a system that does more complicated ".reg/XXX" section
name decoding.

>From the user's perpective, with the core from the objdump listing above,
"info threads" output changes from this:

 (gdb) info threads
   2 LWP    80157          thread_function (arg=0x0) at ../../../src/gdb/testsuite/gdb.threads/schedlock.c:59
 * 1 LWP    145693          0xfee910c0 in _thr_setup () from /lib/libc.so.1
 (gdb)

To this:

 (gdb) info threads
   2 LWP    1          thread_function (arg=0x0) at ../../../src/gdb/testsuite/gdb.threads/schedlock.c:59
 * 1 LWP    2          0xfee910c0 in _thr_setup () from /lib/libc.so.1
 (gdb) info inferiors
 * 1 14621

That is, it looks just like it was when the inferior was a live
process, not a core dump.

FYI, dbx also doesn't expose that encoded lwpid to the user:

 (dbx) threads
 o>    t@1  a  l@1   ?()   signal SIGSEGV in  main()
 (dbx) lwps
 o>l@1 signal SIGSEGV in main()

(that's thread 1 and lwp 1 in dbx's lingo)
(note, that was a core from a different app)

"gcore" on solaris, through procfs.c:procfs_do_thread_registers
is already being compatible with what the kernel produces, by
also generating this encoding.

I needed to move the post_create_inferior call to after
adding the threads, as deep in post_create_inferior there
may be are register reads that would fail otherwise, due to reading
off of an inferior ptid.

Also no regressions on x86_64-linux.  I've also smoke tested debugging
threaded and non-threaded cores on i386-openbsd4.3, to confirm that
core files without ".reg/XXX" sections, only ".reg", still load
fine into gdb.

Checked in.

-- 
Pedro Alves


2009-02-16  Pedro Alves  <pedro@codesourcery.com>

	* corelow.c (core_close): Don't hardcode the core's pid.
	(core_open): Find core threads before calling
	post_create_inferior.
	(add_to_thread_list, get_core_register_section): Take into account
	systems where the regset section names encode the pid of the
	inferior.

	* gdbarch.sh (core_reg_section_encodes_pid): New gdbarch setting.
	* gdbarch.h, gdbarch.c: Regenerate.

	* amd64-sol2-tdep.c (amd64_sol2_init_abi): Set it.
	* i386-sol2-tdep.c (i386_sol2_init_abi): Set it.
	* sparc-sol2-tdep.c (sparc32_sol2_init_abi): Set it.
	* sparc64-sol2-tdep.c (sparc64_sol2_init_abi): Set it.

---
 gdb/amd64-sol2-tdep.c   |    4 ++++
 gdb/corelow.c           |   32 +++++++++++++++++++++++++-------
 gdb/gdbarch.c           |   23 +++++++++++++++++++++++
 gdb/gdbarch.h           |   11 ++++++++++-
 gdb/gdbarch.sh          |    7 +++++++
 gdb/i386-sol2-tdep.c    |    4 ++++
 gdb/sparc-sol2-tdep.c   |    4 ++++
 gdb/sparc64-sol2-tdep.c |    4 ++++
 8 files changed, 81 insertions(+), 8 deletions(-)

Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c	2009-02-16 00:23:30.000000000 +0000
+++ src/gdb/corelow.c	2009-02-16 03:02:45.000000000 +0000
@@ -199,8 +199,9 @@ core_close (int quitting)
 
   if (core_bfd)
     {
+      int pid = ptid_get_pid (inferior_ptid);
       inferior_ptid = null_ptid;	/* Avoid confusion from thread stuff */
-      delete_inferior_silent (CORELOW_PID);
+      delete_inferior_silent (pid);
 
       /* Clear out solib state while the bfd is still open. See
          comments in clear_solib in solib.c. */
@@ -244,7 +245,15 @@ add_to_thread_list (bfd *abfd, asection 
 
   thread_id = atoi (bfd_section_name (abfd, asect) + 5);
 
-  ptid = ptid_build (ptid_get_pid (inferior_ptid), thread_id, 0);
+  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);
+    }
+  else
+    ptid = ptid_build (ptid_get_pid (inferior_ptid), thread_id, 0);
 
   if (ptid_get_lwp (inferior_ptid) == 0)
     /* The main thread has already been added before getting here, and
@@ -374,16 +383,14 @@ core_open (char *filename, int from_tty)
      from ST to MT.  */
   add_thread_silent (inferior_ptid);
 
-  /* This is done first, before anything has a chance to query the
-     inferior for information such as symbols.  */
-  post_create_inferior (&core_ops, from_tty);
-
   /* Build up thread list from BFD sections, and possibly set the
      current thread to the .reg/NN section matching the .reg
      section. */
   bfd_map_over_sections (core_bfd, add_to_thread_list,
 			 bfd_get_section_by_name (core_bfd, ".reg"));
 
+  post_create_inferior (&core_ops, from_tty);
+
   /* Now go through the target stack looking for threads since there
      may be a thread_stratum target loaded on top of target core by
      now.  The layer above should claim threads found in the BFD
@@ -453,7 +460,18 @@ get_core_register_section (struct regcac
   char *contents;
 
   xfree (section_name);
-  if (ptid_get_lwp (inferior_ptid))
+
+  if (core_gdbarch
+      && gdbarch_core_reg_section_encodes_pid (core_gdbarch))
+    {
+      uint32_t merged_pid;
+
+      merged_pid = ptid_get_lwp (inferior_ptid);
+      merged_pid = merged_pid << 16 | ptid_get_pid (inferior_ptid);
+
+      section_name = xstrprintf ("%s/%s", name, plongest (merged_pid));
+    }
+  else if (ptid_get_lwp (inferior_ptid))
     section_name = xstrprintf ("%s/%ld", name, ptid_get_lwp (inferior_ptid));
   else
     section_name = xstrdup (name);
Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh	2009-02-16 00:23:30.000000000 +0000
+++ src/gdb/gdbarch.sh	2009-02-16 03:03:40.000000000 +0000
@@ -600,6 +600,13 @@ F:CORE_ADDR:fetch_pointer_argument:struc
 # name SECT_NAME and size SECT_SIZE.
 M:const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size
 
+# When creating core dumps, some systems encode the PID in addition
+# to the LWP id in core file register section names.  In those cases, the
+# "XXX" in ".reg/XXX" is encoded as [LWPID << 16 | PID].  This setting
+# is set to true for such architectures; false if "XXX" represents an LWP
+# or thread id with no special encoding.
+v:int:core_reg_section_encodes_pid:::0:0::0
+
 # Supported register notes in a core file.
 v:struct core_regset_section *:core_regset_sections:const char *name, int len::::::host_address_to_string (gdbarch->core_regset_sections)
 
Index: src/gdb/amd64-sol2-tdep.c
===================================================================
--- src.orig/gdb/amd64-sol2-tdep.c	2009-02-16 00:24:03.000000000 +0000
+++ src/gdb/amd64-sol2-tdep.c	2009-02-16 01:19:25.000000000 +0000
@@ -113,6 +113,10 @@ amd64_sol2_init_abi (struct gdbarch_info
   set_gdbarch_skip_solib_resolver (gdbarch, sol2_skip_solib_resolver);
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_lp64_fetch_link_map_offsets);
+
+  /* Solaris encodes the pid of the inferior in regset section
+     names.  */
+  set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
 }
 
 
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c	2009-02-16 00:24:35.000000000 +0000
+++ src/gdb/gdbarch.c	2009-02-16 03:04:11.000000000 +0000
@@ -223,6 +223,7 @@ struct gdbarch
   gdbarch_register_reggroup_p_ftype *register_reggroup_p;
   gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument;
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
+  int core_reg_section_encodes_pid;
   struct core_regset_section * core_regset_sections;
   gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
   int vtable_function_descriptors;
@@ -356,6 +357,7 @@ struct gdbarch startup_gdbarch =
   default_register_reggroup_p,  /* register_reggroup_p */
   0,  /* fetch_pointer_argument */
   0,  /* regset_from_core_section */
+  0,  /* core_reg_section_encodes_pid */
   0,  /* core_regset_sections */
   0,  /* core_xfer_shared_libraries */
   0,  /* vtable_function_descriptors */
@@ -609,6 +611,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of register_reggroup_p, invalid_p == 0 */
   /* Skip verify of fetch_pointer_argument, has predicate */
   /* Skip verify of regset_from_core_section, has predicate */
+  /* Skip verify of core_reg_section_encodes_pid, invalid_p == 0 */
   /* Skip verify of core_xfer_shared_libraries, has predicate */
   /* Skip verify of vtable_function_descriptors, invalid_p == 0 */
   /* Skip verify of vbit_in_delta, invalid_p == 0 */
@@ -736,6 +739,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: core_read_description = <%s>\n",
                       host_address_to_string (gdbarch->core_read_description));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: core_reg_section_encodes_pid = %s\n",
+                      plongest (gdbarch->core_reg_section_encodes_pid));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: core_regset_sections = %s\n",
                       host_address_to_string (gdbarch->core_regset_sections));
   fprintf_unfiltered (file,
@@ -2899,6 +2905,23 @@ set_gdbarch_regset_from_core_section (st
   gdbarch->regset_from_core_section = regset_from_core_section;
 }
 
+int
+gdbarch_core_reg_section_encodes_pid (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  /* Skip verify of core_reg_section_encodes_pid, invalid_p == 0 */
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_core_reg_section_encodes_pid called\n");
+  return gdbarch->core_reg_section_encodes_pid;
+}
+
+void
+set_gdbarch_core_reg_section_encodes_pid (struct gdbarch *gdbarch,
+                                          int core_reg_section_encodes_pid)
+{
+  gdbarch->core_reg_section_encodes_pid = core_reg_section_encodes_pid;
+}
+
 struct core_regset_section *
 gdbarch_core_regset_sections (struct gdbarch *gdbarch)
 {
Index: src/gdb/gdbarch.h
===================================================================
--- src.orig/gdb/gdbarch.h	2009-02-16 00:24:31.000000000 +0000
+++ src/gdb/gdbarch.h	2009-02-16 03:04:01.000000000 +0000
@@ -638,6 +638,15 @@ typedef const struct regset * (gdbarch_r
 extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size);
 extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section);
 
+/* When creating core dumps, some systems encode the PID in addition
+   to the LWP id in core file register section names.  In those cases, the
+   "XXX" in ".reg/XXX" is encoded as [LWPID << 16 | PID].  This setting
+   is set to true for such architectures; false if "XXX" represents an LWP
+   or thread id with no special encoding. */
+
+extern int gdbarch_core_reg_section_encodes_pid (struct gdbarch *gdbarch);
+extern void set_gdbarch_core_reg_section_encodes_pid (struct gdbarch *gdbarch, int core_reg_section_encodes_pid);
+
 /* Supported register notes in a core file. */
 
 extern struct core_regset_section * gdbarch_core_regset_sections (struct gdbarch *gdbarch);
@@ -804,7 +813,7 @@ extern int gdbarch_target_signal_to_host
 extern void set_gdbarch_target_signal_to_host (struct gdbarch *gdbarch, gdbarch_target_signal_to_host_ftype *target_signal_to_host);
 
 /* Extra signal info inspection.
-
+  
    Return a type suitable to inspect extra signal information. */
 
 extern int gdbarch_get_siginfo_type_p (struct gdbarch *gdbarch);
Index: src/gdb/i386-sol2-tdep.c
===================================================================
--- src.orig/gdb/i386-sol2-tdep.c	2009-02-16 00:24:24.000000000 +0000
+++ src/gdb/i386-sol2-tdep.c	2009-02-16 01:17:48.000000000 +0000
@@ -135,6 +135,10 @@ i386_sol2_init_abi (struct gdbarch_info 
   set_gdbarch_skip_solib_resolver (gdbarch, sol2_skip_solib_resolver);
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  /* Solaris encodes the pid of the inferior in regset section
+     names.  */
+  set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
 }
 
 
Index: src/gdb/sparc-sol2-tdep.c
===================================================================
--- src.orig/gdb/sparc-sol2-tdep.c	2009-02-16 00:24:10.000000000 +0000
+++ src/gdb/sparc-sol2-tdep.c	2009-02-16 01:19:38.000000000 +0000
@@ -231,6 +231,10 @@ sparc32_sol2_init_abi (struct gdbarch_in
   set_gdbarch_software_single_step (gdbarch, NULL);
 
   frame_unwind_append_unwinder (gdbarch, &sparc32_sol2_sigtramp_frame_unwind);
+
+  /* Solaris encodes the pid of the inferior in regset section
+     names.  */
+  set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
 }
 
 
Index: src/gdb/sparc64-sol2-tdep.c
===================================================================
--- src.orig/gdb/sparc64-sol2-tdep.c	2009-02-16 00:24:07.000000000 +0000
+++ src/gdb/sparc64-sol2-tdep.c	2009-02-16 01:19:52.000000000 +0000
@@ -180,6 +180,10 @@ sparc64_sol2_init_abi (struct gdbarch_in
 
   /* Solaris has kernel-assisted single-stepping support.  */
   set_gdbarch_software_single_step (gdbarch, NULL);
+
+  /* Solaris encodes the pid of the inferior in regset section
+     names.  */
+  set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
 }
 
 



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