mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-01 06:25:50 +00:00
gdb
* NEWS: Mention "info proc" and core files. * corelow.c (core_info_proc): New function. (init_core_ops): Set to_info_proc. * gdbarch.c, gdbarch.h: Rebuild. * gdbarch.sh (core_info_proc): New method. * infcmd.c (info_proc_cmd_1): Invoke target_info_proc first. * linux-tdep.c (linux_core_info_proc_mappings) (linux_core_info_proc): New functions. (linux_find_memory_region_ftype): New typedef. (linux_find_memory_regions_full): New function, from linux_find_memory_regions. (struct linux_find_memory_regions_data): New. (linux_find_memory_regions_thunk): New function. (linux_find_memory_regions): Rewrite. (struct linux_make_mappings_data): New. (linux_make_mappings_callback) (linux_make_mappings_corefile_notes): New functions. (linux_make_corefile_notes): Call linux_make_mappings_corefile_notes. (linux_init_abi): Call set_gdbarch_core_info_proc. * target.c (target_info_proc): Return 'int'. * target.h (target_info_proc): Update. gdb/doc * gdb.texinfo (SVR4 Process Information): Mention core files. gdb/testsuite * gdb.base/info-proc.exp: Add core file tests. bfd * elf.c (elfcore_grok_note) <NT_FILE>: New case.
This commit is contained in:
parent
83a2341852
commit
451b7c33cb
@ -1,3 +1,7 @@
|
||||
2012-12-14 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* elf.c (elfcore_grok_note) <NT_FILE>: New case.
|
||||
|
||||
2012-12-13 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/14956
|
||||
|
@ -8626,6 +8626,10 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case NT_FILE:
|
||||
return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
|
||||
note);
|
||||
|
||||
case NT_SIGINFO:
|
||||
return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
|
||||
note);
|
||||
|
@ -1,3 +1,27 @@
|
||||
2012-12-14 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* NEWS: Mention "info proc" and core files.
|
||||
* corelow.c (core_info_proc): New function.
|
||||
(init_core_ops): Set to_info_proc.
|
||||
* gdbarch.c, gdbarch.h: Rebuild.
|
||||
* gdbarch.sh (core_info_proc): New method.
|
||||
* infcmd.c (info_proc_cmd_1): Invoke target_info_proc first.
|
||||
* linux-tdep.c (linux_core_info_proc_mappings)
|
||||
(linux_core_info_proc): New functions.
|
||||
(linux_find_memory_region_ftype): New typedef.
|
||||
(linux_find_memory_regions_full): New function, from
|
||||
linux_find_memory_regions.
|
||||
(struct linux_find_memory_regions_data): New.
|
||||
(linux_find_memory_regions_thunk): New function.
|
||||
(linux_find_memory_regions): Rewrite.
|
||||
(struct linux_make_mappings_data): New.
|
||||
(linux_make_mappings_callback)
|
||||
(linux_make_mappings_corefile_notes): New functions.
|
||||
(linux_make_corefile_notes): Call linux_make_mappings_corefile_notes.
|
||||
(linux_init_abi): Call set_gdbarch_core_info_proc.
|
||||
* target.c (target_info_proc): Return 'int'.
|
||||
* target.h (target_info_proc): Update.
|
||||
|
||||
2012-12-14 Pierre Muller <muller@sourceware.org>
|
||||
|
||||
* windows-nat.c (windows_xfer_shared_libraries): Avoid
|
||||
|
2
gdb/NEWS
2
gdb/NEWS
@ -18,6 +18,8 @@
|
||||
* The 'ptype' and 'whatis' commands now accept an argument to control
|
||||
type formatting.
|
||||
|
||||
* 'info proc' now works on some core files.
|
||||
|
||||
* Python scripting
|
||||
|
||||
** Vectors can be created with gdb.Type.vector.
|
||||
|
@ -927,6 +927,19 @@ core_has_registers (struct target_ops *ops)
|
||||
return (core_bfd != NULL);
|
||||
}
|
||||
|
||||
/* Implement the to_info_proc method. */
|
||||
|
||||
static void
|
||||
core_info_proc (struct target_ops *ops, char *args, enum info_proc_what request)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_current_arch ();
|
||||
|
||||
/* Since this is the core file target, call the 'core_info_proc'
|
||||
method on gdbarch, not 'info_proc'. */
|
||||
if (gdbarch_core_info_proc_p (gdbarch))
|
||||
gdbarch_core_info_proc (gdbarch, args, request);
|
||||
}
|
||||
|
||||
/* Fill in core_ops with its defined operations and properties. */
|
||||
|
||||
static void
|
||||
@ -953,6 +966,7 @@ init_core_ops (void)
|
||||
core_ops.to_has_memory = core_has_memory;
|
||||
core_ops.to_has_stack = core_has_stack;
|
||||
core_ops.to_has_registers = core_has_registers;
|
||||
core_ops.to_info_proc = core_info_proc;
|
||||
core_ops.to_magic = OPS_MAGIC;
|
||||
|
||||
if (core_target)
|
||||
|
@ -1,3 +1,7 @@
|
||||
2012-12-14 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.texinfo (SVR4 Process Information): Mention core files.
|
||||
|
||||
2012-12-12 Mircea Gherzan <mircea.gherzan@intel.com>
|
||||
|
||||
* gdb.texinfo (GDB/MI Catchpoint Commands): New section.
|
||||
|
@ -18649,13 +18649,17 @@ modern FreeBSD systems.
|
||||
|
||||
Many versions of SVR4 and compatible systems provide a facility called
|
||||
@samp{/proc} that can be used to examine the image of a running
|
||||
process using file-system subroutines. If @value{GDBN} is configured
|
||||
for an operating system with this facility, the command @code{info
|
||||
proc} is available to report information about the process running
|
||||
your program, or about any process running on your system. @code{info
|
||||
proc} works only on SVR4 systems that include the @code{procfs} code.
|
||||
This includes, as of this writing, @sc{gnu}/Linux, OSF/1 (Digital
|
||||
Unix), Solaris, Irix, but not HP-UX, for example.
|
||||
process using file-system subroutines.
|
||||
|
||||
If @value{GDBN} is configured for an operating system with this
|
||||
facility, the command @code{info proc} is available to report
|
||||
information about the process running your program, or about any
|
||||
process running on your system. This includes, as of this writing,
|
||||
@sc{gnu}/Linux, OSF/1 (Digital Unix), Solaris, and Irix, but
|
||||
not HP-UX, for example.
|
||||
|
||||
This command may also work on core files that were created on a system
|
||||
that has the @samp{/proc} facility.
|
||||
|
||||
@table @code
|
||||
@kindex info proc
|
||||
|
@ -283,6 +283,7 @@ struct gdbarch
|
||||
int has_dos_based_file_system;
|
||||
gdbarch_gen_return_address_ftype *gen_return_address;
|
||||
gdbarch_info_proc_ftype *info_proc;
|
||||
gdbarch_core_info_proc_ftype *core_info_proc;
|
||||
gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order;
|
||||
};
|
||||
|
||||
@ -451,6 +452,7 @@ struct gdbarch startup_gdbarch =
|
||||
0, /* has_dos_based_file_system */
|
||||
default_gen_return_address, /* gen_return_address */
|
||||
0, /* info_proc */
|
||||
0, /* core_info_proc */
|
||||
default_iterate_over_objfiles_in_search_order, /* iterate_over_objfiles_in_search_order */
|
||||
/* startup_gdbarch() */
|
||||
};
|
||||
@ -750,6 +752,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of has_dos_based_file_system, invalid_p == 0 */
|
||||
/* Skip verify of gen_return_address, invalid_p == 0 */
|
||||
/* Skip verify of info_proc, has predicate. */
|
||||
/* Skip verify of core_info_proc, has predicate. */
|
||||
/* Skip verify of iterate_over_objfiles_in_search_order, invalid_p == 0 */
|
||||
buf = ui_file_xstrdup (log, &length);
|
||||
make_cleanup (xfree, buf);
|
||||
@ -867,6 +870,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: convert_register_p = <%s>\n",
|
||||
host_address_to_string (gdbarch->convert_register_p));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: gdbarch_core_info_proc_p() = %d\n",
|
||||
gdbarch_core_info_proc_p (gdbarch));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: core_info_proc = <%s>\n",
|
||||
host_address_to_string (gdbarch->core_info_proc));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: gdbarch_core_pid_to_str_p() = %d\n",
|
||||
gdbarch_core_pid_to_str_p (gdbarch));
|
||||
@ -4250,6 +4259,30 @@ set_gdbarch_info_proc (struct gdbarch *gdbarch,
|
||||
gdbarch->info_proc = info_proc;
|
||||
}
|
||||
|
||||
int
|
||||
gdbarch_core_info_proc_p (struct gdbarch *gdbarch)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
return gdbarch->core_info_proc != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gdbarch_core_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
gdb_assert (gdbarch->core_info_proc != NULL);
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_core_info_proc called\n");
|
||||
gdbarch->core_info_proc (gdbarch, args, what);
|
||||
}
|
||||
|
||||
void
|
||||
set_gdbarch_core_info_proc (struct gdbarch *gdbarch,
|
||||
gdbarch_core_info_proc_ftype core_info_proc)
|
||||
{
|
||||
gdbarch->core_info_proc = core_info_proc;
|
||||
}
|
||||
|
||||
void
|
||||
gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile)
|
||||
{
|
||||
|
@ -1193,6 +1193,16 @@ typedef void (gdbarch_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enu
|
||||
extern void gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
|
||||
extern void set_gdbarch_info_proc (struct gdbarch *gdbarch, gdbarch_info_proc_ftype *info_proc);
|
||||
|
||||
/* Implement the "info proc" command for core files. Noe that there
|
||||
are two "info_proc"-like methods on gdbarch -- one for core files,
|
||||
one for live targets. */
|
||||
|
||||
extern int gdbarch_core_info_proc_p (struct gdbarch *gdbarch);
|
||||
|
||||
typedef void (gdbarch_core_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
|
||||
extern void gdbarch_core_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
|
||||
extern void set_gdbarch_core_info_proc (struct gdbarch *gdbarch, gdbarch_core_info_proc_ftype *core_info_proc);
|
||||
|
||||
/* Iterate over all objfiles in the order that makes the most sense
|
||||
for the architecture to make global symbol searches.
|
||||
|
||||
|
@ -943,6 +943,11 @@ m:void:gen_return_address:struct agent_expr *ax, struct axs_value *value, CORE_A
|
||||
# Implement the "info proc" command.
|
||||
M:void:info_proc:char *args, enum info_proc_what what:args, what
|
||||
|
||||
# Implement the "info proc" command for core files. Noe that there
|
||||
# are two "info_proc"-like methods on gdbarch -- one for core files,
|
||||
# one for live targets.
|
||||
M:void:core_info_proc:char *args, enum info_proc_what what:args, what
|
||||
|
||||
# Iterate over all objfiles in the order that makes the most sense
|
||||
# for the architecture to make global symbol searches.
|
||||
#
|
||||
|
11
gdb/infcmd.c
11
gdb/infcmd.c
@ -2883,10 +2883,13 @@ info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_current_arch ();
|
||||
|
||||
if (gdbarch_info_proc_p (gdbarch))
|
||||
gdbarch_info_proc (gdbarch, args, what);
|
||||
else
|
||||
target_info_proc (args, what);
|
||||
if (!target_info_proc (args, what))
|
||||
{
|
||||
if (gdbarch_info_proc_p (gdbarch))
|
||||
gdbarch_info_proc (gdbarch, args, what);
|
||||
else
|
||||
error (_("Not supported on this target."));
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement `info proc' when given without any futher parameters. */
|
||||
|
303
gdb/linux-tdep.c
303
gdb/linux-tdep.c
@ -30,6 +30,8 @@
|
||||
#include "elf-bfd.h" /* for elfcore_write_* */
|
||||
#include "inferior.h"
|
||||
#include "cli/cli-utils.h"
|
||||
#include "arch-utils.h"
|
||||
#include "gdb_obstack.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@ -533,11 +535,149 @@ linux_info_proc (struct gdbarch *gdbarch, char *args,
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement "info proc mappings" for a corefile. */
|
||||
|
||||
static void
|
||||
linux_core_info_proc_mappings (struct gdbarch *gdbarch, char *args)
|
||||
{
|
||||
asection *section;
|
||||
ULONGEST count, page_size;
|
||||
unsigned char *descdata, *filenames, *descend, *contents;
|
||||
size_t note_size;
|
||||
unsigned int addr_size_bits, addr_size;
|
||||
struct cleanup *cleanup;
|
||||
struct gdbarch *core_gdbarch = gdbarch_from_bfd (core_bfd);
|
||||
/* We assume this for reading 64-bit core files. */
|
||||
gdb_static_assert (sizeof (ULONGEST) >= 8);
|
||||
|
||||
section = bfd_get_section_by_name (core_bfd, ".note.linuxcore.file");
|
||||
if (section == NULL)
|
||||
{
|
||||
warning (_("unable to find mappings in core file"));
|
||||
return;
|
||||
}
|
||||
|
||||
addr_size_bits = gdbarch_addr_bit (core_gdbarch);
|
||||
addr_size = addr_size_bits / 8;
|
||||
note_size = bfd_get_section_size (section);
|
||||
|
||||
if (note_size < 2 * addr_size)
|
||||
error (_("malformed core note - too short for header"));
|
||||
|
||||
contents = xmalloc (note_size);
|
||||
cleanup = make_cleanup (xfree, contents);
|
||||
if (!bfd_get_section_contents (core_bfd, section, contents, 0, note_size))
|
||||
error (_("could not get core note contents"));
|
||||
|
||||
descdata = contents;
|
||||
descend = descdata + note_size;
|
||||
|
||||
if (descdata[note_size - 1] != '\0')
|
||||
error (_("malformed note - does not end with \\0"));
|
||||
|
||||
count = bfd_get (addr_size_bits, core_bfd, descdata);
|
||||
descdata += addr_size;
|
||||
|
||||
page_size = bfd_get (addr_size_bits, core_bfd, descdata);
|
||||
descdata += addr_size;
|
||||
|
||||
if (note_size < 2 * addr_size + count * 3 * addr_size)
|
||||
error (_("malformed note - too short for supplied file count"));
|
||||
|
||||
printf_filtered (_("Mapped address spaces:\n\n"));
|
||||
if (gdbarch_addr_bit (gdbarch) == 32)
|
||||
{
|
||||
printf_filtered ("\t%10s %10s %10s %10s %s\n",
|
||||
"Start Addr",
|
||||
" End Addr",
|
||||
" Size", " Offset", "objfile");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf_filtered (" %18s %18s %10s %10s %s\n",
|
||||
"Start Addr",
|
||||
" End Addr",
|
||||
" Size", " Offset", "objfile");
|
||||
}
|
||||
|
||||
filenames = descdata + count * 3 * addr_size;
|
||||
while (--count > 0)
|
||||
{
|
||||
ULONGEST start, end, file_ofs;
|
||||
|
||||
if (filenames == descend)
|
||||
error (_("malformed note - filenames end too early"));
|
||||
|
||||
start = bfd_get (addr_size_bits, core_bfd, descdata);
|
||||
descdata += addr_size;
|
||||
end = bfd_get (addr_size_bits, core_bfd, descdata);
|
||||
descdata += addr_size;
|
||||
file_ofs = bfd_get (addr_size_bits, core_bfd, descdata);
|
||||
descdata += addr_size;
|
||||
|
||||
file_ofs *= page_size;
|
||||
|
||||
if (gdbarch_addr_bit (gdbarch) == 32)
|
||||
printf_filtered ("\t%10s %10s %10s %10s %s\n",
|
||||
paddress (gdbarch, start),
|
||||
paddress (gdbarch, end),
|
||||
hex_string (end - start),
|
||||
hex_string (file_ofs),
|
||||
filenames);
|
||||
else
|
||||
printf_filtered (" %18s %18s %10s %10s %s\n",
|
||||
paddress (gdbarch, start),
|
||||
paddress (gdbarch, end),
|
||||
hex_string (end - start),
|
||||
hex_string (file_ofs),
|
||||
filenames);
|
||||
|
||||
filenames += 1 + strlen ((char *) filenames);
|
||||
}
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
|
||||
/* Implement "info proc" for a corefile. */
|
||||
|
||||
static void
|
||||
linux_core_info_proc (struct gdbarch *gdbarch, char *args,
|
||||
enum info_proc_what what)
|
||||
{
|
||||
int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
|
||||
int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
|
||||
|
||||
if (exe_f)
|
||||
{
|
||||
const char *exe;
|
||||
|
||||
exe = bfd_core_file_failing_command (core_bfd);
|
||||
if (exe != NULL)
|
||||
printf_filtered ("exe = '%s'\n", exe);
|
||||
else
|
||||
warning (_("unable to find command name in core file"));
|
||||
}
|
||||
|
||||
if (mappings_f)
|
||||
linux_core_info_proc_mappings (gdbarch, args);
|
||||
|
||||
if (!exe_f && !mappings_f)
|
||||
error (_("unable to handle request"));
|
||||
}
|
||||
|
||||
typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size,
|
||||
ULONGEST offset, ULONGEST inode,
|
||||
int read, int write,
|
||||
int exec, int modified,
|
||||
const char *filename,
|
||||
void *data);
|
||||
|
||||
/* List memory regions in the inferior for a corefile. */
|
||||
|
||||
static int
|
||||
linux_find_memory_regions (struct gdbarch *gdbarch,
|
||||
find_memory_region_ftype func, void *obfd)
|
||||
linux_find_memory_regions_full (struct gdbarch *gdbarch,
|
||||
linux_find_memory_region_ftype *func,
|
||||
void *obfd)
|
||||
{
|
||||
char filename[100];
|
||||
gdb_byte *data;
|
||||
@ -606,7 +746,8 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
|
||||
modified = 1;
|
||||
|
||||
/* Invoke the callback function to create the corefile segment. */
|
||||
func (addr, endaddr - addr, read, write, exec, modified, obfd);
|
||||
func (addr, endaddr - addr, offset, inode,
|
||||
read, write, exec, modified, filename, obfd);
|
||||
}
|
||||
|
||||
do_cleanups (cleanup);
|
||||
@ -616,6 +757,51 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* A structure for passing information through
|
||||
linux_find_memory_regions_full. */
|
||||
|
||||
struct linux_find_memory_regions_data
|
||||
{
|
||||
/* The original callback. */
|
||||
|
||||
find_memory_region_ftype func;
|
||||
|
||||
/* The original datum. */
|
||||
|
||||
void *obfd;
|
||||
};
|
||||
|
||||
/* A callback for linux_find_memory_regions that converts between the
|
||||
"full"-style callback and find_memory_region_ftype. */
|
||||
|
||||
static int
|
||||
linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size,
|
||||
ULONGEST offset, ULONGEST inode,
|
||||
int read, int write, int exec, int modified,
|
||||
const char *filename, void *arg)
|
||||
{
|
||||
struct linux_find_memory_regions_data *data = arg;
|
||||
|
||||
return data->func (vaddr, size, read, write, exec, modified, data->obfd);
|
||||
}
|
||||
|
||||
/* A variant of linux_find_memory_regions_full that is suitable as the
|
||||
gdbarch find_memory_regions method. */
|
||||
|
||||
static int
|
||||
linux_find_memory_regions (struct gdbarch *gdbarch,
|
||||
find_memory_region_ftype func, void *obfd)
|
||||
{
|
||||
struct linux_find_memory_regions_data data;
|
||||
|
||||
data.func = func;
|
||||
data.obfd = obfd;
|
||||
|
||||
return linux_find_memory_regions_full (gdbarch,
|
||||
linux_find_memory_regions_thunk,
|
||||
&data);
|
||||
}
|
||||
|
||||
/* Determine which signal stopped execution. */
|
||||
|
||||
static int
|
||||
@ -712,6 +898,112 @@ linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
|
||||
return note_data;
|
||||
}
|
||||
|
||||
/* This is used to pass information from
|
||||
linux_make_mappings_corefile_notes through
|
||||
linux_find_memory_regions_full. */
|
||||
|
||||
struct linux_make_mappings_data
|
||||
{
|
||||
/* Number of files mapped. */
|
||||
ULONGEST file_count;
|
||||
|
||||
/* The obstack for the main part of the data. */
|
||||
struct obstack *data_obstack;
|
||||
|
||||
/* The filename obstack. */
|
||||
struct obstack *filename_obstack;
|
||||
|
||||
/* The architecture's "long" type. */
|
||||
struct type *long_type;
|
||||
};
|
||||
|
||||
static linux_find_memory_region_ftype linux_make_mappings_callback;
|
||||
|
||||
/* A callback for linux_find_memory_regions_full that updates the
|
||||
mappings data for linux_make_mappings_corefile_notes. */
|
||||
|
||||
static int
|
||||
linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size,
|
||||
ULONGEST offset, ULONGEST inode,
|
||||
int read, int write, int exec, int modified,
|
||||
const char *filename, void *data)
|
||||
{
|
||||
struct linux_make_mappings_data *map_data = data;
|
||||
gdb_byte buf[sizeof (ULONGEST)];
|
||||
|
||||
if (*filename == '\0' || inode == 0)
|
||||
return 0;
|
||||
|
||||
++map_data->file_count;
|
||||
|
||||
pack_long (buf, map_data->long_type, vaddr);
|
||||
obstack_grow (map_data->data_obstack, buf, TYPE_LENGTH (map_data->long_type));
|
||||
pack_long (buf, map_data->long_type, vaddr + size);
|
||||
obstack_grow (map_data->data_obstack, buf, TYPE_LENGTH (map_data->long_type));
|
||||
pack_long (buf, map_data->long_type, offset);
|
||||
obstack_grow (map_data->data_obstack, buf, TYPE_LENGTH (map_data->long_type));
|
||||
|
||||
obstack_grow_str0 (map_data->filename_obstack, filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write the file mapping data to the core file, if possible. OBFD is
|
||||
the output BFD. NOTE_DATA is the current note data, and NOTE_SIZE
|
||||
is a pointer to the note size. Returns the new NOTE_DATA and
|
||||
updates NOTE_SIZE. */
|
||||
|
||||
static char *
|
||||
linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
|
||||
char *note_data, int *note_size)
|
||||
{
|
||||
struct cleanup *cleanup;
|
||||
struct obstack data_obstack, filename_obstack;
|
||||
struct linux_make_mappings_data mapping_data;
|
||||
struct type *long_type
|
||||
= arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), 0, "long");
|
||||
gdb_byte buf[sizeof (ULONGEST)];
|
||||
|
||||
obstack_init (&data_obstack);
|
||||
cleanup = make_cleanup_obstack_free (&data_obstack);
|
||||
obstack_init (&filename_obstack);
|
||||
make_cleanup_obstack_free (&filename_obstack);
|
||||
|
||||
mapping_data.file_count = 0;
|
||||
mapping_data.data_obstack = &data_obstack;
|
||||
mapping_data.filename_obstack = &filename_obstack;
|
||||
mapping_data.long_type = long_type;
|
||||
|
||||
/* Reserve space for the count. */
|
||||
obstack_blank (&data_obstack, TYPE_LENGTH (long_type));
|
||||
/* We always write the page size as 1 since we have no good way to
|
||||
determine the correct value. */
|
||||
pack_long (buf, long_type, 1);
|
||||
obstack_grow (&data_obstack, buf, TYPE_LENGTH (long_type));
|
||||
|
||||
linux_find_memory_regions_full (gdbarch, linux_make_mappings_callback,
|
||||
&mapping_data);
|
||||
|
||||
if (mapping_data.file_count != 0)
|
||||
{
|
||||
/* Write the count to the obstack. */
|
||||
pack_long (obstack_base (&data_obstack), long_type,
|
||||
mapping_data.file_count);
|
||||
|
||||
/* Copy the filenames to the data obstack. */
|
||||
obstack_grow (&data_obstack, obstack_base (&filename_obstack),
|
||||
obstack_object_size (&filename_obstack));
|
||||
|
||||
note_data = elfcore_write_note (obfd, note_data, note_size,
|
||||
"CORE", NT_FILE,
|
||||
obstack_base (&data_obstack),
|
||||
obstack_object_size (&data_obstack));
|
||||
}
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return note_data;
|
||||
}
|
||||
|
||||
/* Records the thread's register state for the corefile note
|
||||
section. */
|
||||
|
||||
@ -923,6 +1215,10 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size,
|
||||
if (!note_data)
|
||||
return NULL;
|
||||
|
||||
/* File mappings. */
|
||||
note_data = linux_make_mappings_corefile_notes (gdbarch, obfd,
|
||||
note_data, note_size);
|
||||
|
||||
make_cleanup (xfree, note_data);
|
||||
return note_data;
|
||||
}
|
||||
@ -949,6 +1245,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str);
|
||||
set_gdbarch_info_proc (gdbarch, linux_info_proc);
|
||||
set_gdbarch_core_info_proc (gdbarch, linux_core_info_proc);
|
||||
set_gdbarch_find_memory_regions (gdbarch, linux_find_memory_regions);
|
||||
set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes_1);
|
||||
set_gdbarch_has_shared_address_space (gdbarch,
|
||||
|
@ -3144,7 +3144,7 @@ target_supports_non_stop (void)
|
||||
|
||||
/* Implement the "info proc" command. */
|
||||
|
||||
void
|
||||
int
|
||||
target_info_proc (char *args, enum info_proc_what what)
|
||||
{
|
||||
struct target_ops *t;
|
||||
@ -3167,11 +3167,11 @@ target_info_proc (char *args, enum info_proc_what what)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"target_info_proc (\"%s\", %d)\n", args, what);
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
error (_("Not supported on this target."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -976,9 +976,12 @@ extern void target_store_registers (struct regcache *regcache, int regs);
|
||||
|
||||
struct address_space *target_thread_address_space (ptid_t);
|
||||
|
||||
/* Implement the "info proc" command. */
|
||||
/* Implement the "info proc" command. This returns one if the request
|
||||
was handled, and zero otherwise. It can also throw an exception if
|
||||
an error was encountered while attempting to handle the
|
||||
request. */
|
||||
|
||||
void target_info_proc (char *, enum info_proc_what);
|
||||
int target_info_proc (char *, enum info_proc_what);
|
||||
|
||||
/* Returns true if this target can debug multiple processes
|
||||
simultaneously. */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2012-12-14 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.base/info-proc.exp: Add core file tests.
|
||||
|
||||
2012-12-14 Yufeng Zhang <yufeng.zhang@arm.com>
|
||||
|
||||
* gdb.base/kill-after-signal.exp: Disable if gdb,nosignals.
|
||||
|
@ -68,3 +68,17 @@ gdb_test "info proc" "process ${decimal}.*" "info proc with process"
|
||||
gdb_test "info proc mapping" \
|
||||
".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}${ws}${hex}.*" \
|
||||
"info proc mapping"
|
||||
|
||||
if {[istarget "*-*-linux*"]} {
|
||||
set gcorefile [standard_output_file $testfile.gcore]
|
||||
if {[gdb_gcore_cmd $gcorefile "save a core file"]} {
|
||||
clean_restart $binfile
|
||||
|
||||
gdb_test "core $gcorefile" "Core was generated by.*" \
|
||||
"core [file tail $gcorefile]"
|
||||
|
||||
gdb_test "info proc mapping" \
|
||||
".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}${ws}${hex}.*" \
|
||||
"info proc mapping with core file"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user