From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16858 invoked by alias); 19 Oct 2009 20:12:58 -0000 Received: (qmail 16850 invoked by uid 22791); 19 Oct 2009 20:12:56 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from smtp-outbound-2.vmware.com (HELO smtp-outbound-2.vmware.com) (65.115.85.73) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 19 Oct 2009 20:12:51 +0000 Received: from mailhost2.vmware.com (mailhost2.vmware.com [10.16.67.167]) by smtp-outbound-2.vmware.com (Postfix) with ESMTP id 48E4711051; Mon, 19 Oct 2009 13:12:50 -0700 (PDT) Received: from [10.20.94.141] (msnyder-server.eng.vmware.com [10.20.94.141]) by mailhost2.vmware.com (Postfix) with ESMTP id 136398E8F3; Mon, 19 Oct 2009 13:12:50 -0700 (PDT) Message-ID: <4ADCC6D2.9000406@vmware.com> Date: Mon, 19 Oct 2009 20:12:00 -0000 From: Michael Snyder User-Agent: Thunderbird 1.5.0.12 (X11/20080411) MIME-Version: 1.0 To: "tromey@redhat.com" CC: "gdb-patches@sourceware.org" , Hui Zhu , Eli Zaretskii Subject: Re: [RFA, 5 of 3] save/restore process record, part 5 (gcore change) References: <4ADA9558.2010202@vmware.com> In-Reply-To: Content-Type: multipart/mixed; boundary="------------080405010200010007050401" 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: 2009-10/txt/msg00453.txt.bz2 This is a multi-part message in MIME format. --------------080405010200010007050401 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 800 Tom Tromey wrote: >>>>>> "Michael" == Michael Snyder writes: > > Michael> +/* create_gcore_bfd -- helper for gcore_command (exported). */ > > Michael> +bfd * > Michael> +create_gcore_bfd (char *filename) > > That comment is not very descriptive. > > Michael> +/* write_gcore_file -- helper for gcore_command (exported). */ > Michael> + > Michael> +void > Michael> +write_gcore_file (bfd *obfd) > > Likewise. > > Michael> Index: gcore.h > Michael> =================================================================== > Michael> RCS file: gcore.h > Michael> diff -N gcore.h > > The gdb internals document says that headers should have include guards. OK. Also, I found that I had included some code in this patch that I didn't need -- so this version is shorter. ;-) --------------080405010200010007050401 Content-Type: text/plain; name="gcorepb.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="gcorepb.txt" Content-length: 8874 2009-10-17 Michael Snyder * gcore.h: New file. * gcore.c (create_gcore_bfd): New function. (write_gcore_file): New function. (call_target_sbrk): New function. Abstracted from gcore_command. (gcore_command): Call call_target_sbrk. Index: gcore.h =================================================================== RCS file: gcore.h diff -N gcore.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcore.h 19 Oct 2009 20:11:24 -0000 @@ -0,0 +1,27 @@ +/* Support for reading/writing gcore files. + + Copyright (C) 2009, Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#if !defined (GCORE_H) +#define GCORE_H 1 + +extern bfd *create_gcore_bfd (char *filename); +extern void write_gcore_file (bfd *obfd); +extern bfd *load_corefile (char *filename, int from_tty); + +#endif /* GCORE_H */ Index: gcore.c =================================================================== RCS file: /cvs/src/src/gdb/gcore.c,v retrieving revision 1.34 diff -u -p -r1.34 gcore.c --- gcore.c 2 Jul 2009 17:21:06 -0000 1.34 +++ gcore.c 19 Oct 2009 20:11:24 -0000 @@ -25,10 +25,14 @@ #include "gdbcore.h" #include "objfiles.h" #include "symfile.h" - +#include "arch-utils.h" +#include "completer.h" +#include "gcore.h" #include "cli/cli-decode.h" - #include "gdb_assert.h" +#include +#include "regcache.h" +#include "regset.h" /* The largest amount of memory to read from the target at once. We must throttle it to limit the amount of memory used by GDB during @@ -40,45 +44,30 @@ static enum bfd_architecture default_gco static unsigned long default_gcore_mach (void); static int gcore_memory_sections (bfd *); -/* Generate a core file from the inferior process. */ +/* create_gcore_bfd -- helper for gcore_command (exported). + Open a new bfd core file for output, and return the handle. */ -static void -gcore_command (char *args, int from_tty) +bfd * +create_gcore_bfd (char *filename) { - struct cleanup *old_chain; - char *corefilename, corefilename_buffer[40]; - asection *note_sec = NULL; - bfd *obfd; - void *note_data = NULL; - int note_size = 0; - - /* No use generating a corefile without a target process. */ - if (!target_has_execution) - noprocess (); - - if (args && *args) - corefilename = args; - else - { - /* Default corefile name is "core.PID". */ - sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid)); - corefilename = corefilename_buffer; - } - - if (info_verbose) - fprintf_filtered (gdb_stdout, - "Opening corefile '%s' for output.\n", corefilename); - - /* Open the output file. */ - obfd = bfd_openw (corefilename, default_gcore_target ()); + bfd *obfd = bfd_openw (filename, default_gcore_target ()); if (!obfd) - error (_("Failed to open '%s' for output."), corefilename); - - /* Need a cleanup that will close the file (FIXME: delete it?). */ - old_chain = make_cleanup_bfd_close (obfd); - + error (_("Failed to open '%s' for output."), filename); bfd_set_format (obfd, bfd_core); bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ()); + return obfd; +} + +/* write_gcore_file -- helper for gcore_command (exported). + Compose and write the corefile data to the core file. */ + + +void +write_gcore_file (bfd *obfd) +{ + void *note_data = NULL; + int note_size = 0; + asection *note_sec = NULL; /* An external target method must build the notes section. */ note_data = target_make_corefile_notes (obfd, ¬e_size); @@ -107,9 +96,47 @@ gcore_command (char *args, int from_tty) if (note_data != NULL && note_size != 0) { if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size)) - warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ())); + warning (_("writing note section (%s)"), + bfd_errmsg (bfd_get_error ())); + } +} + +/* gcore_command -- implements the 'gcore' command. + Generate a core file from the inferior process. */ + +static void +gcore_command (char *args, int from_tty) +{ + struct cleanup *old_chain; + char *corefilename, corefilename_buffer[40]; + bfd *obfd; + + /* No use generating a corefile without a target process. */ + if (!target_has_execution) + noprocess (); + + if (args && *args) + corefilename = args; + else + { + /* Default corefile name is "core.PID". */ + sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid)); + corefilename = corefilename_buffer; } + if (info_verbose) + fprintf_filtered (gdb_stdout, + "Opening corefile '%s' for output.\n", corefilename); + + /* Open the output file. */ + obfd = create_gcore_bfd (corefilename); + + /* Need a cleanup that will close the file (FIXME: delete it?). */ + old_chain = make_cleanup_bfd_close (obfd); + + /* Call worker function. */ + write_gcore_file (obfd); + /* Succeeded. */ fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename); @@ -212,6 +239,50 @@ derive_stack_segment (bfd_vma *bottom, b return 1; } +/* call_target_sbrk -- + helper function for derive_heap_segment. */ + +static bfd_vma +call_target_sbrk (int sbrk_arg) +{ + struct objfile *sbrk_objf; + struct gdbarch *gdbarch; + bfd_vma top_of_heap; + struct value *target_sbrk_arg; + struct value *sbrk_fn, *ret; + bfd_vma tmp; + + if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL) + { + sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf); + if (sbrk_fn == NULL) + return (bfd_vma) 0; + } + else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL) + { + sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf); + if (sbrk_fn == NULL) + return (bfd_vma) 0; + } + else + return (bfd_vma) 0; + + gdbarch = get_objfile_arch (sbrk_objf); + target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, + sbrk_arg); + gdb_assert (target_sbrk_arg); + ret = call_function_by_hand (sbrk_fn, 1, &target_sbrk_arg); + if (ret == NULL) + return (bfd_vma) 0; + + tmp = value_as_long (ret); + if ((LONGEST) tmp <= 0 || (LONGEST) tmp == 0xffffffff) + return (bfd_vma) 0; + + top_of_heap = tmp; + return top_of_heap; +} + /* Derive a reasonable heap segment for ABFD by looking at sbrk and the static data sections. Store its limits in *BOTTOM and *TOP. Return non-zero if successful. */ @@ -219,12 +290,10 @@ derive_stack_segment (bfd_vma *bottom, b static int derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) { - struct objfile *sbrk_objf; struct gdbarch *gdbarch; bfd_vma top_of_data_memory = 0; bfd_vma top_of_heap = 0; bfd_size_type sec_size; - struct value *zero, *sbrk; bfd_vma sec_vaddr; asection *sec; @@ -259,29 +328,9 @@ derive_heap_segment (bfd *abfd, bfd_vma } } - /* Now get the top-of-heap by calling sbrk in the inferior. */ - if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL) - { - sbrk = find_function_in_inferior ("sbrk", &sbrk_objf); - if (sbrk == NULL) - return 0; - } - else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL) - { - sbrk = find_function_in_inferior ("_sbrk", &sbrk_objf); - if (sbrk == NULL) - return 0; - } - else - return 0; - - gdbarch = get_objfile_arch (sbrk_objf); - zero = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); - gdb_assert (zero); - sbrk = call_function_by_hand (sbrk, 1, &zero); - if (sbrk == NULL) + top_of_heap = call_target_sbrk (0); + if (top_of_heap == (bfd_vma) 0) return 0; - top_of_heap = value_as_long (sbrk); /* Return results. */ if (top_of_heap > top_of_data_memory) @@ -299,13 +348,15 @@ static void make_output_phdrs (bfd *obfd, asection *osec, void *ignored) { int p_flags = 0; - int p_type; + int p_type = 0; /* FIXME: these constants may only be applicable for ELF. */ if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0) p_type = PT_LOAD; - else + else if (strncmp (bfd_section_name (obfd, osec), "note", 4) == 0) p_type = PT_NOTE; + else + p_type = PT_NULL; p_flags |= PF_R; /* Segment is readable. */ if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY)) --------------080405010200010007050401--