From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21232 invoked by alias); 26 Oct 2011 21:08:13 -0000 Received: (qmail 21219 invoked by uid 22791); 26 Oct 2011 21:08:11 -0000 X-SWARE-Spam-Status: No, hits=-6.7 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; Wed, 26 Oct 2011 21:07:50 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9QL7nsN020866 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 26 Oct 2011 17:07:49 -0400 Received: from psique (ovpn-112-22.phx2.redhat.com [10.3.112.22]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p9QL7jbB003456 for ; Wed, 26 Oct 2011 17:07:47 -0400 From: Sergio Durigan Junior To: gdb-patches@sourceware.org Subject: Re: [PATCH] Implement new `info core mappings' command References: Date: Wed, 26 Oct 2011 21:25:00 -0000 In-Reply-To: (Sergio Durigan Junior's message of "Wed, 26 Oct 2011 18:49:53 -0200") 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-10/txt/msg00708.txt.bz2 Sergio Durigan Junior writes: > Hello there, I have a theory that you only see errors in your patch when it's already on the mailing list. > diff --git a/gdb/NEWS b/gdb/NEWS > index 5cdb63e..6f8feaa 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -3,6 +3,9 @@ > > *** Changes since GDB 7.3.1 > > +* GDB has a new `info core mappings' command. It displays the memory > + regions in a corefile, similar to `info pro mappings' command. ^^^ Typo. > +static void > +info_core_cmd (char *args, int from_tty) > +{ > + char **argv = NULL; > + int mappings_f = 1; > + int all = 0; > + > + 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); > + make_cleanup_freeargv (argv); > + } > + while (argv != NULL && *argv != NULL) > + { > + if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0) > + { > + mappings_f = 1; > + } > + else if (strncmp (argv[0], "all", strlen (argv[0])) == 0) > + { > + all = 1; > + } > + argv++; > + } > + > + if (mappings_f || all) > + print_core_map (); Forgot to free `argv'. Please, consider this new patch. Thanks, Sergio. diff --git a/gdb/NEWS b/gdb/NEWS index 5cdb63e..d04fbe6 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,9 @@ *** Changes since GDB 7.3.1 +* GDB has a new `info core mappings' command. It displays the memory + regions in a corefile, similar to `info proc mappings' command. + * GDB has two new commands: "set remote hardware-watchpoint-length-limit" and "show remote hardware-watchpoint-length-limit". These allows to set or show the maximum length limit (in bytes) of a remote diff --git a/gdb/corefile.c b/gdb/corefile.c index ce3b755..ab3c6bb 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,189 @@ core_file_command (char *filename, int from_tty) } +/* Helper function for `print_core_map'. It is used to iterate + over the corefile's 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 +print_proc_map_iter (bfd *bfd, 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); + /* Flag to indicate whether we have found something. */ + int found = 0; + /* The section's size. */ + bfd_size_type secsize; + /* 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. */ + unsigned long start = 0, end = 0; + unsigned int size = 0; + char *filename = NULL; + + if (strncmp (proc_map_match, sect->name, proc_map_match_size) != 0) + /* This section is not useful. */ + return; + + bitness = gdbarch_addr_bit (gdbarch_from_bfd (bfd)); + + /* Unfortunately, some sections in the corefile don't have any + content inside. This is bad because we need to print, among + other things, its final address in the memory (which is + impossible to know if we don't have a size). That's why we + first need to check if the section's got anything inside it. */ + secsize = bfd_section_size (bfd, sect); + + if (secsize == 0) + { + /* Ok, the section is empty. In this case, we must look inside + ELF's Program Header, because (at least) there we have + information about the section's size. That's what we're doing + here. */ + Elf_Internal_Phdr *p = elf_tdata (bfd)->phdr; + if (p != NULL) + { + int i; + unsigned int n = elf_elfheader (bfd)->e_phnum; + for (i = 0; i < n; i++, p++) + /* For each entry in the Program Header, we have to + check if the section's initial address is equal to + the entry's virtual address. If it is, then we + have just found the section's entry in the Program + Header, and can use the entry's information to + complete missing data from the section. */ + if (sect->vma == p->p_vaddr) + { + found = 1; + break; + } + if (found) + secsize = p->p_memsz; + } + } + + size = secsize; + start = sect->vma; + end = (unsigned long) (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. */ + found = 0; + ALL_OBJSECTIONS (objfile, s) + if (obj_section_addr (s) >= start + && obj_section_addr (s) <= end) + { + found = 1; + break; + } + + if (found) + filename = s->objfile->name; + + 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 : ""); +} + +/* Implements the `info proc map' command when the user has provided + a corefile. */ + +static void +print_core_map (void) +{ + const char *exe; + int bitness; + + gdb_assert (core_bfd != NULL); + + bitness = gdbarch_addr_bit (gdbarch_from_bfd (core_bfd)); + + /* Getting the executable name. */ + exe = bfd_core_file_failing_command (core_bfd); + + printf_filtered (_("exe = '%s'\n"), exe); + 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"); + + bfd_map_over_sections (core_bfd, + print_proc_map_iter, + NULL); +} + +/* Implement the `info core' command. */ + +static void +info_core_cmd (char *args, int from_tty) +{ + char **argv = NULL; + int mappings_f = 1; + int all = 0; + struct cleanup *c; + + 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; + } + else if (strncmp (argv[0], "all", strlen (argv[0])) == 0) + { + all = 1; + } + argv++; + } + + if (mappings_f || all) + print_core_map (); + + do_cleanups (c); +} + /* If there are two or more functions that wish to hook into exec_file_command, this function will call all of the hook functions. */ @@ -450,6 +639,11 @@ _initialize_core (void) { struct cmd_list_element *c; + add_info ("core", info_core_cmd, _("\ +Show information about a corefile.\n\ +Specify any of the following keywords for detailed info:\n\ + mappings -- list of mapped memory regions.")); + c = add_cmd ("core-file", class_files, core_file_command, _("\ Use FILE as core dump for examining memory and registers.\n\ No arg means have no core file. This command has been superseded by the\n\ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index b451a6a..92e06f3 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -17655,6 +17655,13 @@ value; etc. For more information, see the @samp{proc} man page Show all the information about the process described under all of the above @code{info proc} subcommands. +@kindex info core +@cindex core dump file +@item info core +@item info core mappings +@cindex memory address space mappings +Report the memory address space ranges accessible in the core file. + @ignore @comment These sub-options of 'info proc' were not included when @comment procfs.c was re-written. Keep their descriptions around diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp index 5b0cdf1..190281c 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 mapping' command. +set ws "\[ \t\]+" +set test "test info core mapping" +gdb_test "info core mapping" \ + ".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}.*" \ + $test + # test reinit_frame_cache gdb_load ${binfile}