mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-17 07:53:51 +08:00
gdb/
* findvar.c (value_of_register): Mark the value as unavailable, if the register is unavailable. * frame.h (frame_register_unwind): New `unavailablep' parameter. (frame_register): New `unavailablep' parameter. (frame_register_read): Update comment. * frame.c (frame_register_unwind): New `unavailablep' parameter. Set it if the register is unavailable. If the register is unavailable, clear the output buffer. (frame_register): New `unavailablep' parameter. Pass it down. (frame_unwind_register): Adjust. (put_frame_register): Adjust. (frame_register_read): Adjust. Also return false if the register is not available. (frame_register_unwind_location): Adjust. * sentinel-frame.c (sentinel_frame_prev_register): If the register is unavailable, mark the value accordingly. * stack.c (frame_info): Handle unavailable registers. gdb/testsuite/ * gdb.trace/unavailable.exp (fpreg, spreg, pcreg): Define. (test_register, test_register_unavailable): New procedures. (gdb_unavailable_registers_test): New procedure. (gdb_trace_collection_test): Call it.
This commit is contained in:
@ -1,3 +1,23 @@
|
|||||||
|
2011-03-18 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
* findvar.c (value_of_register): Mark the value as unavailable, if
|
||||||
|
the register is unavailable.
|
||||||
|
* frame.h (frame_register_unwind): New `unavailablep' parameter.
|
||||||
|
(frame_register): New `unavailablep' parameter.
|
||||||
|
(frame_register_read): Update comment.
|
||||||
|
* frame.c (frame_register_unwind): New `unavailablep' parameter.
|
||||||
|
Set it if the register is unavailable. If the register is
|
||||||
|
unavailable, clear the output buffer.
|
||||||
|
(frame_register): New `unavailablep' parameter. Pass it down.
|
||||||
|
(frame_unwind_register): Adjust.
|
||||||
|
(put_frame_register): Adjust.
|
||||||
|
(frame_register_read): Adjust. Also return false if the register
|
||||||
|
is not available.
|
||||||
|
(frame_register_unwind_location): Adjust.
|
||||||
|
* sentinel-frame.c (sentinel_frame_prev_register): If the register
|
||||||
|
is unavailable, mark the value accordingly.
|
||||||
|
* stack.c (frame_info): Handle unavailable registers.
|
||||||
|
|
||||||
2011-03-18 Pedro Alves <pedro@codesourcery.com>
|
2011-03-18 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* mi/mi-main.c (register_changed_p): Handle REG_UNAVAILABLE, and
|
* mi/mi-main.c (register_changed_p): Handle REG_UNAVAILABLE, and
|
||||||
|
@ -265,6 +265,7 @@ value_of_register (int regnum, struct frame_info *frame)
|
|||||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
int optim;
|
int optim;
|
||||||
|
int unavail;
|
||||||
struct value *reg_val;
|
struct value *reg_val;
|
||||||
int realnum;
|
int realnum;
|
||||||
gdb_byte raw_buffer[MAX_REGISTER_SIZE];
|
gdb_byte raw_buffer[MAX_REGISTER_SIZE];
|
||||||
@ -276,16 +277,24 @@ value_of_register (int regnum, struct frame_info *frame)
|
|||||||
+ gdbarch_num_pseudo_regs (gdbarch))
|
+ gdbarch_num_pseudo_regs (gdbarch))
|
||||||
return value_of_user_reg (regnum, frame);
|
return value_of_user_reg (regnum, frame);
|
||||||
|
|
||||||
frame_register (frame, regnum, &optim, &lval, &addr, &realnum, raw_buffer);
|
frame_register (frame, regnum, &optim, &unavail,
|
||||||
|
&lval, &addr, &realnum, raw_buffer);
|
||||||
|
|
||||||
reg_val = allocate_value (register_type (gdbarch, regnum));
|
reg_val = allocate_value (register_type (gdbarch, regnum));
|
||||||
|
|
||||||
memcpy (value_contents_raw (reg_val), raw_buffer,
|
if (!optim && !unavail)
|
||||||
register_size (gdbarch, regnum));
|
memcpy (value_contents_raw (reg_val), raw_buffer,
|
||||||
|
register_size (gdbarch, regnum));
|
||||||
|
else
|
||||||
|
memset (value_contents_raw (reg_val), 0,
|
||||||
|
register_size (gdbarch, regnum));
|
||||||
|
|
||||||
VALUE_LVAL (reg_val) = lval;
|
VALUE_LVAL (reg_val) = lval;
|
||||||
set_value_address (reg_val, addr);
|
set_value_address (reg_val, addr);
|
||||||
VALUE_REGNUM (reg_val) = regnum;
|
VALUE_REGNUM (reg_val) = regnum;
|
||||||
set_value_optimized_out (reg_val, optim);
|
set_value_optimized_out (reg_val, optim);
|
||||||
|
if (unavail)
|
||||||
|
mark_value_bytes_unavailable (reg_val, 0, register_size (gdbarch, regnum));
|
||||||
VALUE_FRAME_ID (reg_val) = get_frame_id (frame);
|
VALUE_FRAME_ID (reg_val) = get_frame_id (frame);
|
||||||
return reg_val;
|
return reg_val;
|
||||||
}
|
}
|
||||||
|
44
gdb/frame.c
44
gdb/frame.c
@ -757,8 +757,9 @@ frame_pop (struct frame_info *this_frame)
|
|||||||
|
|
||||||
void
|
void
|
||||||
frame_register_unwind (struct frame_info *frame, int regnum,
|
frame_register_unwind (struct frame_info *frame, int regnum,
|
||||||
int *optimizedp, enum lval_type *lvalp,
|
int *optimizedp, int *unavailablep,
|
||||||
CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp)
|
enum lval_type *lvalp, CORE_ADDR *addrp,
|
||||||
|
int *realnump, gdb_byte *bufferp)
|
||||||
{
|
{
|
||||||
struct value *value;
|
struct value *value;
|
||||||
|
|
||||||
@ -775,13 +776,19 @@ frame_register_unwind (struct frame_info *frame, int regnum,
|
|||||||
gdb_assert (value != NULL);
|
gdb_assert (value != NULL);
|
||||||
|
|
||||||
*optimizedp = value_optimized_out (value);
|
*optimizedp = value_optimized_out (value);
|
||||||
|
*unavailablep = !value_entirely_available (value);
|
||||||
*lvalp = VALUE_LVAL (value);
|
*lvalp = VALUE_LVAL (value);
|
||||||
*addrp = value_address (value);
|
*addrp = value_address (value);
|
||||||
*realnump = VALUE_REGNUM (value);
|
*realnump = VALUE_REGNUM (value);
|
||||||
|
|
||||||
if (bufferp && !*optimizedp)
|
if (bufferp)
|
||||||
memcpy (bufferp, value_contents_all (value),
|
{
|
||||||
TYPE_LENGTH (value_type (value)));
|
if (!*optimizedp && !*unavailablep)
|
||||||
|
memcpy (bufferp, value_contents_all (value),
|
||||||
|
TYPE_LENGTH (value_type (value)));
|
||||||
|
else
|
||||||
|
memset (bufferp, 0, TYPE_LENGTH (value_type (value)));
|
||||||
|
}
|
||||||
|
|
||||||
/* Dispose of the new value. This prevents watchpoints from
|
/* Dispose of the new value. This prevents watchpoints from
|
||||||
trying to watch the saved frame pointer. */
|
trying to watch the saved frame pointer. */
|
||||||
@ -791,7 +798,7 @@ frame_register_unwind (struct frame_info *frame, int regnum,
|
|||||||
|
|
||||||
void
|
void
|
||||||
frame_register (struct frame_info *frame, int regnum,
|
frame_register (struct frame_info *frame, int regnum,
|
||||||
int *optimizedp, enum lval_type *lvalp,
|
int *optimizedp, int *unavailablep, enum lval_type *lvalp,
|
||||||
CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp)
|
CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp)
|
||||||
{
|
{
|
||||||
/* Require all but BUFFERP to be valid. A NULL BUFFERP indicates
|
/* Require all but BUFFERP to be valid. A NULL BUFFERP indicates
|
||||||
@ -805,20 +812,21 @@ frame_register (struct frame_info *frame, int regnum,
|
|||||||
/* Obtain the register value by unwinding the register from the next
|
/* Obtain the register value by unwinding the register from the next
|
||||||
(more inner frame). */
|
(more inner frame). */
|
||||||
gdb_assert (frame != NULL && frame->next != NULL);
|
gdb_assert (frame != NULL && frame->next != NULL);
|
||||||
frame_register_unwind (frame->next, regnum, optimizedp, lvalp, addrp,
|
frame_register_unwind (frame->next, regnum, optimizedp, unavailablep,
|
||||||
realnump, bufferp);
|
lvalp, addrp, realnump, bufferp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf)
|
frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf)
|
||||||
{
|
{
|
||||||
int optimized;
|
int optimized;
|
||||||
|
int unavailable;
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
int realnum;
|
int realnum;
|
||||||
enum lval_type lval;
|
enum lval_type lval;
|
||||||
|
|
||||||
frame_register_unwind (frame, regnum, &optimized, &lval, &addr,
|
frame_register_unwind (frame, regnum, &optimized, &unavailable,
|
||||||
&realnum, buf);
|
&lval, &addr, &realnum, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -940,10 +948,12 @@ put_frame_register (struct frame_info *frame, int regnum,
|
|||||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||||
int realnum;
|
int realnum;
|
||||||
int optim;
|
int optim;
|
||||||
|
int unavail;
|
||||||
enum lval_type lval;
|
enum lval_type lval;
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
|
|
||||||
frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
|
frame_register (frame, regnum, &optim, &unavail,
|
||||||
|
&lval, &addr, &realnum, NULL);
|
||||||
if (optim)
|
if (optim)
|
||||||
error (_("Attempt to assign to a value that was optimized out."));
|
error (_("Attempt to assign to a value that was optimized out."));
|
||||||
switch (lval)
|
switch (lval)
|
||||||
@ -978,13 +988,15 @@ frame_register_read (struct frame_info *frame, int regnum,
|
|||||||
gdb_byte *myaddr)
|
gdb_byte *myaddr)
|
||||||
{
|
{
|
||||||
int optimized;
|
int optimized;
|
||||||
|
int unavailable;
|
||||||
enum lval_type lval;
|
enum lval_type lval;
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
int realnum;
|
int realnum;
|
||||||
|
|
||||||
frame_register (frame, regnum, &optimized, &lval, &addr, &realnum, myaddr);
|
frame_register (frame, regnum, &optimized, &unavailable,
|
||||||
|
&lval, &addr, &realnum, myaddr);
|
||||||
|
|
||||||
return !optimized;
|
return !optimized && !unavailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1425,8 +1437,10 @@ frame_register_unwind_location (struct frame_info *this_frame, int regnum,
|
|||||||
|
|
||||||
while (this_frame != NULL)
|
while (this_frame != NULL)
|
||||||
{
|
{
|
||||||
frame_register_unwind (this_frame, regnum, optimizedp, lvalp,
|
int unavailable;
|
||||||
addrp, realnump, NULL);
|
|
||||||
|
frame_register_unwind (this_frame, regnum, optimizedp, &unavailable,
|
||||||
|
lvalp, addrp, realnump, NULL);
|
||||||
|
|
||||||
if (*optimizedp)
|
if (*optimizedp)
|
||||||
break;
|
break;
|
||||||
|
20
gdb/frame.h
20
gdb/frame.h
@ -471,7 +471,8 @@ const char *frame_stop_reason_string (enum unwind_stop_reason);
|
|||||||
fetch/compute the value. Instead just return the location of the
|
fetch/compute the value. Instead just return the location of the
|
||||||
value. */
|
value. */
|
||||||
extern void frame_register_unwind (struct frame_info *frame, int regnum,
|
extern void frame_register_unwind (struct frame_info *frame, int regnum,
|
||||||
int *optimizedp, enum lval_type *lvalp,
|
int *optimizedp, int *unavailablep,
|
||||||
|
enum lval_type *lvalp,
|
||||||
CORE_ADDR *addrp, int *realnump,
|
CORE_ADDR *addrp, int *realnump,
|
||||||
gdb_byte *valuep);
|
gdb_byte *valuep);
|
||||||
|
|
||||||
@ -507,7 +508,8 @@ extern ULONGEST get_frame_register_unsigned (struct frame_info *frame,
|
|||||||
VALUEP is NULL, the registers value is not fetched/computed. */
|
VALUEP is NULL, the registers value is not fetched/computed. */
|
||||||
|
|
||||||
extern void frame_register (struct frame_info *frame, int regnum,
|
extern void frame_register (struct frame_info *frame, int regnum,
|
||||||
int *optimizedp, enum lval_type *lvalp,
|
int *optimizedp, int *unavailablep,
|
||||||
|
enum lval_type *lvalp,
|
||||||
CORE_ADDR *addrp, int *realnump,
|
CORE_ADDR *addrp, int *realnump,
|
||||||
gdb_byte *valuep);
|
gdb_byte *valuep);
|
||||||
|
|
||||||
@ -654,12 +656,14 @@ extern int deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc);
|
|||||||
/* FIXME: cagney/2003-02-02: Should be deprecated or replaced with a
|
/* FIXME: cagney/2003-02-02: Should be deprecated or replaced with a
|
||||||
function called get_frame_register_p(). This slightly weird (and
|
function called get_frame_register_p(). This slightly weird (and
|
||||||
older) variant of get_frame_register() returns zero (indicating the
|
older) variant of get_frame_register() returns zero (indicating the
|
||||||
register is unavailable) if either: the register isn't cached; or
|
register value is unavailable/invalid) if either: the register
|
||||||
the register has been optimized out. Problem is, neither check is
|
isn't cached; or the register has been optimized out; or the
|
||||||
exactly correct. A register can't be optimized out (it may not
|
register contents are unavailable (because they haven't been
|
||||||
have been saved as part of a function call); The fact that a
|
collected in a traceframe). Problem is, neither check is exactly
|
||||||
register isn't in the register cache doesn't mean that the register
|
correct. A register can't be optimized out (it may not have been
|
||||||
isn't available (it could have been fetched from memory). */
|
saved as part of a function call); The fact that a register isn't
|
||||||
|
in the register cache doesn't mean that the register isn't
|
||||||
|
available (it could have been fetched from memory). */
|
||||||
|
|
||||||
extern int frame_register_read (struct frame_info *frame, int regnum,
|
extern int frame_register_read (struct frame_info *frame, int regnum,
|
||||||
gdb_byte *buf);
|
gdb_byte *buf);
|
||||||
|
@ -61,7 +61,10 @@ sentinel_frame_prev_register (struct frame_info *this_frame,
|
|||||||
/* Use the regcache_cooked_read() method so that it, on the fly,
|
/* Use the regcache_cooked_read() method so that it, on the fly,
|
||||||
constructs either a raw or pseudo register from the raw
|
constructs either a raw or pseudo register from the raw
|
||||||
register cache. */
|
register cache. */
|
||||||
regcache_cooked_read (cache->regcache, regnum, value_contents_raw (value));
|
if (regcache_cooked_read (cache->regcache,
|
||||||
|
regnum,
|
||||||
|
value_contents_raw (value)) == REG_UNAVAILABLE)
|
||||||
|
mark_value_bytes_unavailable (value, 0, register_size (gdbarch, regnum));
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
17
gdb/stack.c
17
gdb/stack.c
@ -1186,6 +1186,7 @@ frame_info (char *addr_exp, int from_tty)
|
|||||||
{
|
{
|
||||||
enum lval_type lval;
|
enum lval_type lval;
|
||||||
int optimized;
|
int optimized;
|
||||||
|
int unavailable;
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
int realnum;
|
int realnum;
|
||||||
int count;
|
int count;
|
||||||
@ -1202,9 +1203,9 @@ frame_info (char *addr_exp, int from_tty)
|
|||||||
/* Find out the location of the saved stack pointer with out
|
/* Find out the location of the saved stack pointer with out
|
||||||
actually evaluating it. */
|
actually evaluating it. */
|
||||||
frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
|
frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
|
||||||
&optimized, &lval, &addr,
|
&optimized, &unavailable, &lval, &addr,
|
||||||
&realnum, NULL);
|
&realnum, NULL);
|
||||||
if (!optimized && lval == not_lval)
|
if (!optimized && !unavailable && lval == not_lval)
|
||||||
{
|
{
|
||||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||||
int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
|
int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
|
||||||
@ -1212,7 +1213,7 @@ frame_info (char *addr_exp, int from_tty)
|
|||||||
CORE_ADDR sp;
|
CORE_ADDR sp;
|
||||||
|
|
||||||
frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
|
frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
|
||||||
&optimized, &lval, &addr,
|
&optimized, &unavailable, &lval, &addr,
|
||||||
&realnum, value);
|
&realnum, value);
|
||||||
/* NOTE: cagney/2003-05-22: This is assuming that the
|
/* NOTE: cagney/2003-05-22: This is assuming that the
|
||||||
stack pointer was packed as an unsigned integer. That
|
stack pointer was packed as an unsigned integer. That
|
||||||
@ -1223,14 +1224,14 @@ frame_info (char *addr_exp, int from_tty)
|
|||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
need_nl = 0;
|
need_nl = 0;
|
||||||
}
|
}
|
||||||
else if (!optimized && lval == lval_memory)
|
else if (!optimized && !unavailable && lval == lval_memory)
|
||||||
{
|
{
|
||||||
printf_filtered (" Previous frame's sp at ");
|
printf_filtered (" Previous frame's sp at ");
|
||||||
fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
|
fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
need_nl = 0;
|
need_nl = 0;
|
||||||
}
|
}
|
||||||
else if (!optimized && lval == lval_register)
|
else if (!optimized && !unavailable && lval == lval_register)
|
||||||
{
|
{
|
||||||
printf_filtered (" Previous frame's sp in %s\n",
|
printf_filtered (" Previous frame's sp in %s\n",
|
||||||
gdbarch_register_name (gdbarch, realnum));
|
gdbarch_register_name (gdbarch, realnum));
|
||||||
@ -1248,11 +1249,11 @@ frame_info (char *addr_exp, int from_tty)
|
|||||||
{
|
{
|
||||||
/* Find out the location of the saved register without
|
/* Find out the location of the saved register without
|
||||||
fetching the corresponding value. */
|
fetching the corresponding value. */
|
||||||
frame_register_unwind (fi, i, &optimized, &lval, &addr, &realnum,
|
frame_register_unwind (fi, i, &optimized, &unavailable,
|
||||||
NULL);
|
&lval, &addr, &realnum, NULL);
|
||||||
/* For moment, only display registers that were saved on the
|
/* For moment, only display registers that were saved on the
|
||||||
stack. */
|
stack. */
|
||||||
if (!optimized && lval == lval_memory)
|
if (!optimized && !unavailable && lval == lval_memory)
|
||||||
{
|
{
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
puts_filtered (" Saved registers:\n ");
|
puts_filtered (" Saved registers:\n ");
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2011-03-18 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
* gdb.trace/unavailable.exp (fpreg, spreg, pcreg): Define.
|
||||||
|
(test_register, test_register_unavailable): New procedures.
|
||||||
|
(gdb_unavailable_registers_test): New procedure.
|
||||||
|
(gdb_trace_collection_test): Call it.
|
||||||
|
|
||||||
2011-03-18 Phil Muldoon <pmuldoon@redhat.com>
|
2011-03-18 Phil Muldoon <pmuldoon@redhat.com>
|
||||||
|
|
||||||
PR python/12149
|
PR python/12149
|
||||||
|
@ -30,10 +30,48 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
|
|||||||
set ws "\[\r\n\t \]+"
|
set ws "\[\r\n\t \]+"
|
||||||
set cr "\[\r\n\]+"
|
set cr "\[\r\n\]+"
|
||||||
|
|
||||||
|
if [istarget "x86_64-*"] then {
|
||||||
|
set fpreg "rbp"
|
||||||
|
set spreg "rsp"
|
||||||
|
set pcreg "rip"
|
||||||
|
} elseif [istarget "i?86-*"] then {
|
||||||
|
set fpreg "ebp"
|
||||||
|
set spreg "esp"
|
||||||
|
set pcreg "eip"
|
||||||
|
} else {
|
||||||
|
set fpreg "fp"
|
||||||
|
set spreg "sp"
|
||||||
|
set pcreg "pc"
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Utility procs
|
# Utility procs
|
||||||
#
|
#
|
||||||
|
|
||||||
|
proc test_register { reg } {
|
||||||
|
global gdb_prompt
|
||||||
|
global hex
|
||||||
|
global cr
|
||||||
|
|
||||||
|
gdb_test_multiple "print /x $reg" "collected $reg" {
|
||||||
|
-re "\\$\[0-9\]+ = \[x0\]+$cr$gdb_prompt $" {
|
||||||
|
fail "collected $reg (zero)"
|
||||||
|
}
|
||||||
|
-re "\\$\[0-9\]+ = $hex$cr$gdb_prompt $" {
|
||||||
|
pass "collected $reg"
|
||||||
|
}
|
||||||
|
-re "\[Ee\]rror.*$gdb_prompt $" {
|
||||||
|
fail "collected $reg (error)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc test_register_unavailable { reg } {
|
||||||
|
gdb_test "print /x $reg" \
|
||||||
|
"<unavailable>" \
|
||||||
|
"correctly report $reg as unavailable"
|
||||||
|
}
|
||||||
|
|
||||||
proc prepare_for_trace_test {} {
|
proc prepare_for_trace_test {} {
|
||||||
global executable
|
global executable
|
||||||
|
|
||||||
@ -69,6 +107,63 @@ proc run_trace_experiment { test_func } {
|
|||||||
# Test procs
|
# Test procs
|
||||||
#
|
#
|
||||||
|
|
||||||
|
proc gdb_unavailable_registers_test { } {
|
||||||
|
global gdb_prompt
|
||||||
|
global spreg
|
||||||
|
global pcreg
|
||||||
|
global pf_prefix
|
||||||
|
|
||||||
|
set old_pf_prefix $pf_prefix
|
||||||
|
set pf_prefix "$pf_prefix unavailable registers:"
|
||||||
|
|
||||||
|
prepare_for_trace_test
|
||||||
|
|
||||||
|
# We'll simply re-use the globals_test_function for this test
|
||||||
|
gdb_test "trace globals_test_func" \
|
||||||
|
"Tracepoint \[0-9\]+ at .*" \
|
||||||
|
"set tracepoint"
|
||||||
|
|
||||||
|
# Collect nothing.
|
||||||
|
|
||||||
|
# Begin the test.
|
||||||
|
run_trace_experiment globals_test_func
|
||||||
|
|
||||||
|
# On some archs, the $sp/$pc are a real raw registers. On others,
|
||||||
|
# like x86, they're user registers. Test both variants.
|
||||||
|
test_register_unavailable "\$$spreg"
|
||||||
|
test_register_unavailable "\$sp"
|
||||||
|
|
||||||
|
# Test reading uncollected pseudo-registers. The set of which
|
||||||
|
# depends on target.
|
||||||
|
if [istarget "x86_64-*"] then {
|
||||||
|
# Check the raw register first.
|
||||||
|
test_register_unavailable "\$rax"
|
||||||
|
test_register_unavailable "\$eax"
|
||||||
|
test_register_unavailable "\$ax"
|
||||||
|
} elseif [istarget "i?86-*"] then {
|
||||||
|
# Check the raw register first.
|
||||||
|
test_register_unavailable "\$eax"
|
||||||
|
test_register_unavailable "\$ax"
|
||||||
|
}
|
||||||
|
|
||||||
|
# GDBserver always provides the PC value of regular tracepoint
|
||||||
|
# hits, since it's the same as the tracepoint's address.
|
||||||
|
test_register "\$$pcreg"
|
||||||
|
test_register "\$pc"
|
||||||
|
|
||||||
|
gdb_test "info registers" \
|
||||||
|
"\\*value not available\\*.*\\*value not available\\*" \
|
||||||
|
"info registers, multiple registers not available"
|
||||||
|
|
||||||
|
gdb_test "info registers \$$spreg" \
|
||||||
|
"\\*value not available\\*" \
|
||||||
|
"info registers \$$spreg reports not available"
|
||||||
|
|
||||||
|
gdb_test "tfind none" "#0 end .*" "cease trace debugging"
|
||||||
|
|
||||||
|
set pf_prefix $old_pf_prefix
|
||||||
|
}
|
||||||
|
|
||||||
proc gdb_collect_globals_test { } {
|
proc gdb_collect_globals_test { } {
|
||||||
global ws
|
global ws
|
||||||
global cr
|
global cr
|
||||||
@ -321,6 +416,7 @@ proc gdb_collect_globals_test { } {
|
|||||||
|
|
||||||
proc gdb_trace_collection_test {} {
|
proc gdb_trace_collection_test {} {
|
||||||
gdb_collect_globals_test
|
gdb_collect_globals_test
|
||||||
|
gdb_unavailable_registers_test
|
||||||
}
|
}
|
||||||
|
|
||||||
clean_restart $executable
|
clean_restart $executable
|
||||||
|
Reference in New Issue
Block a user