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]

Re: [PATCH] Implement new `info core mappings' command


Jan Kratochvil <jan.kratochvil@redhat.com> writes:

> On Tue, 08 Nov 2011 02:48:54 +0100, Sergio Durigan Junior wrote:
>> > On Thu, 03 Nov 2011 21:00:39 +0100, Sergio Durigan Junior wrote:
>> > For ELF core files you should rather check also the ELF segments in
>> > objfiles->obfd and verify it is fully covered.
> [...]
>> This one is giving me headaches...
>
> So I understand in some corner cases without ABRT `info core mappings' may be
> useful but I no longer find too much interest in it myself and some
> approximate file suggestion may be just good enough there.  After all the
> whole information about where is which file mapped is just an approximate
> suggestion by GDB anyway.

Ok, so I would like to ask for another round of review of this patch
then.  I am aware of Ulrich's work towards a new `info mappings'
command, but since I've got no response from him yet, I decided to
continue my efforts here.

The documentation bits were already approved by Eli, and the code was
discussed a lot with Jan.  This patch causes no regression, as mentioned
earlier.  For more details, please read the whole thread.

Thanks a lot.

2011-11-16  Sergio Durigan Junior  <sergiodj@redhat.com>

	Implement `info core mappings'.
	* NEWS: Mention new `info core' command, along with its new
	subcommands `mappings', `exe' and `all'.
	* corefile.c: Include a bunch of header files needed to implement
	the `info core mappings'.
	(info_core_what): New enum.
	(info_core_print_core_exe): New function.
	(info_core_print_proc_map_non_elf): Likewise.
	(info_core_print_core_map_elf): Likewise.
	(info_core_print_core_map): Likewise.
	(info_core_cmd_1): Likewise.
	(info_core_cmd): Likewise.
	(info_core_cmd_mappings): Likewise.
	(info_core_cmd_exe): Likewise.
	(info_core_cmd_all): Likewise.
	(_initialize_core): Add new `info core' command, along with its new
	subcommands `mappings', `exe' and `all'.

2011-11-16  Sergio Durigan Junior  <sergiodj@redhat.com>

	Implement `info core mappings'.
	* gdb.texinfo: Add documentation for `info core', and to its new
	subcommands `mappings', `exe' and `all'.

2011-11-16  Sergio Durigan Junior  <sergiodj@redhat.com>

	Implement `info core mappings'.
	* gdb.base/corefile.exp: Add test for `info core', and for its new
	subcommands `mappings', `exe' and `all'.

diff --git a/gdb/NEWS b/gdb/NEWS
index c4e59c4..e649727 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,17 @@
 
 *** Changes since GDB 7.3.1
 
+* GDB has a new `info core' command, which can be used to display information
+  from a corefile.  Its subcommands are:
+
+  ** `info core mappings': display information about memory mappings
+  from the corefile.
+
+  ** `info core exe': display the executable filename that generated
+  the corefile.
+
+  ** `info core all': display all of the above.
+
 * GDB now allows you to skip uninteresting functions and files when
   stepping with the "skip function" and "skip file" commands.
 
diff --git a/gdb/corefile.c b/gdb/corefile.c
index ce3b755..9302476 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -24,17 +24,23 @@
 #include <errno.h>
 #include <signal.h>
 #include <fcntl.h>
+#include <ctype.h>
 #include "inferior.h"
 #include "symtab.h"
+#include "gdbarch.h"
+#include "arch-utils.h"
 #include "command.h"
 #include "gdbcmd.h"
 #include "bfd.h"
+#include "elf-bfd.h"
+#include "elf/internal.h"
 #include "target.h"
 #include "gdbcore.h"
 #include "dis-asm.h"
 #include "gdb_stat.h"
 #include "completer.h"
 #include "exceptions.h"
+#include "objfiles.h"
 
 /* Local function declarations.  */
 
@@ -83,6 +89,267 @@ core_file_command (char *filename, int from_tty)
 }
 
 
+/* Implement the `info core' command.  */
+
+enum info_core_what
+  {
+    /* Display the default exe output.  */
+    IC_MINIMAL,
+
+    /* Display `info core mappings'.  */
+    IC_MAPPINGS,
+
+    /* Display `info core exe'.  */
+    IC_EXE,
+
+    /* Display all of the above.  */
+    IC_ALL
+  };
+
+/* Implement `info core exe' command.  */
+
+static void
+info_core_print_core_exe (void)
+{
+  const char *exe;
+
+  /* Getting the executable name.  */
+  exe = bfd_core_file_failing_command (core_bfd);
+
+  if (exe)
+    printf_filtered (_("exe = '%s'\n"), exe);
+  else
+    warning (_("Could not obtain executable name: %s"),
+	     bfd_errmsg (bfd_get_error ()));
+}
+
+/* Helper function for `info_core_print_proc_map', used for non-ELF objects.
+
+   It is used to iterate over the corefile's BFD sections and print proper
+   information about memory-mappings.
+
+   ABFD is the bfd used to get the sections.
+   SECT is the current section being "visited".
+   OBJ is not used.  */
+
+static void
+info_core_print_proc_map_non_elf (bfd *abfd, asection *sect, void *obj)
+{
+  /* We're interested in matching sections' names beginning with
+     `load', because they are the sections containing information
+     about the process' memory regions.  */
+  static const char proc_map_match[] = "load";
+  int proc_map_match_size = strlen (proc_map_match);
+  /* We have to know the bitness of this architecture.  */
+  struct gdbarch *gdbarch;
+  int bitness;
+  /* We'll use these later.  They are basically used for iterating
+     over every objfile in the system so that we can find needed
+     information about the memory region being examinated.  */
+  struct obj_section *s;
+  struct objfile *objfile;
+  /* Fields to be printed for the proc map.  */
+  CORE_ADDR start;
+  CORE_ADDR end;
+  CORE_ADDR size;
+  char *filename = "";
+
+  if (strncmp (proc_map_match, sect->name, proc_map_match_size) != 0)
+    /* This section is not useful.  */
+    return;
+
+  /* Bitness is important for formatting the text to output.  */
+  gdbarch = gdbarch_from_bfd (abfd);
+  bitness = gdbarch_addr_bit (gdbarch);
+
+  /* Retrieving the section size.  */
+  size = bfd_section_size (bfd, sect);
+
+  start = sect->vma;
+  end = sect->vma + size;
+
+  /* Now begins a new part of the work.  We still don't have complete
+     information about the memory region.  For example, we still need
+     to know the filename which is represented by the region.  Such
+     info can be gathered from the objfile's data structure, and for
+     that we must iterate over all the objsections and check if the
+     objsection's initial address is inside the section we have at hand.
+     If it is, then we can use this specific objsection to obtain the
+     missing data.  */
+  ALL_OBJSECTIONS (objfile, s)
+    {
+      if (objfile->separate_debug_objfile_backlink)
+	continue;
+
+      if (!section_is_overlay (s) && obj_section_addr (s) >= start
+	  && obj_section_addr (s) <= end)
+	{
+	  filename = s->objfile->name;
+	  break;
+	}
+    }
+
+  if (bitness == 32)
+    printf_filtered ("\t%10s %10s %10s %s\n",
+		     paddress (gdbarch, start),
+		     paddress (gdbarch, end),
+		     paddress (gdbarch, size), filename);
+  else
+    printf_filtered ("  %18s %18s %10s %s\n",
+		     paddress (gdbarch, start),
+		     paddress (gdbarch, end),
+		     paddress (gdbarch, size), filename);
+}
+
+/* Helper function for `info_core_print_core_map' which handles objects
+   in the ELF format.  */
+
+static void
+info_core_print_core_map_elf (void)
+{
+#ifdef HAVE_ELF
+  int bitness;
+  unsigned int n_segs;
+  Elf_Internal_Phdr *p;
+  struct gdbarch *gdbarch = gdbarch_from_bfd (core_bfd);
+
+  /* Bitness is important when formatting the text to be printed.  */
+  bitness = gdbarch_addr_bit (gdbarch);
+
+  p = elf_tdata (core_bfd)->phdr;
+  if (!p)
+    error (_("Could not obtain mapped addresses."));
+
+  printf_filtered (_("Mapped address spaces:\n\n"));
+  if (bitness == 32)
+    printf_filtered ("\t%10s %10s %10s %s\n",
+		     "Start Address",
+		     "  End Address",
+		     "      Size", "objfile");
+  else
+    printf_filtered ("  %18s %18s %10s %s\n",
+		     "Start Address",
+		     "  End Address",
+		     "      Size", "objfile");
+
+  for (n_segs = elf_elfheader (core_bfd)->e_phnum;
+       n_segs > 0; n_segs--, p++)
+    {
+      /* These are basically used for iterating over every objfile in
+	 the system so that we can find needed information about the
+	 memory region being examinated.  */
+      struct obj_section *s;
+      struct objfile *objfile;
+      /* Information about the segment.  */
+      CORE_ADDR start;
+      CORE_ADDR end;
+      CORE_ADDR size;
+      /* File associated with this memory region.  */
+      char *filename = "";
+
+      if (p->p_type != PT_LOAD)
+	/* We are only interested in PT_LOAD segments.  */
+	continue;
+
+      start = p->p_vaddr;
+      size = p->p_memsz;
+      end = start + size;
+
+      ALL_OBJSECTIONS (objfile, s)
+	{
+	  if (objfile->separate_debug_objfile_backlink)
+	    continue;
+
+	  if (!section_is_overlay (s) && obj_section_addr (s) >= start
+	      && obj_section_addr (s) <= end)
+	    {
+	      filename = s->objfile->name;
+	      break;
+	    }
+	}
+
+      if (bitness == 32)
+	printf_filtered ("\t%10s %10s %10s %s\n",
+			 paddress (gdbarch, start),
+			 paddress (gdbarch, end),
+			 paddress (gdbarch, size), filename);
+      else
+	printf_filtered ("  %18s %18s %10s %s\n",
+			 paddress (gdbarch, start),
+			 paddress (gdbarch, end),
+			 paddress (gdbarch, size), filename);
+    }
+#else
+  error (_("Your system does not support ELF format."));
+#endif /* HAVE_ELF */
+}
+
+/* Implement the `info core map' command.  */
+
+static void
+info_core_print_core_map (void)
+{
+  gdb_assert (core_bfd != NULL);
+
+  if (bfd_get_flavour (core_bfd) == bfd_target_elf_flavour)
+    info_core_print_core_map_elf ();
+  else
+    bfd_map_over_sections (core_bfd,
+			   info_core_print_proc_map_non_elf,
+			   NULL);
+}
+
+/* Implement the `info core' command.  */
+
+static void
+info_core_cmd_1 (char *args, enum info_core_what what, int from_tty)
+{
+  char **argv = NULL;
+  int mappings_f = (what == IC_MAPPINGS || what == IC_ALL);
+  int exe_f = (what == IC_MINIMAL || what == IC_EXE || what == IC_ALL);
+
+  if (!core_bfd)
+    error (_("You are not using a corefile at the moment."));
+
+  if (exe_f)
+    info_core_print_core_exe ();
+
+  if (mappings_f)
+    info_core_print_core_map ();
+}
+
+/* Implement `info core' without parameters.  */
+
+static void
+info_core_cmd (char *args, int from_tty)
+{
+  info_core_cmd_1 (args, IC_MINIMAL, from_tty);
+}
+
+/* Implement `info core mappings'.  */
+
+static void
+info_core_cmd_mappings (char *args, int from_tty)
+{
+  info_core_cmd_1 (args, IC_MAPPINGS, from_tty);
+}
+
+/* Implement `info core exe'.  */
+
+static void
+info_core_cmd_exe (char *args, int from_tty)
+{
+  info_core_cmd_1 (args, IC_EXE, from_tty);
+}
+
+/* Implement `info core all'.  */
+
+static void
+info_core_cmd_all (char *args, int from_tty)
+{
+  info_core_cmd_1 (args, IC_ALL, from_tty);
+}
+
 /* If there are two or more functions that wish to hook into
    exec_file_command, this function will call all of the hook
    functions.  */
@@ -449,6 +716,26 @@ void
 _initialize_core (void)
 {
   struct cmd_list_element *c;
+  static struct cmd_list_element *info_core_cmdlist;
+
+  add_prefix_cmd ("core", class_info, info_core_cmd,
+		  _("\
+Show information about a corefile.\n\
+The command uses the corefile loaded."),
+		  &info_core_cmdlist, "info core ",
+		  1/*allow-unknown*/, &infolist);
+
+  add_cmd ("mappings", class_info, info_core_cmd_mappings, _("\
+List of mapped memory regions."),
+	   &info_core_cmdlist);
+
+  add_cmd ("exe", class_info, info_core_cmd_exe, _("\
+List absolute filename for executable which generated the corefile."),
+	   &info_core_cmdlist);
+
+  add_cmd ("all", class_info, info_core_cmd_all, _("\
+List all available corefile information."),
+	   &info_core_cmdlist);
 
   c = add_cmd ("core-file", class_files, core_file_command, _("\
 Use FILE as core dump for examining memory and registers.\n\
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index f4f7f1e..eb2bdc8 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17885,6 +17885,62 @@ processes and all the threads within each process.
 For QNX Neutrino only, this command displays the list of all mapinfos.
 @end table
 
+@node Process Information from Core Dump File
+@subsection Process Information from Core Dump File
+@cindex examine core dump file process information
+@cindex process info via core dump file
+
+If your system supports the generation of core dump files (core files), you
+can use them to obtain information about processes.  For that, you can use
+the command @code{info core} inside @value{GDBN} to report information like
+the memory mappings of the process when the core dump was generated.
+@code{info core} works only on systems that support core dump files, and only
+when you are using a core dump file inside @value{GDBN}.
+
+@xref{Core File Generation}, for information on how to generate core dump
+files inside @value{GDBN}.  @xref{Files}, for information on invoking
+@value{GDBN} in the post-mortem debugging mode.
+
+@table @code
+@kindex info core
+@cindex core dump file, process information
+@item info core
+@itemx info core mappings
+@cindex memory address space mappings inside a core dump file
+Report the memory address ranges accessible in the core dump file.  Assuming
+you have a core dump file and it is loaded into @value{GDBN}, the output of
+the command will be similar to:
+
+@smallexample
+(@value{GDBP}) info core mappings
+Mapped address spaces:
+
+  Start Addr      End Addr      Size objfile
+    0x400000      0x401000    0x1000 /tmp/a.out
+    0x600000      0x601000    0x1000 /tmp/a.out
+0x397de00000  0x397de1f000   0x1f000 /usr/lib/debug/lib/ld.so
+0x397e01e000  0x397e01f000    0x1000 /usr/lib/debug/lib/ld.so
+0x397e01f000  0x397e020000    0x1000 /usr/lib/debug/lib/ld.so
+0x397e020000  0x397e021000    0x1000 /usr/lib/debug/lib/ld.so
+0x397e200000  0x397e391000  0x191000 /usr/lib/debug/lib/libc.so
+0x397e591000  0x397e595000    0x4000 /usr/lib/debug/lib/libc.so
+0x397e595000  0x397e596000    0x1000 /usr/lib/debug/lib/libc.so
+0x397e596000  0x397e59c000    0x6000
+@end smallexample
+
+@item info core exe
+Show the filename of the process that generated this core dump file.
+
+@smallexample
+(@value{GDBP}) info core exe
+exe = '/tmp/a.out'
+@end smallexample
+
+@item info core all
+Show all the information about the core dump file described under all of
+the above @code{info core} subcommands.
+@end table
+
 @node DJGPP Native
 @subsection Features for Debugging @sc{djgpp} Programs
 @cindex @sc{djgpp} debugging
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
index 5b0cdf1..364a018 100644
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -171,6 +171,13 @@ gdb_test_multiple "x/8bd buf2" "$test" {
     }
 }
 
+# Test the `info core mappings' command.
+set ws "\[ \t\]+"
+set test "test info core mappings"
+gdb_test "info core mappings" \
+	"Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}.*" \
+	$test
+
 # test reinit_frame_cache
 
 gdb_load ${binfile}


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