This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
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}