* 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:
Pedro Alves
2011-03-18 18:41:36 +00:00
parent e69aa73e27
commit 0fdb4f184b
8 changed files with 189 additions and 35 deletions

View File

@ -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
value. */
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,
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. */
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,
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
function called get_frame_register_p(). This slightly weird (and
older) variant of get_frame_register() returns zero (indicating the
register is unavailable) if either: the register isn't cached; or
the register has been optimized out. Problem is, neither check is
exactly correct. A register can't be optimized out (it may not
have been 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). */
register value is unavailable/invalid) if either: the register
isn't cached; or the register has been optimized out; or the
register contents are unavailable (because they haven't been
collected in a traceframe). Problem is, neither check is exactly
correct. A register can't be optimized out (it may not have been
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,
gdb_byte *buf);