From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8110 invoked by alias); 3 Nov 2011 20:01:08 -0000 Received: (qmail 8062 invoked by uid 22791); 3 Nov 2011 20:01:05 -0000 X-SWARE-Spam-Status: No, hits=-7.1 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_BJ,TW_RG X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 03 Nov 2011 20:00:48 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pA3K0mU9032591 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 3 Nov 2011 16:00:48 -0400 Received: from psique (ovpn-112-40.phx2.redhat.com [10.3.112.40]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pA3K0f1e019952; Thu, 3 Nov 2011 16:00:45 -0400 From: Sergio Durigan Junior To: Jan Kratochvil Cc: gdb-patches@sourceware.org Subject: Re: [PATCH] Implement new `info core mappings' command References: <20111031001117.GA11608@host1.jankratochvil.net> <20111031070012.GA32610@host1.jankratochvil.net> Date: Thu, 03 Nov 2011 20:01:00 -0000 In-Reply-To: <20111031070012.GA32610@host1.jankratochvil.net> (Jan Kratochvil's message of "Mon, 31 Oct 2011 08:00:12 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii 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: 2011-11/txt/msg00101.txt.bz2 Hello guys, Jan Kratochvil writes: > On Mon, 31 Oct 2011 04:16:51 +0100, Sergio Durigan Junior wrote: >> > I think this function should not be based on sections at all, it should just >> > read the segments. Linux kernel does not dump any sections. bfd creates some >> > some sections from those segments (_bfd_elf_make_section_from_phdr) but they >> > cannot / do not contain any additional info, those are there IMO only for >> > better compatibility with sections-only consuming code. >> >> Just to be clear, you're saying that I should actually forget about the >> part of the code which checks inside (possible non-empty) sections in >> the corefile, and just check immediately for segments? > > Yes. Otherwise you need the tricks combining it with segments you do below > anyway, moreover you can read in sections in core file generated by gcore > which are completely useless, Ok, I have addressed all the comments in this message, plus the comments that Eli has made about the documentation bits. Now this patch implements three commands: `info core exe', `info core mappings' and `info core all'. When the corefile is ELF-compatible, and there is support for ELF compiled (HAVE_ELF), I use it to figure out information about segments (as proposed by Jan). In this case, I do not touch sections because they are useless. When the corefile is not ELF-compatible, I use the old approach: iterate over corefile sections and try to gather as much information as I can about the memory mappings. Unfortunately, I don't have a system to test this non-ELF implementation, so I'm kindly ask for someone with a Mac or Window to give it a try and see if it works. I also implemented the `exe' command by simply extracting the executable filename from the corefile BFD. I also updated the documentation to reflect this new command, along with the `all' command. This has been regtested on TestFarm, without regressions for x86{,_64,_64 w/ -m32}. How does this patch look to you? Thanks, Sergio. gdb/ChangeLog 2011-11-03 Sergio Durigan Junior 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'. gdb/doc/ChangeLog 2011-11-03 Sergio Durigan Junior Implement `info core mappings'. * gdb.texinfo: Add documentation for `info core', and to its new subcommands `mappings', `exe' and `all'. gdb/testsuite/ChangeLog 2011-11-03 Sergio Durigan Junior 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 1713049..df9e573 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,20 @@ *** 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. + +It displays the memory + regions in a corefile, similar to `info proc mappings' command. + * 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..d0897fe 100644 --- a/gdb/corefile.c +++ b/gdb/corefile.c @@ -24,17 +24,23 @@ #include #include #include +#include #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,280 @@ 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. + + BFD 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); + /* The section's size. */ + bfd_size_type size; + /* We have to know the bitness of this architecture. */ + 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 = NULL; + struct objfile *objfile = NULL; + /* Fields to be printed for the proc map. */ + bfd_vma start; + bfd_vma end = 0; + char *filename = NULL; + + 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. */ + bitness = gdbarch_addr_bit (gdbarch_from_bfd (abfd)); + + /* Retrieving the section size. */ + size = bfd_section_size (bfd, sect); + + start = sect->vma; + if (size) + 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 (!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%#10lx %#10lx %#10x %7s\n", + start, + end, + (int) size, + filename ? filename : ""); + else + printf_filtered (" %#18lx %#18lx %#10x %7s\n", + start, + end, + (int) size, + filename ? 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; + int i; + unsigned int n_segs; + Elf_Internal_Phdr *p; + + /* Bitness is important when formatting the text to be printed. */ + bitness = gdbarch_addr_bit (gdbarch_from_bfd (core_bfd)); + + 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 %7s\n", + "Start Addr", + " End Addr", + " Size", "objfile"); + else + printf_filtered (" %18s %18s %10s %7s\n", + "Start Addr", + " End Addr", + " Size", "objfile"); + + n_segs = elf_elfheader (core_bfd)->e_phnum; + + for (i = 0; i < n_segs; i++, 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 = NULL; + struct objfile *objfile = NULL; + /* Information about the segment. */ + bfd_vma start; + bfd_vma end; + bfd_vma size; + /* File associated with this memory region. */ + char *filename = NULL; + + 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 (!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%#10lx %#10lx %#10x %7s\n", + start, + end, + (int) size, + filename ? filename : ""); + else + printf_filtered (" %#18lx %#18lx %#10x %7s\n", + start, + end, + (int) size, + filename ? 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); + struct cleanup *c = NULL; + + if (!core_bfd) + error (_("You are not using a corefile at the moment.")); + + if (args) + { + /* Break up 'args' into an argv array. */ + argv = gdb_buildargv (args); + c = make_cleanup_freeargv (argv); + } + while (argv != NULL && *argv != NULL) + { + if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0) + { + mappings_f = 1; + } + argv++; + } + + if (exe_f) + info_core_print_core_exe (); + + if (mappings_f) + info_core_print_core_map (); + + if (c) + do_cleanups (c); +} + +/* 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 +729,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 93450c6..e138f5a 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -17829,6 +17829,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.debug +0x397e01e000 0x397e01f000 0x1000 /usr/lib/debug/lib/ld.so.debug +0x397e01f000 0x397e020000 0x1000 /usr/lib/debug/lib/ld.so.debug +0x397e020000 0x397e021000 0x1000 /usr/lib/debug/lib/ld.so.debug +0x397e200000 0x397e391000 0x191000 /usr/lib/debug/lib/libc.so.debug +0x397e591000 0x397e595000 0x4000 /usr/lib/debug/lib/libc.so.debug +0x397e595000 0x397e596000 0x1000 /usr/lib/debug/lib/libc.so.debug +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..ccf226f 100644 --- a/gdb/testsuite/gdb.base/corefile.exp +++ b/gdb/testsuite/gdb.base/corefile.exp @@ -171,6 +171,18 @@ 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 the `info core exe' command. +set test "test info core exe" +gdb_test "info core exe" \ + "exe = .*" + # test reinit_frame_cache gdb_load ${binfile}