gdb/
Make core files the process_stratum. * corefile.c (core_target): New variable. (core_file_command): Remove variable t, use core_target. * corelow.c (core_ops): Make it static. (init_core_ops): Change to process_stratum. Initialize CORE_TARGET. * defs.h (make_cleanup_unpush_target): New prototype. * gdbarch.h: Regenerate. * gdbarch.sh (core_pid_to_str): Remove core_stratum from its comment. * gdbcore.h (core_target): New declaration. * inf-ptrace.c (inf_ptrace_create_inferior, inf_ptrace_attach): New variables ops_already_pushed and back_to. Use push_target, make_cleanup_unpush_target and discard_cleanups calls. * record.c (record_open): Replace core_stratum by a core_bfd check. * target.c (target_is_pushed): New function. (find_core_target): Remove. * target.h (enum strata) <core_stratum>: Remove. (target_is_pushed): New declaration. (find_core_target): Remove declaration. * tracepoint.c (init_tfile_ops) <to_stratum>: Remove comment. * utils.c (do_unpush_target, make_cleanup_unpush_target): New functions. gdb/doc/ Make core files the process_stratum. * gdb.texinfo (Active Targets): Remove core_stratum. Include record_stratum example. gdb/testsuite/ Make core files the process_stratum. * gdb.base/corefile.exp (run: load core again) (run: sanity check we see the core file, run: with core) (run: core file is cleared, attach: load core again) (attach: sanity check we see the core file, attach: with core) (attach: core file is cleared): New tests. * gdb.base/coremaker.c (main): New parameters. Implement "sleep" argv.
This commit is contained in:
parent
3437afb199
commit
c0edd9edad
18 changed files with 216 additions and 73 deletions
|
@ -1,3 +1,26 @@
|
||||||
|
2010-07-19 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
Make core files the process_stratum.
|
||||||
|
* corefile.c (core_target): New variable.
|
||||||
|
(core_file_command): Remove variable t, use core_target.
|
||||||
|
* corelow.c (core_ops): Make it static.
|
||||||
|
(init_core_ops): Change to process_stratum. Initialize CORE_TARGET.
|
||||||
|
* defs.h (make_cleanup_unpush_target): New prototype.
|
||||||
|
* gdbarch.h: Regenerate.
|
||||||
|
* gdbarch.sh (core_pid_to_str): Remove core_stratum from its comment.
|
||||||
|
* gdbcore.h (core_target): New declaration.
|
||||||
|
* inf-ptrace.c (inf_ptrace_create_inferior, inf_ptrace_attach): New
|
||||||
|
variables ops_already_pushed and back_to. Use push_target,
|
||||||
|
make_cleanup_unpush_target and discard_cleanups calls.
|
||||||
|
* record.c (record_open): Replace core_stratum by a core_bfd check.
|
||||||
|
* target.c (target_is_pushed): New function.
|
||||||
|
(find_core_target): Remove.
|
||||||
|
* target.h (enum strata) <core_stratum>: Remove.
|
||||||
|
(target_is_pushed): New declaration.
|
||||||
|
(find_core_target): Remove declaration.
|
||||||
|
* tracepoint.c (init_tfile_ops) <to_stratum>: Remove comment.
|
||||||
|
* utils.c (do_unpush_target, make_cleanup_unpush_target): New functions.
|
||||||
|
|
||||||
2010-07-19 Hui Zhu <teawater@gmail.com>
|
2010-07-19 Hui Zhu <teawater@gmail.com>
|
||||||
|
|
||||||
* breakpoint.c (single_step_breakpoints_inserted): New
|
* breakpoint.c (single_step_breakpoints_inserted): New
|
||||||
|
|
|
@ -59,6 +59,10 @@ static int exec_file_hook_count = 0; /* size of array */
|
||||||
/* Binary file diddling handle for the core file. */
|
/* Binary file diddling handle for the core file. */
|
||||||
|
|
||||||
bfd *core_bfd = NULL;
|
bfd *core_bfd = NULL;
|
||||||
|
|
||||||
|
/* corelow.c target (if included for this gdb target). */
|
||||||
|
|
||||||
|
struct target_ops *core_target;
|
||||||
|
|
||||||
|
|
||||||
/* Backward compatability with old way of specifying core files. */
|
/* Backward compatability with old way of specifying core files. */
|
||||||
|
@ -66,18 +70,15 @@ bfd *core_bfd = NULL;
|
||||||
void
|
void
|
||||||
core_file_command (char *filename, int from_tty)
|
core_file_command (char *filename, int from_tty)
|
||||||
{
|
{
|
||||||
struct target_ops *t;
|
|
||||||
|
|
||||||
dont_repeat (); /* Either way, seems bogus. */
|
dont_repeat (); /* Either way, seems bogus. */
|
||||||
|
|
||||||
t = find_core_target ();
|
if (core_target == NULL)
|
||||||
if (t == NULL)
|
|
||||||
error (_("GDB can't read core files on this machine."));
|
error (_("GDB can't read core files on this machine."));
|
||||||
|
|
||||||
if (!filename)
|
if (!filename)
|
||||||
(t->to_detach) (t, filename, from_tty);
|
(core_target->to_detach) (core_target, filename, from_tty);
|
||||||
else
|
else
|
||||||
(t->to_open) (filename, from_tty);
|
(core_target->to_open) (filename, from_tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ static void init_core_ops (void);
|
||||||
|
|
||||||
void _initialize_corelow (void);
|
void _initialize_corelow (void);
|
||||||
|
|
||||||
struct target_ops core_ops;
|
static struct target_ops core_ops;
|
||||||
|
|
||||||
/* An arbitrary identifier for the core inferior. */
|
/* An arbitrary identifier for the core inferior. */
|
||||||
#define CORELOW_PID 1
|
#define CORELOW_PID 1
|
||||||
|
@ -911,11 +911,17 @@ init_core_ops (void)
|
||||||
core_ops.to_thread_alive = core_thread_alive;
|
core_ops.to_thread_alive = core_thread_alive;
|
||||||
core_ops.to_read_description = core_read_description;
|
core_ops.to_read_description = core_read_description;
|
||||||
core_ops.to_pid_to_str = core_pid_to_str;
|
core_ops.to_pid_to_str = core_pid_to_str;
|
||||||
core_ops.to_stratum = core_stratum;
|
core_ops.to_stratum = process_stratum;
|
||||||
core_ops.to_has_memory = core_has_memory;
|
core_ops.to_has_memory = core_has_memory;
|
||||||
core_ops.to_has_stack = core_has_stack;
|
core_ops.to_has_stack = core_has_stack;
|
||||||
core_ops.to_has_registers = core_has_registers;
|
core_ops.to_has_registers = core_has_registers;
|
||||||
core_ops.to_magic = OPS_MAGIC;
|
core_ops.to_magic = OPS_MAGIC;
|
||||||
|
|
||||||
|
if (core_target)
|
||||||
|
internal_error (__FILE__, __LINE__,
|
||||||
|
_("init_core_ops: core target already exists (\"%s\")."),
|
||||||
|
core_target->to_longname);
|
||||||
|
core_target = &core_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -352,6 +352,9 @@ extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack);
|
||||||
|
|
||||||
extern struct cleanup *make_cleanup_restore_integer (int *variable);
|
extern struct cleanup *make_cleanup_restore_integer (int *variable);
|
||||||
|
|
||||||
|
struct target_ops;
|
||||||
|
extern struct cleanup *make_cleanup_unpush_target (struct target_ops *ops);
|
||||||
|
|
||||||
extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
|
extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
|
||||||
|
|
||||||
extern struct cleanup *make_my_cleanup (struct cleanup **,
|
extern struct cleanup *make_my_cleanup (struct cleanup **,
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2010-07-19 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
Eli Zaretskii <eliz@gnu.org>
|
||||||
|
|
||||||
|
Make core files the process_stratum.
|
||||||
|
* gdb.texinfo (Active Targets): Remove core_stratum. Include
|
||||||
|
record_stratum example.
|
||||||
|
|
||||||
2010-07-13 Tom Tromey <tromey@redhat.com>
|
2010-07-13 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* gdb.texinfo (Index Files): New node.
|
* gdb.texinfo (Index Files): New node.
|
||||||
|
|
|
@ -15391,33 +15391,20 @@ and @code{show architecture}.
|
||||||
@cindex active targets
|
@cindex active targets
|
||||||
@cindex multiple targets
|
@cindex multiple targets
|
||||||
|
|
||||||
There are three classes of targets: processes, core files, and
|
There are multiple classes of targets such, as: processes, executable files or
|
||||||
executable files. @value{GDBN} can work concurrently on up to three
|
recording sessions. Core files belong to the process class, making core file
|
||||||
active targets, one in each class. This allows you to (for example)
|
and process mutually exclusive. Otherwise, @value{GDBN} can work concurrently
|
||||||
start a process and inspect its activity without abandoning your work on
|
on multiple active targets, one in each class. This allows you to (for
|
||||||
a core file.
|
example) start a process and inspect its activity, while still having access to
|
||||||
|
the executable file after the process finishes. Or if you start process
|
||||||
|
recording (@pxref{Reverse Execution}) and @code{reverse-step} there, you are
|
||||||
|
presented a virtual layer of the recording target, while the process target
|
||||||
|
remains stopped at the chronologically last point of the process execution.
|
||||||
|
|
||||||
For example, if you execute @samp{gdb a.out}, then the executable file
|
Use the @code{core-file} and @code{exec-file} commands to select a new core
|
||||||
@code{a.out} is the only active target. If you designate a core file as
|
file or executable target (@pxref{Files, ,Commands to Specify Files}). To
|
||||||
well---presumably from a prior run that crashed and coredumped---then
|
specify as a target a process that is already running, use the @code{attach}
|
||||||
@value{GDBN} has two active targets and uses them in tandem, looking
|
command (@pxref{Attach, ,Debugging an Already-running Process}).
|
||||||
first in the corefile target, then in the executable file, to satisfy
|
|
||||||
requests for memory addresses. (Typically, these two classes of target
|
|
||||||
are complementary, since core files contain only a program's
|
|
||||||
read-write memory---variables and so on---plus machine status, while
|
|
||||||
executable files contain only the program text and initialized data.)
|
|
||||||
|
|
||||||
When you type @code{run}, your executable file becomes an active process
|
|
||||||
target as well. When a process target is active, all @value{GDBN}
|
|
||||||
commands requesting memory addresses refer to that target; addresses in
|
|
||||||
an active core file or executable file target are obscured while the
|
|
||||||
process target is active.
|
|
||||||
|
|
||||||
Use the @code{core-file} and @code{exec-file} commands to select a new
|
|
||||||
core file or executable target (@pxref{Files, ,Commands to Specify
|
|
||||||
Files}). To specify as a target a process that is already running, use
|
|
||||||
the @code{attach} command (@pxref{Attach, ,Debugging an Already-running
|
|
||||||
Process}).
|
|
||||||
|
|
||||||
@node Target Commands
|
@node Target Commands
|
||||||
@section Commands for Managing Targets
|
@section Commands for Managing Targets
|
||||||
|
|
|
@ -672,8 +672,7 @@ typedef LONGEST (gdbarch_core_xfer_shared_libraries_ftype) (struct gdbarch *gdba
|
||||||
extern LONGEST gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, LONGEST len);
|
extern LONGEST gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, LONGEST len);
|
||||||
extern void set_gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries);
|
extern void set_gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries);
|
||||||
|
|
||||||
/* How the core_stratum layer converts a PTID from a core file to a
|
/* How the core target converts a PTID from a core file to a string. */
|
||||||
string. */
|
|
||||||
|
|
||||||
extern int gdbarch_core_pid_to_str_p (struct gdbarch *gdbarch);
|
extern int gdbarch_core_pid_to_str_p (struct gdbarch *gdbarch);
|
||||||
|
|
||||||
|
|
|
@ -611,8 +611,7 @@ v:struct core_regset_section *:core_regset_sections:const char *name, int len:::
|
||||||
# core file into buffer READBUF with length LEN.
|
# core file into buffer READBUF with length LEN.
|
||||||
M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
|
M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
|
||||||
|
|
||||||
# How the core_stratum layer converts a PTID from a core file to a
|
# How the core target converts a PTID from a core file to a string.
|
||||||
# string.
|
|
||||||
M:char *:core_pid_to_str:ptid_t ptid:ptid
|
M:char *:core_pid_to_str:ptid_t ptid:ptid
|
||||||
|
|
||||||
# BFD target to use when generating a core file.
|
# BFD target to use when generating a core file.
|
||||||
|
|
|
@ -108,6 +108,8 @@ extern void specify_exec_file_hook (void (*hook) (char *filename));
|
||||||
|
|
||||||
extern bfd *core_bfd;
|
extern bfd *core_bfd;
|
||||||
|
|
||||||
|
extern struct target_ops *core_target;
|
||||||
|
|
||||||
/* Whether to open exec and core files read-only or read-write. */
|
/* Whether to open exec and core files read-only or read-write. */
|
||||||
|
|
||||||
extern int write_files;
|
extern int write_files;
|
||||||
|
|
|
@ -121,10 +121,23 @@ inf_ptrace_create_inferior (struct target_ops *ops,
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
|
/* Do not change either targets above or the same target if already present.
|
||||||
|
The reason is the target stack is shared across multiple inferiors. */
|
||||||
|
int ops_already_pushed = target_is_pushed (ops);
|
||||||
|
struct cleanup *back_to;
|
||||||
|
|
||||||
|
if (! ops_already_pushed)
|
||||||
|
{
|
||||||
|
/* Clear possible core file with its process_stratum. */
|
||||||
|
push_target (ops);
|
||||||
|
back_to = make_cleanup_unpush_target (ops);
|
||||||
|
}
|
||||||
|
|
||||||
pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
|
pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
push_target (ops);
|
if (! ops_already_pushed)
|
||||||
|
discard_cleanups (back_to);
|
||||||
|
|
||||||
/* On some targets, there must be some explicit synchronization
|
/* On some targets, there must be some explicit synchronization
|
||||||
between the parent and child processes after the debugger
|
between the parent and child processes after the debugger
|
||||||
|
@ -189,11 +202,24 @@ inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
struct inferior *inf;
|
struct inferior *inf;
|
||||||
|
|
||||||
|
/* Do not change either targets above or the same target if already present.
|
||||||
|
The reason is the target stack is shared across multiple inferiors. */
|
||||||
|
int ops_already_pushed = target_is_pushed (ops);
|
||||||
|
struct cleanup *back_to;
|
||||||
|
|
||||||
pid = parse_pid_to_attach (args);
|
pid = parse_pid_to_attach (args);
|
||||||
|
|
||||||
if (pid == getpid ()) /* Trying to masturbate? */
|
if (pid == getpid ()) /* Trying to masturbate? */
|
||||||
error (_("I refuse to debug myself!"));
|
error (_("I refuse to debug myself!"));
|
||||||
|
|
||||||
|
if (! ops_already_pushed)
|
||||||
|
{
|
||||||
|
/* target_pid_to_str already uses the target. Also clear possible core
|
||||||
|
file with its process_stratum. */
|
||||||
|
push_target (ops);
|
||||||
|
back_to = make_cleanup_unpush_target (ops);
|
||||||
|
}
|
||||||
|
|
||||||
if (from_tty)
|
if (from_tty)
|
||||||
{
|
{
|
||||||
exec_file = get_exec_file (0);
|
exec_file = get_exec_file (0);
|
||||||
|
@ -226,7 +252,8 @@ inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
|
||||||
target, it should decorate the ptid later with more info. */
|
target, it should decorate the ptid later with more info. */
|
||||||
add_thread_silent (inferior_ptid);
|
add_thread_silent (inferior_ptid);
|
||||||
|
|
||||||
push_target(ops);
|
if (! ops_already_pushed)
|
||||||
|
discard_cleanups (back_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PT_GET_PROCESS_STATE
|
#ifdef PT_GET_PROCESS_STATE
|
||||||
|
|
|
@ -962,7 +962,7 @@ record_open (char *name, int from_tty)
|
||||||
record_beneath_to_stopped_by_watchpoint = tmp_to_stopped_by_watchpoint;
|
record_beneath_to_stopped_by_watchpoint = tmp_to_stopped_by_watchpoint;
|
||||||
record_beneath_to_stopped_data_address = tmp_to_stopped_data_address;
|
record_beneath_to_stopped_data_address = tmp_to_stopped_data_address;
|
||||||
|
|
||||||
if (current_target.to_stratum == core_stratum)
|
if (core_bfd)
|
||||||
record_core_open_1 (name, from_tty);
|
record_core_open_1 (name, from_tty);
|
||||||
else
|
else
|
||||||
record_open_1 (name, from_tty);
|
record_open_1 (name, from_tty);
|
||||||
|
|
49
gdb/target.c
49
gdb/target.c
|
@ -1037,6 +1037,30 @@ pop_all_targets (int quitting)
|
||||||
pop_all_targets_above (dummy_stratum, quitting);
|
pop_all_targets_above (dummy_stratum, quitting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return 1 if T is now pushed in the target stack. Return 0 otherwise. */
|
||||||
|
|
||||||
|
int
|
||||||
|
target_is_pushed (struct target_ops *t)
|
||||||
|
{
|
||||||
|
struct target_ops **cur;
|
||||||
|
|
||||||
|
/* Check magic number. If wrong, it probably means someone changed
|
||||||
|
the struct definition, but not all the places that initialize one. */
|
||||||
|
if (t->to_magic != OPS_MAGIC)
|
||||||
|
{
|
||||||
|
fprintf_unfiltered (gdb_stderr,
|
||||||
|
"Magic number of %s target struct wrong\n",
|
||||||
|
t->to_shortname);
|
||||||
|
internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
|
||||||
|
if (*cur == t)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Using the objfile specified in OBJFILE, find the address for the
|
/* Using the objfile specified in OBJFILE, find the address for the
|
||||||
current thread's thread-local storage with offset OFFSET. */
|
current thread's thread-local storage with offset OFFSET. */
|
||||||
CORE_ADDR
|
CORE_ADDR
|
||||||
|
@ -2770,31 +2794,6 @@ find_run_target (void)
|
||||||
return (count == 1 ? runable : NULL);
|
return (count == 1 ? runable : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a single core_stratum target in the list of targets and return it.
|
|
||||||
If for some reason there is more than one, return NULL. */
|
|
||||||
|
|
||||||
struct target_ops *
|
|
||||||
find_core_target (void)
|
|
||||||
{
|
|
||||||
struct target_ops **t;
|
|
||||||
struct target_ops *runable = NULL;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
|
|
||||||
for (t = target_structs; t < target_structs + target_struct_size;
|
|
||||||
++t)
|
|
||||||
{
|
|
||||||
if ((*t)->to_stratum == core_stratum)
|
|
||||||
{
|
|
||||||
runable = *t;
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (count == 1 ? runable : NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the next target down the stack from the specified target.
|
* Find the next target down the stack from the specified target.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -68,8 +68,7 @@ enum strata
|
||||||
{
|
{
|
||||||
dummy_stratum, /* The lowest of the low */
|
dummy_stratum, /* The lowest of the low */
|
||||||
file_stratum, /* Executable files, etc */
|
file_stratum, /* Executable files, etc */
|
||||||
core_stratum, /* Core dump files */
|
process_stratum, /* Executing processes or core dump files */
|
||||||
process_stratum, /* Executing processes */
|
|
||||||
thread_stratum, /* Executing threads */
|
thread_stratum, /* Executing threads */
|
||||||
record_stratum, /* Support record debugging */
|
record_stratum, /* Support record debugging */
|
||||||
arch_stratum /* Architecture overrides */
|
arch_stratum /* Architecture overrides */
|
||||||
|
@ -1485,6 +1484,8 @@ extern void pop_all_targets (int quitting);
|
||||||
strictly above ABOVE_STRATUM. */
|
strictly above ABOVE_STRATUM. */
|
||||||
extern void pop_all_targets_above (enum strata above_stratum, int quitting);
|
extern void pop_all_targets_above (enum strata above_stratum, int quitting);
|
||||||
|
|
||||||
|
extern int target_is_pushed (struct target_ops *t);
|
||||||
|
|
||||||
extern CORE_ADDR target_translate_tls_address (struct objfile *objfile,
|
extern CORE_ADDR target_translate_tls_address (struct objfile *objfile,
|
||||||
CORE_ADDR offset);
|
CORE_ADDR offset);
|
||||||
|
|
||||||
|
@ -1546,8 +1547,6 @@ extern void find_default_create_inferior (struct target_ops *,
|
||||||
|
|
||||||
extern struct target_ops *find_run_target (void);
|
extern struct target_ops *find_run_target (void);
|
||||||
|
|
||||||
extern struct target_ops *find_core_target (void);
|
|
||||||
|
|
||||||
extern struct target_ops *find_target_beneath (struct target_ops *);
|
extern struct target_ops *find_target_beneath (struct target_ops *);
|
||||||
|
|
||||||
/* Read OS data object of type TYPE from the target, and return it in
|
/* Read OS data object of type TYPE from the target, and return it in
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
2010-07-19 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
Make core files the process_stratum.
|
||||||
|
* gdb.base/corefile.exp (run: load core again)
|
||||||
|
(run: sanity check we see the core file, run: with core)
|
||||||
|
(run: core file is cleared, attach: load core again)
|
||||||
|
(attach: sanity check we see the core file, attach: with core)
|
||||||
|
(attach: core file is cleared): New tests.
|
||||||
|
* gdb.base/coremaker.c (main): New parameters. Implement "sleep" argv.
|
||||||
|
|
||||||
2010-07-14 Ken Werner <ken.werner@de.ibm.com>
|
2010-07-14 Ken Werner <ken.werner@de.ibm.com>
|
||||||
|
|
||||||
* gdb.arch/altivec-abi.exp: New tests.
|
* gdb.arch/altivec-abi.exp: New tests.
|
||||||
|
|
|
@ -177,3 +177,62 @@ gdb_load ${binfile}
|
||||||
gdb_test "up" "#\[0-9\]* *\[0-9xa-fH'\]* in .* \\(.*\\).*" "up in corefile.exp (reinit)"
|
gdb_test "up" "#\[0-9\]* *\[0-9xa-fH'\]* in .* \\(.*\\).*" "up in corefile.exp (reinit)"
|
||||||
|
|
||||||
gdb_test "core" "No core file now."
|
gdb_test "core" "No core file now."
|
||||||
|
|
||||||
|
|
||||||
|
# Test a run (start) command will clear any loaded core file.
|
||||||
|
|
||||||
|
gdb_test "core-file $corefile" "Core was generated by .*" "run: load core again"
|
||||||
|
gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "run: sanity check we see the core file"
|
||||||
|
|
||||||
|
set test "run: with core"
|
||||||
|
if [runto_main] {
|
||||||
|
pass $test
|
||||||
|
} else {
|
||||||
|
fail $test
|
||||||
|
}
|
||||||
|
|
||||||
|
set test "run: core file is cleared"
|
||||||
|
gdb_test_multiple "info files" $test {
|
||||||
|
-re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
|
||||||
|
fail $test
|
||||||
|
}
|
||||||
|
-re "\r\n$gdb_prompt $" {
|
||||||
|
pass $test
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_exit
|
||||||
|
|
||||||
|
|
||||||
|
# Test an attach command will clear any loaded core file.
|
||||||
|
|
||||||
|
if ![is_remote target] {
|
||||||
|
set test "attach: spawn sleep"
|
||||||
|
set res [remote_spawn host "$binfile sleep"];
|
||||||
|
if { $res < 0 || $res == "" } {
|
||||||
|
fail $test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set pid [exp_pid -i $res]
|
||||||
|
# We don't care whether the program is still in the startup phase when we
|
||||||
|
# attach.
|
||||||
|
|
||||||
|
gdb_start
|
||||||
|
|
||||||
|
gdb_test "core-file $corefile" "Core was generated by .*" "attach: load core again"
|
||||||
|
gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "attach: sanity check we see the core file"
|
||||||
|
|
||||||
|
gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach: with core"
|
||||||
|
|
||||||
|
set test "attach: core file is cleared"
|
||||||
|
gdb_test_multiple "info files" $test {
|
||||||
|
-re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
|
||||||
|
fail $test
|
||||||
|
}
|
||||||
|
-re "\r\n$gdb_prompt $" {
|
||||||
|
pass $test
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_exit
|
||||||
|
}
|
||||||
|
|
|
@ -133,8 +133,14 @@ func1 ()
|
||||||
func2 ();
|
func2 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main ()
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
if (argc == 2 && strcmp (argv[1], "sleep") == 0)
|
||||||
|
{
|
||||||
|
sleep (60);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
mmapdata ();
|
mmapdata ();
|
||||||
func1 ();
|
func1 ();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -4098,8 +4098,6 @@ init_tfile_ops (void)
|
||||||
tfile_ops.to_get_trace_status = tfile_get_trace_status;
|
tfile_ops.to_get_trace_status = tfile_get_trace_status;
|
||||||
tfile_ops.to_trace_find = tfile_trace_find;
|
tfile_ops.to_trace_find = tfile_trace_find;
|
||||||
tfile_ops.to_get_trace_state_variable_value = tfile_get_trace_state_variable_value;
|
tfile_ops.to_get_trace_state_variable_value = tfile_get_trace_state_variable_value;
|
||||||
/* core_stratum might seem more logical, but GDB doesn't like having
|
|
||||||
more than one core_stratum vector. */
|
|
||||||
tfile_ops.to_stratum = process_stratum;
|
tfile_ops.to_stratum = process_stratum;
|
||||||
tfile_ops.to_has_all_memory = tfile_has_all_memory;
|
tfile_ops.to_has_all_memory = tfile_has_all_memory;
|
||||||
tfile_ops.to_has_memory = tfile_has_memory;
|
tfile_ops.to_has_memory = tfile_has_memory;
|
||||||
|
|
18
gdb/utils.c
18
gdb/utils.c
|
@ -352,6 +352,24 @@ make_cleanup_restore_integer (int *variable)
|
||||||
xfree);
|
xfree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper for make_cleanup_unpush_target. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_unpush_target (void *arg)
|
||||||
|
{
|
||||||
|
struct target_ops *ops = arg;
|
||||||
|
|
||||||
|
unpush_target (ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a new cleanup that unpushes OPS. */
|
||||||
|
|
||||||
|
struct cleanup *
|
||||||
|
make_cleanup_unpush_target (struct target_ops *ops)
|
||||||
|
{
|
||||||
|
return make_my_cleanup (&cleanup_chain, do_unpush_target, ops);
|
||||||
|
}
|
||||||
|
|
||||||
struct cleanup *
|
struct cleanup *
|
||||||
make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
|
make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
|
||||||
void *arg, void (*free_arg) (void *))
|
void *arg, void (*free_arg) (void *))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue