mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-01 06:25:50 +00:00
gdb/
Display @entry parameter values (without references). * dwarf2expr.c (dwarf_block_to_fb_offset, dwarf_block_to_sp_offset): New functions. * dwarf2expr.h (dwarf_block_to_fb_offset, dwarf_block_to_sp_offset): New declarations. * dwarf2loc.c (dwarf2_find_location_expression): Support location list entry record. (dwarf_entry_parameter_to_value, value_of_dwarf_reg_entry) (value_of_dwarf_block_entry, locexpr_read_variable_at_entry): New functions. (dwarf2_locexpr_funcs): Install locexpr_read_variable_at_entry. (loclist_read_variable_at_entry): New function. (dwarf2_loclist_funcs): Install loclist_read_variable_at_entry. * dwarf2read.c (read_call_site_scope): Support also DW_OP_fbreg in DW_AT_location, call dwarf_block_to_sp_offset for it. * frame.h (print_entry_values_no, print_entry_values_only) (print_entry_values_preferred, print_entry_values_if_needed) (print_entry_values_both, print_entry_values_compact) (print_entry_values_default, print_entry_values): New declarations. (struct frame_arg): New field entry_kind. (read_frame_arg): New parameter entryargp. * mi/mi-cmd-stack.c (list_arg_or_local): New gdb_assert for arg->entry_kind. Optionally print the `@entry' suffix. (list_args_or_locals): New variable entryarg, initialize it. Initialize also entry_kind of arg and entryarg. Conditionalize list_arg_or_local for arg, add list_arg_or_local for entryarg. Call xfree for entryarg.error. * stack.c (print_entry_values_no, print_entry_values_only) (print_entry_values_preferred, print_entry_values_if_needed) (print_entry_values_both, print_entry_values_compact) (print_entry_values_default, print_entry_values_choices) (print_entry_values): New variables. (print_frame_arg): New gdb_assert for arg->entry_kind. Optionally print the `@entry' suffix, possibly in combination for print_entry_values_compact. (read_frame_arg): New parameter entryargp, new variables entryval, entryval_error and val_equal. Read in also entryargp, respect print_entry_values, compare the values using val_equal, fill in also argp->entry_kind (together with entryargp->entry_kind). (print_frame_args): New variable entryarg, initialize it. Conditionalize print_frame_arg for arg, add print_frame_arg for entryarg. Call xfree for entryarg.error. (_initialize_stack): Call add_setshow_enum_cmd for `entry-values'. * symtab.h (struct symbol_computed_ops): New field read_variable_at_entry. gdb/doc/ Display @entry parameter values (without references). * gdb.texinfo (Tail Call Frames): Add anchor. Add self tail call example. (Print Settings): New description of set print entry-values and show print entry-values. gdb/testsuite/ Display @entry parameter values (without references). * gdb.arch/amd64-entry-value.cc (locexpr, stacktest, data, data2) (different, validity, invalid): New functions. (main): Call them. * gdb.arch/amd64-entry-value.exp: New breakpoints breakhere_locexpr, stacktest, breakhere_stacktest, different, breakhere_different, breakhere_validity and breakhere_invalid. (entry: bt): Update for @entry. (entry_locexpr: *, entry_stack: *, entry_equal: *, entry_different: *) (entry_validity: *, entry_invalid: *): Many new tests. * gdb.base/break.exp (run until breakpoint set at small function, optimized file): Accept also the @entry suffix. * gdb.mi/Makefile.in (PROGS): Add mi2-amd64-entry-value. * gdb.mi/mi2-amd64-entry-value.c: New files. * gdb.mi/mi2-amd64-entry-value.exp: New files.
This commit is contained in:
parent
93d86cefdf
commit
e18b27534c
@ -1,3 +1,51 @@
|
||||
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Display @entry parameter values (without references).
|
||||
* dwarf2expr.c (dwarf_block_to_fb_offset, dwarf_block_to_sp_offset):
|
||||
New functions.
|
||||
* dwarf2expr.h (dwarf_block_to_fb_offset, dwarf_block_to_sp_offset):
|
||||
New declarations.
|
||||
* dwarf2loc.c (dwarf2_find_location_expression): Support location list
|
||||
entry record.
|
||||
(dwarf_entry_parameter_to_value, value_of_dwarf_reg_entry)
|
||||
(value_of_dwarf_block_entry, locexpr_read_variable_at_entry): New
|
||||
functions.
|
||||
(dwarf2_locexpr_funcs): Install locexpr_read_variable_at_entry.
|
||||
(loclist_read_variable_at_entry): New function.
|
||||
(dwarf2_loclist_funcs): Install loclist_read_variable_at_entry.
|
||||
* dwarf2read.c (read_call_site_scope): Support also DW_OP_fbreg in
|
||||
DW_AT_location, call dwarf_block_to_sp_offset for it.
|
||||
* frame.h (print_entry_values_no, print_entry_values_only)
|
||||
(print_entry_values_preferred, print_entry_values_if_needed)
|
||||
(print_entry_values_both, print_entry_values_compact)
|
||||
(print_entry_values_default, print_entry_values): New declarations.
|
||||
(struct frame_arg): New field entry_kind.
|
||||
(read_frame_arg): New parameter entryargp.
|
||||
* mi/mi-cmd-stack.c (list_arg_or_local): New gdb_assert for
|
||||
arg->entry_kind. Optionally print the `@entry' suffix.
|
||||
(list_args_or_locals): New variable entryarg, initialize it.
|
||||
Initialize also entry_kind of arg and entryarg. Conditionalize
|
||||
list_arg_or_local for arg, add list_arg_or_local for entryarg. Call
|
||||
xfree for entryarg.error.
|
||||
* stack.c (print_entry_values_no, print_entry_values_only)
|
||||
(print_entry_values_preferred, print_entry_values_if_needed)
|
||||
(print_entry_values_both, print_entry_values_compact)
|
||||
(print_entry_values_default, print_entry_values_choices)
|
||||
(print_entry_values): New variables.
|
||||
(print_frame_arg): New gdb_assert for arg->entry_kind. Optionally
|
||||
print the `@entry' suffix, possibly in combination for
|
||||
print_entry_values_compact.
|
||||
(read_frame_arg): New parameter entryargp, new variables entryval,
|
||||
entryval_error and val_equal. Read in also entryargp, respect
|
||||
print_entry_values, compare the values using val_equal, fill in also
|
||||
argp->entry_kind (together with entryargp->entry_kind).
|
||||
(print_frame_args): New variable entryarg, initialize it.
|
||||
Conditionalize print_frame_arg for arg, add print_frame_arg for
|
||||
entryarg. Call xfree for entryarg.error.
|
||||
(_initialize_stack): Call add_setshow_enum_cmd for `entry-values'.
|
||||
* symtab.h (struct symbol_computed_ops): New field
|
||||
read_variable_at_entry.
|
||||
|
||||
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Code reshuffle.
|
||||
|
@ -1,3 +1,12 @@
|
||||
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Display @entry parameter values (without references).
|
||||
* gdb.texinfo (Tail Call Frames): Add anchor. Add self tail call
|
||||
example.
|
||||
(Print Settings): New description of set print entry-values and show
|
||||
print entry-values.
|
||||
|
||||
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
|
@ -7941,6 +7941,120 @@ thus speeding up the display of each Ada frame.
|
||||
@item show print frame-arguments
|
||||
Show how the value of arguments should be displayed when printing a frame.
|
||||
|
||||
@item set print entry-values @var{value}
|
||||
@kindex set print entry-values
|
||||
Set printing of frame argument values at function entry. In some cases
|
||||
@value{GDBN} can determine the value of function argument which was passed by
|
||||
the function caller, even if the value was modified inside the called function
|
||||
and therefore is different. With optimized code, the current value could be
|
||||
unavailable, but the entry value may still be known.
|
||||
|
||||
The default value is @code{default} (see below for its description). Older
|
||||
@value{GDBN} behaved as with the setting @code{no}. Compilers not supporting
|
||||
this feature will behave in the @code{default} setting the same way as with the
|
||||
@code{no} setting.
|
||||
|
||||
This functionality is currently supported only by DWARF 2 debugging format and
|
||||
the compiler has to produce @samp{DW_TAG_GNU_call_site} tags. With
|
||||
@value{NGCC}, you need to specify @option{-O -g} during compilation, to get
|
||||
this information.
|
||||
|
||||
The @var{value} parameter can be one of the following:
|
||||
|
||||
@table @code
|
||||
@item no
|
||||
Print only actual parameter values, never print values from function entry
|
||||
point.
|
||||
@smallexample
|
||||
#0 equal (val=5)
|
||||
#0 different (val=6)
|
||||
#0 lost (val=<optimized out>)
|
||||
#0 born (val=10)
|
||||
#0 invalid (val=<optimized out>)
|
||||
@end smallexample
|
||||
|
||||
@item only
|
||||
Print only parameter values from function entry point. The actual parameter
|
||||
values are never printed.
|
||||
@smallexample
|
||||
#0 equal (val@@entry=5)
|
||||
#0 different (val@@entry=5)
|
||||
#0 lost (val@@entry=5)
|
||||
#0 born (val@@entry=<optimized out>)
|
||||
#0 invalid (val@@entry=<optimized out>)
|
||||
@end smallexample
|
||||
|
||||
@item preferred
|
||||
Print only parameter values from function entry point. If value from function
|
||||
entry point is not known while the actual value is known, print the actual
|
||||
value for such parameter.
|
||||
@smallexample
|
||||
#0 equal (val@@entry=5)
|
||||
#0 different (val@@entry=5)
|
||||
#0 lost (val@@entry=5)
|
||||
#0 born (val=10)
|
||||
#0 invalid (val@@entry=<optimized out>)
|
||||
@end smallexample
|
||||
|
||||
@item if-needed
|
||||
Print actual parameter values. If actual parameter value is not known while
|
||||
value from function entry point is known, print the entry point value for such
|
||||
parameter.
|
||||
@smallexample
|
||||
#0 equal (val=5)
|
||||
#0 different (val=6)
|
||||
#0 lost (val@@entry=5)
|
||||
#0 born (val=10)
|
||||
#0 invalid (val=<optimized out>)
|
||||
@end smallexample
|
||||
|
||||
@item both
|
||||
Always print both the actual parameter value and its value from function entry
|
||||
point, even if values of one or both are not available due to compiler
|
||||
optimizations.
|
||||
@smallexample
|
||||
#0 equal (val=5, val@@entry=5)
|
||||
#0 different (val=6, val@@entry=5)
|
||||
#0 lost (val=<optimized out>, val@@entry=5)
|
||||
#0 born (val=10, val@@entry=<optimized out>)
|
||||
#0 invalid (val=<optimized out>, val@@entry=<optimized out>)
|
||||
@end smallexample
|
||||
|
||||
@item compact
|
||||
Print the actual parameter value if it is known and also its value from
|
||||
function entry point if it is known. If neither is known, print for the actual
|
||||
value @code{<optimized out>}. If not in MI mode (@pxref{GDB/MI}) and if both
|
||||
values are known and identical, print the shortened
|
||||
@code{param=param@@entry=VALUE} notation.
|
||||
@smallexample
|
||||
#0 equal (val=val@@entry=5)
|
||||
#0 different (val=6, val@@entry=5)
|
||||
#0 lost (val@@entry=5)
|
||||
#0 born (val=10)
|
||||
#0 invalid (val=<optimized out>)
|
||||
@end smallexample
|
||||
|
||||
@item default
|
||||
Always print the actual parameter value. Print also its value from function
|
||||
entry point, but only if it is known. If not in MI mode (@pxref{GDB/MI}) and
|
||||
if both values are known and identical, print the shortened
|
||||
@code{param=param@@entry=VALUE} notation.
|
||||
@smallexample
|
||||
#0 equal (val=val@@entry=5)
|
||||
#0 different (val=6, val@@entry=5)
|
||||
#0 lost (val=<optimized out>, val@@entry=5)
|
||||
#0 born (val=10)
|
||||
#0 invalid (val=<optimized out>)
|
||||
@end smallexample
|
||||
@end table
|
||||
|
||||
For analysis messages on possible failures of frame argument values at function
|
||||
entry resolution see @ref{set debug entry-values}.
|
||||
|
||||
@item show print entry-values
|
||||
Show the method being used for printing of frame argument values at function
|
||||
entry.
|
||||
|
||||
@item set print repeats
|
||||
@cindex repeated array elements
|
||||
Set the threshold for suppressing display of repeated array
|
||||
@ -9600,6 +9714,7 @@ tries to show at least all the unambiguous top tail callers and all the
|
||||
unambiguous bottom tail calees, if any.
|
||||
|
||||
@table @code
|
||||
@anchor{set debug entry-values}
|
||||
@item set debug entry-values
|
||||
@kindex set debug entry-values
|
||||
When set to on, enables printing of analysis messages for both frame argument
|
||||
@ -9675,6 +9790,32 @@ also ambigous. The only non-ambiguous frame is the one for function @code{a},
|
||||
therefore this one is displayed to the user while the ambiguous frames are
|
||||
omitted.
|
||||
|
||||
There can be also reasons why printing of frame argument values at function
|
||||
entry may fail:
|
||||
|
||||
@smallexample
|
||||
int v;
|
||||
static void __attribute__((noinline, noclone)) c (int i) @{ v++; @}
|
||||
static void __attribute__((noinline, noclone)) a (int i);
|
||||
static void __attribute__((noinline, noclone)) b (int i) @{ a (i); @}
|
||||
static void __attribute__((noinline, noclone)) a (int i)
|
||||
@{ if (i) b (i - 1); else c (0); @}
|
||||
int main (void) @{ a (5); return 0; @}
|
||||
|
||||
(gdb) bt
|
||||
#0 c (i=i@@entry=0) at t.c:2
|
||||
#1 0x0000000000400428 in a (DW_OP_GNU_entry_value resolving has found
|
||||
function "a" at 0x400420 can call itself via tail calls
|
||||
i=<optimized out>) at t.c:6
|
||||
#2 0x000000000040036e in main () at t.c:7
|
||||
@end smallexample
|
||||
|
||||
@value{GDBN} cannot find out from the inferior state if and how many times did
|
||||
function @code{a} call itself (via function @code{b}) as these calls would be
|
||||
tail calls. Such tail calls would modify thue @code{i} variable, therefore
|
||||
@value{GDBN} cannot be sure the value it knows would be right - @value{GDBN}
|
||||
prints @code{<optimized out>} instead.
|
||||
|
||||
@node Macros
|
||||
@chapter C Preprocessor Macros
|
||||
|
||||
|
@ -518,6 +518,68 @@ dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end)
|
||||
return dwarf_reg;
|
||||
}
|
||||
|
||||
/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_fbreg(X) fill
|
||||
in FB_OFFSET_RETURN with the X offset and return 1. Otherwise return 0. */
|
||||
|
||||
int
|
||||
dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
|
||||
CORE_ADDR *fb_offset_return)
|
||||
{
|
||||
LONGEST fb_offset;
|
||||
|
||||
if (buf_end <= buf)
|
||||
return 0;
|
||||
|
||||
if (*buf != DW_OP_fbreg)
|
||||
return 0;
|
||||
buf++;
|
||||
|
||||
buf = read_sleb128 (buf, buf_end, &fb_offset);
|
||||
*fb_offset_return = fb_offset;
|
||||
if (buf != buf_end || fb_offset != (LONGEST) *fb_offset_return)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_bregSP(X) fill
|
||||
in SP_OFFSET_RETURN with the X offset and return 1. Otherwise return 0.
|
||||
The matched SP register number depends on GDBARCH. */
|
||||
|
||||
int
|
||||
dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
|
||||
const gdb_byte *buf_end, CORE_ADDR *sp_offset_return)
|
||||
{
|
||||
ULONGEST dwarf_reg;
|
||||
LONGEST sp_offset;
|
||||
|
||||
if (buf_end <= buf)
|
||||
return 0;
|
||||
if (*buf >= DW_OP_breg0 && *buf <= DW_OP_breg31)
|
||||
{
|
||||
dwarf_reg = *buf - DW_OP_breg0;
|
||||
buf++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*buf != DW_OP_bregx)
|
||||
return 0;
|
||||
buf++;
|
||||
buf = read_uleb128 (buf, buf_end, &dwarf_reg);
|
||||
}
|
||||
|
||||
if (gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_reg)
|
||||
!= gdbarch_sp_regnum (gdbarch))
|
||||
return 0;
|
||||
|
||||
buf = read_sleb128 (buf, buf_end, &sp_offset);
|
||||
*sp_offset_return = sp_offset;
|
||||
if (buf != buf_end || sp_offset != (LONGEST) *sp_offset_return)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The engine for the expression evaluator. Using the context in CTX,
|
||||
evaluate the expression between OP_PTR and OP_END. */
|
||||
|
||||
|
@ -281,4 +281,11 @@ void ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
|
||||
|
||||
int dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end);
|
||||
|
||||
int dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
|
||||
CORE_ADDR *fb_offset_return);
|
||||
|
||||
int dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
|
||||
const gdb_byte *buf_end,
|
||||
CORE_ADDR *sp_offset_return);
|
||||
|
||||
#endif /* dwarf2expr.h */
|
||||
|
138
gdb/dwarf2loc.c
138
gdb/dwarf2loc.c
@ -121,6 +121,24 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
|
||||
length = extract_unsigned_integer (loc_ptr, 2, byte_order);
|
||||
loc_ptr += 2;
|
||||
|
||||
if (low == high && pc == low)
|
||||
{
|
||||
/* This is entry PC record present only at entry point
|
||||
of a function. Verify it is really the function entry point. */
|
||||
|
||||
struct block *pc_block = block_for_pc (pc);
|
||||
struct symbol *pc_func = NULL;
|
||||
|
||||
if (pc_block)
|
||||
pc_func = block_linkage_function (pc_block);
|
||||
|
||||
if (pc_func && pc == BLOCK_START (SYMBOL_BLOCK_VALUE (pc_func)))
|
||||
{
|
||||
*locexpr_length = length;
|
||||
return loc_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (pc >= low && pc < high)
|
||||
{
|
||||
*locexpr_length = length;
|
||||
@ -892,6 +910,33 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame, int dwarf_reg,
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/* Return value for PARAMETER for DW_AT_GNU_call_site_value.
|
||||
|
||||
TYPE and CALLER_FRAME specify how to evaluate the DWARF block into returned
|
||||
struct value.
|
||||
|
||||
Function always returns non-NULL, non-optimized out value. It throws
|
||||
NO_ENTRY_VALUE_ERROR if it cannot resolve the value for any reason. */
|
||||
|
||||
static struct value *
|
||||
dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
|
||||
struct type *type,
|
||||
struct frame_info *caller_frame,
|
||||
struct dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
gdb_byte *data;
|
||||
|
||||
/* DW_AT_GNU_call_site_value is a DWARF expression, not a DWARF
|
||||
location. Postprocessing of DWARF_VALUE_MEMORY would lose the type from
|
||||
DWARF block. */
|
||||
data = alloca (parameter->value_size + 1);
|
||||
memcpy (data, parameter->value, parameter->value_size);
|
||||
data[parameter->value_size] = DW_OP_stack_value;
|
||||
|
||||
return dwarf2_evaluate_loc_desc (type, caller_frame, data,
|
||||
parameter->value_size + 1, per_cu);
|
||||
}
|
||||
|
||||
/* Execute call_site_parameter's DWARF block for caller of the CTX's frame.
|
||||
CTX must be of dwarf_expr_ctx_funcs kind. See DWARF_REG and FB_OFFSET
|
||||
description at struct dwarf_expr_context_funcs->push_dwarf_reg_entry_value.
|
||||
@ -942,6 +987,58 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
|
||||
ctx->baton = saved_ctx.baton;
|
||||
}
|
||||
|
||||
/* Read parameter of TYPE at (callee) FRAME's function entry. DWARF_REG and
|
||||
FB_OFFSET are used to match DW_AT_location at the caller's
|
||||
DW_TAG_GNU_call_site_parameter. See DWARF_REG and FB_OFFSET description at
|
||||
struct dwarf_expr_context_funcs->push_dwarf_reg_entry_value.
|
||||
|
||||
Function always returns non-NULL value. It throws NO_ENTRY_VALUE_ERROR if it
|
||||
cannot resolve the parameter for any reason. */
|
||||
|
||||
static struct value *
|
||||
value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
|
||||
int dwarf_reg, CORE_ADDR fb_offset)
|
||||
{
|
||||
struct frame_info *caller_frame = get_prev_frame (frame);
|
||||
struct call_site_parameter *parameter;
|
||||
struct dwarf2_per_cu_data *caller_per_cu;
|
||||
|
||||
parameter = dwarf_expr_reg_to_entry_parameter (frame, dwarf_reg, fb_offset,
|
||||
&caller_per_cu);
|
||||
|
||||
return dwarf_entry_parameter_to_value (parameter, type, caller_frame,
|
||||
caller_per_cu);
|
||||
}
|
||||
|
||||
/* Read parameter of TYPE at (callee) FRAME's function entry. DATA and
|
||||
SIZE are DWARF block used to match DW_AT_location at the caller's
|
||||
DW_TAG_GNU_call_site_parameter.
|
||||
|
||||
Function always returns non-NULL value. It throws NO_ENTRY_VALUE_ERROR if it
|
||||
cannot resolve the parameter for any reason. */
|
||||
|
||||
static struct value *
|
||||
value_of_dwarf_block_entry (struct type *type, struct frame_info *frame,
|
||||
const gdb_byte *block, size_t block_len)
|
||||
{
|
||||
int dwarf_reg;
|
||||
CORE_ADDR fb_offset;
|
||||
|
||||
dwarf_reg = dwarf_block_to_dwarf_reg (block, block + block_len);
|
||||
if (dwarf_reg != -1)
|
||||
return value_of_dwarf_reg_entry (type, frame, dwarf_reg, 0 /* unused */);
|
||||
|
||||
if (dwarf_block_to_fb_offset (block, block + block_len, &fb_offset))
|
||||
return value_of_dwarf_reg_entry (type, frame, -1, fb_offset);
|
||||
|
||||
/* This can normally happen - throw NO_ENTRY_VALUE_ERROR to get the message
|
||||
suppressed during normal operation. The expression can be arbitrary if
|
||||
there is no caller-callee entry value binding expected. */
|
||||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||||
_("DWARF-2 expression error: DW_OP_GNU_entry_value is supported "
|
||||
"only for single DW_OP_reg* or for DW_OP_fbreg(*)"));
|
||||
}
|
||||
|
||||
struct piece_closure
|
||||
{
|
||||
/* Reference count. */
|
||||
@ -2853,6 +2950,19 @@ locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Return the value of SYMBOL in FRAME at (callee) FRAME's function
|
||||
entry. SYMBOL should be a function parameter, otherwise NO_ENTRY_VALUE_ERROR
|
||||
will be thrown. */
|
||||
|
||||
static struct value *
|
||||
locexpr_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
|
||||
{
|
||||
struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
|
||||
|
||||
return value_of_dwarf_block_entry (SYMBOL_TYPE (symbol), frame, dlbaton->data,
|
||||
dlbaton->size);
|
||||
}
|
||||
|
||||
/* Return non-zero iff we need a frame to evaluate SYMBOL. */
|
||||
static int
|
||||
locexpr_read_needs_frame (struct symbol *symbol)
|
||||
@ -3494,6 +3604,7 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
|
||||
evaluator. */
|
||||
const struct symbol_computed_ops dwarf2_locexpr_funcs = {
|
||||
locexpr_read_variable,
|
||||
locexpr_read_variable_at_entry,
|
||||
locexpr_read_needs_frame,
|
||||
locexpr_describe_location,
|
||||
locexpr_tracepoint_var_ref
|
||||
@ -3524,6 +3635,32 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Read variable SYMBOL like loclist_read_variable at (callee) FRAME's function
|
||||
entry. SYMBOL should be a function parameter, otherwise NO_ENTRY_VALUE_ERROR
|
||||
will be thrown.
|
||||
|
||||
Function always returns non-NULL value, it may be marked optimized out if
|
||||
inferior frame information is not available. It throws NO_ENTRY_VALUE_ERROR
|
||||
if it cannot resolve the parameter for any reason. */
|
||||
|
||||
static struct value *
|
||||
loclist_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
|
||||
{
|
||||
struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
|
||||
const gdb_byte *data;
|
||||
size_t size;
|
||||
CORE_ADDR pc;
|
||||
|
||||
if (frame == NULL || !get_frame_func_if_available (frame, &pc))
|
||||
return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
|
||||
|
||||
data = dwarf2_find_location_expression (dlbaton, &size, pc);
|
||||
if (data == NULL)
|
||||
return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
|
||||
|
||||
return value_of_dwarf_block_entry (SYMBOL_TYPE (symbol), frame, data, size);
|
||||
}
|
||||
|
||||
/* Return non-zero iff we need a frame to evaluate SYMBOL. */
|
||||
static int
|
||||
loclist_read_needs_frame (struct symbol *symbol)
|
||||
@ -3643,6 +3780,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
|
||||
evaluator and location lists. */
|
||||
const struct symbol_computed_ops dwarf2_loclist_funcs = {
|
||||
loclist_read_variable,
|
||||
loclist_read_variable_at_entry,
|
||||
loclist_read_needs_frame,
|
||||
loclist_describe_location,
|
||||
loclist_tracepoint_var_ref
|
||||
|
@ -6346,10 +6346,13 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
}
|
||||
parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
|
||||
&DW_BLOCK (attr)->data[DW_BLOCK (attr)->size]);
|
||||
if (parameter->dwarf_reg == -1)
|
||||
if (parameter->dwarf_reg == -1
|
||||
&& !dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (attr)->data,
|
||||
&DW_BLOCK (attr)->data[DW_BLOCK (attr)->size],
|
||||
¶meter->fb_offset))
|
||||
{
|
||||
complaint (&symfile_complaints,
|
||||
_("Only single DW_OP_reg is supported "
|
||||
_("Only single DW_OP_reg or DW_OP_fbreg is supported "
|
||||
"for DW_FORM_block* DW_AT_location for "
|
||||
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
|
||||
child_die->offset, cu->objfile->name);
|
||||
|
23
gdb/frame.h
23
gdb/frame.h
@ -712,6 +712,15 @@ extern int frame_register_read (struct frame_info *frame, int regnum,
|
||||
|
||||
/* From stack.c. */
|
||||
|
||||
extern const char print_entry_values_no[];
|
||||
extern const char print_entry_values_only[];
|
||||
extern const char print_entry_values_preferred[];
|
||||
extern const char print_entry_values_if_needed[];
|
||||
extern const char print_entry_values_both[];
|
||||
extern const char print_entry_values_compact[];
|
||||
extern const char print_entry_values_default[];
|
||||
extern const char *print_entry_values;
|
||||
|
||||
/* Inferior function parameter value read in from a frame. */
|
||||
|
||||
struct frame_arg
|
||||
@ -726,10 +735,22 @@ struct frame_arg
|
||||
/* String containing the error message, it is more usually NULL indicating no
|
||||
error occured reading this parameter. */
|
||||
char *error;
|
||||
|
||||
/* One of the print_entry_values_* entries as appropriate specifically for
|
||||
this frame_arg. It will be different from print_entry_values. With
|
||||
print_entry_values_no this frame_arg should be printed as a normal
|
||||
parameter. print_entry_values_only says it should be printed as entry
|
||||
value parameter. print_entry_values_compact says it should be printed as
|
||||
both as a normal parameter and entry values parameter having the same
|
||||
value - print_entry_values_compact is not permitted fi ui_out_is_mi_like_p
|
||||
(in such case print_entry_values_no and print_entry_values_only is used
|
||||
for each parameter kind specifically. */
|
||||
const char *entry_kind;
|
||||
};
|
||||
|
||||
extern void read_frame_arg (struct symbol *sym, struct frame_info *frame,
|
||||
struct frame_arg *argp);
|
||||
struct frame_arg *argp,
|
||||
struct frame_arg *entryargp);
|
||||
|
||||
extern void args_info (char *, int);
|
||||
|
||||
|
@ -256,11 +256,17 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
|| values == PRINT_SIMPLE_VALUES
|
||||
|| (values == PRINT_ALL_VALUES
|
||||
&& (arg->val != NULL || arg->error != NULL)));
|
||||
gdb_assert (arg->entry_kind == print_entry_values_no
|
||||
|| (arg->entry_kind == print_entry_values_only
|
||||
&& (arg->val || arg->error)));
|
||||
|
||||
if (values != PRINT_NO_VALUES || what == all)
|
||||
cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
|
||||
ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (arg->sym));
|
||||
fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb->stream);
|
||||
if (arg->entry_kind == print_entry_values_only)
|
||||
fputs_filtered ("@entry", stb->stream);
|
||||
ui_out_field_stream (uiout, "name", stb);
|
||||
|
||||
if (what == all && SYMBOL_IS_ARGUMENT (arg->sym))
|
||||
ui_out_field_int (uiout, "arg", 1);
|
||||
@ -380,7 +386,7 @@ list_args_or_locals (enum what_to_list what, enum print_values values,
|
||||
if (print_me)
|
||||
{
|
||||
struct symbol *sym2;
|
||||
struct frame_arg arg;
|
||||
struct frame_arg arg, entryarg;
|
||||
|
||||
if (SYMBOL_IS_ARGUMENT (sym))
|
||||
sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
|
||||
@ -391,6 +397,10 @@ list_args_or_locals (enum what_to_list what, enum print_values values,
|
||||
|
||||
memset (&arg, 0, sizeof (arg));
|
||||
arg.sym = sym2;
|
||||
arg.entry_kind = print_entry_values_no;
|
||||
memset (&entryarg, 0, sizeof (entryarg));
|
||||
entryarg.sym = sym2;
|
||||
entryarg.entry_kind = print_entry_values_no;
|
||||
|
||||
switch (values)
|
||||
{
|
||||
@ -401,13 +411,17 @@ list_args_or_locals (enum what_to_list what, enum print_values values,
|
||||
&& TYPE_CODE (type) != TYPE_CODE_UNION)
|
||||
{
|
||||
case PRINT_ALL_VALUES:
|
||||
read_frame_arg (sym2, fi, &arg);
|
||||
read_frame_arg (sym2, fi, &arg, &entryarg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
list_arg_or_local (&arg, what, values);
|
||||
if (arg.entry_kind != print_entry_values_only)
|
||||
list_arg_or_local (&arg, what, values);
|
||||
if (entryarg.entry_kind != print_entry_values_no)
|
||||
list_arg_or_local (&entryarg, what, values);
|
||||
xfree (arg.error);
|
||||
xfree (entryarg.error);
|
||||
}
|
||||
}
|
||||
if (BLOCK_FUNCTION (block))
|
||||
|
205
gdb/stack.c
205
gdb/stack.c
@ -64,6 +64,29 @@ static const char *print_frame_arguments_choices[] =
|
||||
{"all", "scalars", "none", NULL};
|
||||
static const char *print_frame_arguments = "scalars";
|
||||
|
||||
/* The possible choices of "set print entry-values", and the value
|
||||
of this setting. */
|
||||
|
||||
const char print_entry_values_no[] = "no";
|
||||
const char print_entry_values_only[] = "only";
|
||||
const char print_entry_values_preferred[] = "preferred";
|
||||
const char print_entry_values_if_needed[] = "if-needed";
|
||||
const char print_entry_values_both[] = "both";
|
||||
const char print_entry_values_compact[] = "compact";
|
||||
const char print_entry_values_default[] = "default";
|
||||
static const char *print_entry_values_choices[] =
|
||||
{
|
||||
print_entry_values_no,
|
||||
print_entry_values_only,
|
||||
print_entry_values_preferred,
|
||||
print_entry_values_if_needed,
|
||||
print_entry_values_both,
|
||||
print_entry_values_compact,
|
||||
print_entry_values_default,
|
||||
NULL
|
||||
};
|
||||
const char *print_entry_values = print_entry_values_default;
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
static void print_frame_local_vars (struct frame_info *, int,
|
||||
@ -180,12 +203,29 @@ print_frame_arg (const struct frame_arg *arg)
|
||||
old_chain = make_cleanup_ui_out_stream_delete (stb);
|
||||
|
||||
gdb_assert (!arg->val || !arg->error);
|
||||
gdb_assert (arg->entry_kind == print_entry_values_no
|
||||
|| arg->entry_kind == print_entry_values_only
|
||||
|| (!ui_out_is_mi_like_p (uiout)
|
||||
&& arg->entry_kind == print_entry_values_compact));
|
||||
|
||||
annotate_arg_begin ();
|
||||
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (arg->sym),
|
||||
SYMBOL_LANGUAGE (arg->sym), DMGL_PARAMS | DMGL_ANSI);
|
||||
if (arg->entry_kind == print_entry_values_compact)
|
||||
{
|
||||
/* It is OK to provide invalid MI-like stream as with
|
||||
PRINT_ENTRY_VALUE_COMPACT we never use MI. */
|
||||
fputs_filtered ("=", stb->stream);
|
||||
|
||||
fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (arg->sym),
|
||||
SYMBOL_LANGUAGE (arg->sym),
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
}
|
||||
if (arg->entry_kind == print_entry_values_only
|
||||
|| arg->entry_kind == print_entry_values_compact)
|
||||
fputs_filtered ("@entry", stb->stream);
|
||||
ui_out_field_stream (uiout, "name", stb);
|
||||
annotate_arg_name_end ();
|
||||
ui_out_text (uiout, "=");
|
||||
@ -248,25 +288,138 @@ print_frame_arg (const struct frame_arg *arg)
|
||||
|
||||
void
|
||||
read_frame_arg (struct symbol *sym, struct frame_info *frame,
|
||||
struct frame_arg *argp)
|
||||
struct frame_arg *argp, struct frame_arg *entryargp)
|
||||
{
|
||||
struct value *val = NULL;
|
||||
char *val_error = NULL;
|
||||
struct value *val = NULL, *entryval = NULL;
|
||||
char *val_error = NULL, *entryval_error = NULL;
|
||||
int val_equal = 0;
|
||||
volatile struct gdb_exception except;
|
||||
|
||||
TRY_CATCH (except, RETURN_MASK_ERROR)
|
||||
if (print_entry_values != print_entry_values_only
|
||||
&& print_entry_values != print_entry_values_preferred)
|
||||
{
|
||||
val = read_var_value (sym, frame);
|
||||
TRY_CATCH (except, RETURN_MASK_ERROR)
|
||||
{
|
||||
val = read_var_value (sym, frame);
|
||||
}
|
||||
if (!val)
|
||||
{
|
||||
val_error = alloca (strlen (except.message) + 1);
|
||||
strcpy (val_error, except.message);
|
||||
}
|
||||
}
|
||||
if (!val)
|
||||
|
||||
if (SYMBOL_CLASS (sym) == LOC_COMPUTED
|
||||
&& print_entry_values != print_entry_values_no
|
||||
&& (print_entry_values != print_entry_values_if_needed
|
||||
|| !val || value_optimized_out (val)))
|
||||
{
|
||||
val_error = alloca (strlen (except.message) + 1);
|
||||
strcpy (val_error, except.message);
|
||||
TRY_CATCH (except, RETURN_MASK_ERROR)
|
||||
{
|
||||
const struct symbol_computed_ops *ops;
|
||||
|
||||
ops = SYMBOL_COMPUTED_OPS (sym);
|
||||
entryval = ops->read_variable_at_entry (sym, frame);
|
||||
}
|
||||
if (!entryval)
|
||||
{
|
||||
entryval_error = alloca (strlen (except.message) + 1);
|
||||
strcpy (entryval_error, except.message);
|
||||
}
|
||||
|
||||
if (except.error == NO_ENTRY_VALUE_ERROR
|
||||
|| (entryval && value_optimized_out (entryval)))
|
||||
{
|
||||
entryval = NULL;
|
||||
entryval_error = NULL;
|
||||
}
|
||||
|
||||
if (print_entry_values == print_entry_values_compact
|
||||
|| print_entry_values == print_entry_values_default)
|
||||
{
|
||||
/* For MI do not try to use print_entry_values_compact for ARGP. */
|
||||
|
||||
if (val && entryval && !ui_out_is_mi_like_p (current_uiout))
|
||||
{
|
||||
unsigned len = TYPE_LENGTH (value_type (val));
|
||||
|
||||
if (!value_optimized_out (val) && value_lazy (val))
|
||||
value_fetch_lazy (val);
|
||||
if (!value_optimized_out (val) && value_lazy (entryval))
|
||||
value_fetch_lazy (entryval);
|
||||
if (!value_optimized_out (val)
|
||||
&& value_available_contents_eq (val, 0, entryval, 0, len))
|
||||
{
|
||||
entryval = NULL;
|
||||
val_equal = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to remove possibly duplicate error message for ENTRYARGP even
|
||||
in MI mode. */
|
||||
|
||||
if (val_error && entryval_error
|
||||
&& strcmp (val_error, entryval_error) == 0)
|
||||
{
|
||||
entryval_error = NULL;
|
||||
|
||||
/* Do not se VAL_EQUAL as the same error message may be shown for
|
||||
the entry value even if no entry values are present in the
|
||||
inferior. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entryval == NULL)
|
||||
{
|
||||
if (print_entry_values == print_entry_values_preferred)
|
||||
{
|
||||
TRY_CATCH (except, RETURN_MASK_ERROR)
|
||||
{
|
||||
val = read_var_value (sym, frame);
|
||||
}
|
||||
if (!val)
|
||||
{
|
||||
val_error = alloca (strlen (except.message) + 1);
|
||||
strcpy (val_error, except.message);
|
||||
}
|
||||
}
|
||||
if (print_entry_values == print_entry_values_only
|
||||
|| print_entry_values == print_entry_values_both
|
||||
|| (print_entry_values == print_entry_values_preferred
|
||||
&& (!val || value_optimized_out (val))))
|
||||
entryval = allocate_optimized_out_value (SYMBOL_TYPE (sym));
|
||||
}
|
||||
if ((print_entry_values == print_entry_values_compact
|
||||
|| print_entry_values == print_entry_values_if_needed
|
||||
|| print_entry_values == print_entry_values_preferred)
|
||||
&& (!val || value_optimized_out (val)) && entryval != NULL)
|
||||
{
|
||||
val = NULL;
|
||||
val_error = NULL;
|
||||
}
|
||||
|
||||
argp->sym = sym;
|
||||
argp->val = val;
|
||||
argp->error = val_error ? xstrdup (val_error) : NULL;
|
||||
if (!val && !val_error)
|
||||
argp->entry_kind = print_entry_values_only;
|
||||
else if ((print_entry_values == print_entry_values_compact
|
||||
|| print_entry_values == print_entry_values_default) && val_equal)
|
||||
{
|
||||
argp->entry_kind = print_entry_values_compact;
|
||||
gdb_assert (!ui_out_is_mi_like_p (current_uiout));
|
||||
}
|
||||
else
|
||||
argp->entry_kind = print_entry_values_no;
|
||||
|
||||
entryargp->sym = sym;
|
||||
entryargp->val = entryval;
|
||||
entryargp->error = entryval_error ? xstrdup (entryval_error) : NULL;
|
||||
if (!entryval && !entryval_error)
|
||||
entryargp->entry_kind = print_entry_values_no;
|
||||
else
|
||||
entryargp->entry_kind = print_entry_values_only;
|
||||
}
|
||||
|
||||
/* Print the arguments of frame FRAME on STREAM, given the function
|
||||
@ -308,7 +461,7 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
struct frame_arg arg;
|
||||
struct frame_arg arg, entryarg;
|
||||
|
||||
QUIT;
|
||||
|
||||
@ -426,13 +579,30 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
|
||||
{
|
||||
memset (&arg, 0, sizeof (arg));
|
||||
arg.sym = sym;
|
||||
arg.entry_kind = print_entry_values_no;
|
||||
memset (&entryarg, 0, sizeof (entryarg));
|
||||
entryarg.sym = sym;
|
||||
entryarg.entry_kind = print_entry_values_no;
|
||||
}
|
||||
else
|
||||
read_frame_arg (sym, frame, &arg);
|
||||
read_frame_arg (sym, frame, &arg, &entryarg);
|
||||
|
||||
print_frame_arg (&arg);
|
||||
if (arg.entry_kind != print_entry_values_only)
|
||||
print_frame_arg (&arg);
|
||||
|
||||
if (entryarg.entry_kind != print_entry_values_no)
|
||||
{
|
||||
if (arg.entry_kind != print_entry_values_only)
|
||||
{
|
||||
ui_out_text (uiout, ", ");
|
||||
ui_out_wrap_hint (uiout, " ");
|
||||
}
|
||||
|
||||
print_frame_arg (&entryarg);
|
||||
}
|
||||
|
||||
xfree (arg.error);
|
||||
xfree (entryarg.error);
|
||||
|
||||
first = 0;
|
||||
}
|
||||
@ -2313,4 +2483,17 @@ source line."),
|
||||
show_disassemble_next_line,
|
||||
&setlist, &showlist);
|
||||
disassemble_next_line = AUTO_BOOLEAN_FALSE;
|
||||
|
||||
add_setshow_enum_cmd ("entry-values", class_stack,
|
||||
print_entry_values_choices, &print_entry_values,
|
||||
_("Set printing of function arguments at function "
|
||||
"entry"),
|
||||
_("Show printing of function arguments at function "
|
||||
"entry"),
|
||||
_("\
|
||||
GDB can sometimes determine the values of function arguments at entry,\n\
|
||||
in addition to their current values. This option tells GDB whether\n\
|
||||
to print the current value, the value at entry (marked as val@entry),\n\
|
||||
or both. Note that one or both of these values may be <optimized out>."),
|
||||
NULL, NULL, &setprintlist, &showprintlist);
|
||||
}
|
||||
|
@ -533,6 +533,12 @@ struct symbol_computed_ops
|
||||
struct value *(*read_variable) (struct symbol * symbol,
|
||||
struct frame_info * frame);
|
||||
|
||||
/* Read variable SYMBOL like read_variable at (callee) FRAME's function
|
||||
entry. SYMBOL should be a function parameter, otherwise
|
||||
NO_ENTRY_VALUE_ERROR will be thrown. */
|
||||
struct value *(*read_variable_at_entry) (struct symbol *symbol,
|
||||
struct frame_info *frame);
|
||||
|
||||
/* Return non-zero if we need a frame to find the value of the SYMBOL. */
|
||||
int (*read_needs_frame) (struct symbol * symbol);
|
||||
|
||||
|
@ -1,3 +1,22 @@
|
||||
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Display @entry parameter values (without references).
|
||||
* gdb.arch/amd64-entry-value.cc (locexpr, stacktest, data, data2)
|
||||
(different, validity, invalid): New functions.
|
||||
(main): Call them.
|
||||
* gdb.arch/amd64-entry-value.exp: New breakpoints breakhere_locexpr,
|
||||
stacktest, breakhere_stacktest, different, breakhere_different,
|
||||
breakhere_validity and breakhere_invalid.
|
||||
(entry: bt): Update for @entry.
|
||||
(entry_locexpr: *, entry_stack: *, entry_equal: *, entry_different: *)
|
||||
(entry_validity: *, entry_invalid: *): Many new tests.
|
||||
* gdb.base/break.exp
|
||||
(run until breakpoint set at small function, optimized file): Accept
|
||||
also the @entry suffix.
|
||||
* gdb.mi/Makefile.in (PROGS): Add mi2-amd64-entry-value.
|
||||
* gdb.mi/mi2-amd64-entry-value.c: New files.
|
||||
* gdb.mi/mi2-amd64-entry-value.exp: New files.
|
||||
|
||||
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Protect entry values against self tail calls.
|
||||
|
@ -34,6 +34,13 @@ asm ("breakhere:");
|
||||
e (v, v);
|
||||
}
|
||||
|
||||
static void __attribute__((noinline, noclone))
|
||||
locexpr (int i)
|
||||
{
|
||||
i = i;
|
||||
asm ("breakhere_locexpr:");
|
||||
}
|
||||
|
||||
static void __attribute__((noinline, noclone))
|
||||
c (int i, double j)
|
||||
{
|
||||
@ -114,10 +121,68 @@ self (int i)
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((noinline, noclone))
|
||||
stacktest (int r1, int r2, int r3, int r4, int r5, int r6, int s1, int s2,
|
||||
double d1, double d2, double d3, double d4, double d5, double d6,
|
||||
double d7, double d8, double d9, double da)
|
||||
{
|
||||
s1 = 3;
|
||||
s2 = 4;
|
||||
d9 = 3.5;
|
||||
da = 4.5;
|
||||
e (v, v);
|
||||
asm ("breakhere_stacktest:");
|
||||
e (v, v);
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
data (void)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
data2 (void)
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
different (int val)
|
||||
{
|
||||
val++;
|
||||
e (val, val);
|
||||
asm ("breakhere_different:");
|
||||
return val;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
validity (int lost, int born)
|
||||
{
|
||||
lost = data ();
|
||||
e (0, 0.0);
|
||||
asm ("breakhere_validity:");
|
||||
return born;
|
||||
}
|
||||
|
||||
static void __attribute__((noinline, noclone))
|
||||
invalid (int inv)
|
||||
{
|
||||
e (0, 0.0);
|
||||
asm ("breakhere_invalid:");
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
d (30, 30.5);
|
||||
locexpr (30);
|
||||
stacktest (1, 2, 3, 4, 5, 6, 11, 12,
|
||||
1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 11.5, 12.5);
|
||||
different (5);
|
||||
validity (5, data ());
|
||||
invalid (data2 ());
|
||||
|
||||
if (v)
|
||||
a (1, 1.25);
|
||||
else
|
||||
|
@ -35,23 +35,128 @@ if ![runto_main] {
|
||||
}
|
||||
|
||||
gdb_breakpoint "breakhere"
|
||||
gdb_breakpoint "breakhere_locexpr"
|
||||
gdb_breakpoint "stacktest"
|
||||
gdb_breakpoint "breakhere_stacktest"
|
||||
gdb_breakpoint "different"
|
||||
gdb_breakpoint "breakhere_different"
|
||||
gdb_breakpoint "breakhere_validity"
|
||||
gdb_breakpoint "breakhere_invalid"
|
||||
|
||||
|
||||
# Test @entry values for register passed parameters.
|
||||
|
||||
gdb_continue_to_breakpoint "entry: breakhere"
|
||||
|
||||
gdb_test "bt" "^bt\r\n#0 +d *\\(i=31, j=31\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in main .*" \
|
||||
gdb_test "bt" "^bt\r\n#0 +d *\\(i=31, i@entry=30, j=31\\.5, j@entry=30\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in main .*" \
|
||||
"entry: bt"
|
||||
gdb_test "p i" " = 31" "entry: p i"
|
||||
gdb_test "p j" { = 31\.5} "entry: p j"
|
||||
|
||||
|
||||
# Test @entry values when parameter in function is locexpr (and not loclist).
|
||||
|
||||
gdb_continue_to_breakpoint "entry_locexpr: breakhere_locexpr"
|
||||
gdb_test "p i" " = 30" "entry_locexpr: p i"
|
||||
gdb_test_no_output "set variable i = 0" "entry_locexpr: set variable i = 0"
|
||||
gdb_test "bt" "^bt\r\n#0 +locexpr *\\(i=0, i@entry=30\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in main .*" \
|
||||
"entry_locexpr: bt"
|
||||
|
||||
|
||||
# Test @entry values for stack passed parameters.
|
||||
|
||||
gdb_continue_to_breakpoint "entry_stack: stacktest"
|
||||
|
||||
gdb_test "bt" "^bt\r\n#0 +stacktest *\\(r1=r1@entry=1, r2=r2@entry=2, \[^\r\n\]+, s1=s1@entry=11, s2=s2@entry=12, \[^\r\n\]+, d9=d9@entry=11\\.5, da=da@entry=12\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in main .*" \
|
||||
"entry_stack: bt at entry"
|
||||
|
||||
gdb_continue_to_breakpoint "entry_stack: breakhere_stacktest"
|
||||
|
||||
gdb_test "bt" "^bt\r\n#0 +stacktest *\\(r1=r1@entry=1, r2=r2@entry=2, \[^\r\n\]+, s1=3, s1@entry=11, s2=4, s2@entry=12, \[^\r\n\]+, d9=3\\.5, d9@entry=11\\.5, da=4\\.5, da@entry=12\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in main .*" \
|
||||
"entry_stack: bt"
|
||||
|
||||
gdb_test "p s1" " = 3" "entry_stack: p s1"
|
||||
gdb_test "p s2" " = 4" "entry_stack: p s2"
|
||||
gdb_test "p d9" " = 3\\.5" "entry_stack: p d9"
|
||||
gdb_test "p da" " = 4\\.5" "entry_stack: p da"
|
||||
|
||||
|
||||
# Test various kinds of `set print entry-values'.
|
||||
|
||||
gdb_continue_to_breakpoint "entry_equal: breakhere"
|
||||
|
||||
gdb_test_no_output "set print entry-values no" "entry_equal: set print entry-values no"
|
||||
gdb_test "frame" {\(val=5\).*} "entry_equal: frame: no"
|
||||
gdb_test_no_output "set print entry-values only" "entry_equal: set print entry-values only"
|
||||
gdb_test "frame" {\(val@entry=5\).*} "entry_equal: frame: only"
|
||||
gdb_test_no_output "set print entry-values preferred" "entry_equal: set print entry-values preferred"
|
||||
gdb_test "frame" {\(val@entry=5\).*} "entry_equal: frame: preferred"
|
||||
gdb_test_no_output "set print entry-values if-needed" "entry_equal: set print entry-values if-needed"
|
||||
gdb_test "frame" {\(val=5\).*} "entry_equal: frame: if-needed"
|
||||
gdb_test_no_output "set print entry-values both" "entry_equal: set print entry-values both"
|
||||
gdb_test "frame" {\(val=5, val@entry=5\).*} "entry_equal: frame: both"
|
||||
gdb_test_no_output "set print entry-values compact" "entry_equal: set print entry-values compact"
|
||||
gdb_test "frame" {\(val=val@entry=5\).*} "entry_equal: frame: compact"
|
||||
gdb_test_no_output "set print entry-values default" "entry_equal: set print entry-values default"
|
||||
gdb_test "frame" {\(val=val@entry=5\).*} "entry_equal: frame: default"
|
||||
|
||||
gdb_continue_to_breakpoint "entry_different: breakhere"
|
||||
|
||||
gdb_test_no_output "set print entry-values no" "entry_different: set print entry-values no"
|
||||
gdb_test "frame" {\(val=6\).*} "entry_different: frame: no"
|
||||
gdb_test_no_output "set print entry-values only" "entry_different: set print entry-values only"
|
||||
gdb_test "frame" {\(val@entry=5\).*} "entry_different: frame: only"
|
||||
gdb_test_no_output "set print entry-values preferred" "entry_different: set print entry-values preferred"
|
||||
gdb_test "frame" {\(val@entry=5\).*} "entry_different: frame: preferred"
|
||||
gdb_test_no_output "set print entry-values if-needed" "entry_different: set print entry-values if-needed"
|
||||
gdb_test "frame" {\(val=6\).*} "entry_different: frame: if-needed"
|
||||
gdb_test_no_output "set print entry-values both" "entry_different: set print entry-values both"
|
||||
gdb_test "frame" {\(val=6, val@entry=5\).*} "entry_different: frame: both"
|
||||
gdb_test_no_output "set print entry-values compact" "entry_different: set print entry-values compact"
|
||||
gdb_test "frame" {\(val=6, val@entry=5\).*} "entry_different: frame: compact"
|
||||
gdb_test_no_output "set print entry-values default" "entry_different: set print entry-values default"
|
||||
gdb_test "frame" {\(val=6, val@entry=5\).*} "entry_different: frame: default"
|
||||
|
||||
gdb_continue_to_breakpoint "entry_validity: breakhere"
|
||||
|
||||
gdb_test_no_output "set print entry-values no" "entry_validity: set print entry-values no"
|
||||
gdb_test "frame" {\(lost=<optimized out>, born=10\).*} "entry_validity: frame: no"
|
||||
gdb_test_no_output "set print entry-values only" "entry_validity: set print entry-values only"
|
||||
gdb_test "frame" {\(lost@entry=5, born@entry=<optimized out>\).*} "entry_validity: frame: only"
|
||||
gdb_test_no_output "set print entry-values preferred" "entry_validity: set print entry-values preferred"
|
||||
gdb_test "frame" {\(lost@entry=5, born=10\).*} "entry_validity: frame: preferred"
|
||||
gdb_test_no_output "set print entry-values if-needed" "entry_validity: set print entry-values if-needed"
|
||||
gdb_test "frame" {\(lost@entry=5, born=10\).*} "entry_validity: frame: if-needed"
|
||||
gdb_test_no_output "set print entry-values both" "entry_validity: set print entry-values both"
|
||||
gdb_test "frame" {\(lost=<optimized out>, lost@entry=5, born=10, born@entry=<optimized out>\).*} "entry_validity: frame: both"
|
||||
gdb_test_no_output "set print entry-values compact" "entry_validity: set print entry-values compact"
|
||||
gdb_test "frame" {\(lost@entry=5, born=10\).*} "entry_validity: frame: compact"
|
||||
gdb_test_no_output "set print entry-values default" "entry_validity: set print entry-values default"
|
||||
gdb_test "frame" {\(lost=<optimized out>, lost@entry=5, born=10\).*} "entry_validity: frame: default"
|
||||
|
||||
gdb_continue_to_breakpoint "entry_invalid: breakhere"
|
||||
|
||||
gdb_test_no_output "set print entry-values no" "entry_invalid: set print entry-values no"
|
||||
gdb_test "frame" {\(inv=<optimized out>\).*} "entry_invalid: frame: no"
|
||||
gdb_test_no_output "set print entry-values only" "entry_invalid: set print entry-values only"
|
||||
gdb_test "frame" {\(inv@entry=<optimized out>\).*} "entry_invalid: frame: only"
|
||||
gdb_test_no_output "set print entry-values preferred" "entry_invalid: set print entry-values preferred"
|
||||
gdb_test "frame" {\(inv@entry=<optimized out>\).*} "entry_invalid: frame: preferred"
|
||||
gdb_test_no_output "set print entry-values if-needed" "entry_invalid: set print entry-values if-needed"
|
||||
gdb_test "frame" {\(inv=<optimized out>\).*} "entry_invalid: frame: if-needed"
|
||||
gdb_test_no_output "set print entry-values both" "entry_invalid: set print entry-values both"
|
||||
gdb_test "frame" {\(inv=<optimized out>, inv@entry=<optimized out>\).*} "entry_invalid: frame: both"
|
||||
gdb_test_no_output "set print entry-values compact" "entry_invalid: set print entry-values compact"
|
||||
gdb_test "frame" {\(inv=<optimized out>\).*} "entry_invalid: frame: compact"
|
||||
gdb_test_no_output "set print entry-values default" "entry_invalid: set print entry-values default"
|
||||
gdb_test "frame" {\(inv=<optimized out>\).*} "entry_invalid: frame: default"
|
||||
|
||||
|
||||
# Test virtual tail call frames.
|
||||
|
||||
gdb_continue_to_breakpoint "tailcall: breakhere"
|
||||
|
||||
gdb_test "bt" "^bt\r\n#0 +d *\\(i=71, j=73\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in c \\(i=7, j=7\\.25\\) \[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in b \\(i=5, j=5\\.25\\) \[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in main \[^\r\n\]*" \
|
||||
gdb_test "bt" "^bt\r\n#0 +d *\\(i=71, i@entry=70, j=73\\.5, j@entry=72\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in c \\(i=i@entry=7, j=j@entry=7\\.25\\) \[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in b \\(i=i@entry=5, j=j@entry=5\\.25\\) \[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in main \[^\r\n\]*" \
|
||||
"tailcall: bt"
|
||||
gdb_test "p i" " = 71" "tailcall: p i"
|
||||
gdb_test "p j" " = 73\\.5" "tailcall: p j"
|
||||
@ -71,7 +176,7 @@ gdb_test {p $sp0 + sizeof (void *) == $sp} " = true"
|
||||
|
||||
gdb_continue_to_breakpoint "ambiguous: breakhere"
|
||||
|
||||
gdb_test "bt" "^bt\r\n#0 +d \\(i=<optimized out>, j=<optimized out>\\)\[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in amb_z \\(i=<optimized out>\\)\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in amb_y \\(i=<optimized out>\\)\[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in amb_x \\(i=<optimized out>\\)\[^\r\n\]*\r\n#4 +0x\[0-9a-f\]+ in amb_b \\(i=101\\)\[^\r\n\]*\r\n#5 +0x\[0-9a-f\]+ in amb_a \\(i=100\\)\[^\r\n\]*\r\n#6 +0x\[0-9a-f\]+ in main \\(\\)\[^\r\n\]*" \
|
||||
gdb_test "bt" "^bt\r\n#0 +d \\(i=<optimized out>, j=<optimized out>\\)\[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in amb_z \\(i=<optimized out>\\)\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in amb_y \\(i=<optimized out>\\)\[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in amb_x \\(i=<optimized out>\\)\[^\r\n\]*\r\n#4 +0x\[0-9a-f\]+ in amb_b \\(i=i@entry=101\\)\[^\r\n\]*\r\n#5 +0x\[0-9a-f\]+ in amb_a \\(i=i@entry=100\\)\[^\r\n\]*\r\n#6 +0x\[0-9a-f\]+ in main \\(\\)\[^\r\n\]*" \
|
||||
"ambiguous: bt"
|
||||
|
||||
|
||||
|
@ -916,13 +916,13 @@ set bp_location14 [gdb_get_line_number "set breakpoint 14 here" $srcfile1]
|
||||
|
||||
gdb_test_multiple "continue" \
|
||||
"run until breakpoint set at small function, optimized file" {
|
||||
-re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile1:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
|
||||
-re "Breakpoint $decimal, marker4 \\(d=(d@entry=)?177601976\\) at .*$srcfile1:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
|
||||
pass "run until breakpoint set at small function, optimized file"
|
||||
}
|
||||
-re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile1:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
|
||||
-re "Breakpoint $decimal, $hex in marker4 \\(d=(d@entry=)?177601976\\) at .*$srcfile1:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
|
||||
pass "run until breakpoint set at small function, optimized file"
|
||||
}
|
||||
-re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile1:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" {
|
||||
-re "Breakpoint $decimal, marker4 \\(d=(d@entry=)?177601976\\) at .*$srcfile1:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" {
|
||||
# marker4() is defined at line 46 when compiled with -DPROTOTYPES
|
||||
pass "run until breakpoint set at small function, optimized file (line bp_location14)"
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ PROGS = basics c_variable cpp_variable var-cmd dw2-ref-missing-frame \
|
||||
mi-pending mi-pthreads mi-read-memory mi-regs mi-return \
|
||||
mi-reverse mi-simplerun mi-stack mi-stepi mi-syn-frame \
|
||||
mi-var-block mi-var-child mi-var-cmd mi-var-cp mi-var-display \
|
||||
mi-var-invalidate mi-var-invalidate_bis mi-watch mi2-basics \
|
||||
mi-var-invalidate mi-var-invalidate_bis mi-watch \
|
||||
mi2-amd64-entry-value mi2-basics \
|
||||
mi2-break mi2-cli mi2-disassemble mi2-eval mi2-file \
|
||||
mi2-pthreads mi2-regs mi2-return mi2-simplerun mi2-stepi \
|
||||
mi2-var-block mi2-var-child mi2-var-cmd mi2-var-display \
|
||||
|
70
gdb/testsuite/gdb.mi/mi2-amd64-entry-value.c
Normal file
70
gdb/testsuite/gdb.mi/mi2-amd64-entry-value.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2011 Free Software Foundation, Inc.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
static volatile int v;
|
||||
|
||||
static void __attribute__((noinline, noclone))
|
||||
e (int i, double j)
|
||||
{
|
||||
v = 0;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
data (void)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
data2 (void)
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
different (int val)
|
||||
{
|
||||
val++;
|
||||
e (val, val);
|
||||
asm ("breakhere_different:");
|
||||
return val;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline, noclone))
|
||||
validity (int lost, int born)
|
||||
{
|
||||
lost = data ();
|
||||
e (0, 0.0);
|
||||
asm ("breakhere_validity:");
|
||||
return born;
|
||||
}
|
||||
|
||||
static void __attribute__((noinline, noclone))
|
||||
invalid (int inv)
|
||||
{
|
||||
e (0, 0.0);
|
||||
asm ("breakhere_invalid:");
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
different (5);
|
||||
validity (5, data ());
|
||||
invalid (data2 ());
|
||||
return 0;
|
||||
}
|
171
gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp
Normal file
171
gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp
Normal file
@ -0,0 +1,171 @@
|
||||
# Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib mi-support.exp
|
||||
set MIFLAGS "-i=mi2"
|
||||
|
||||
gdb_exit
|
||||
if [mi_gdb_start] {
|
||||
continue
|
||||
}
|
||||
|
||||
set testfile mi2-amd64-entry-value
|
||||
set srcfile ${testfile}.s
|
||||
set opts {}
|
||||
|
||||
if [info exists COMPILE] {
|
||||
# make check RUNTESTFLAGS="gdb.mi/mi2-amd64-entry-value.exp COMPILE=1"
|
||||
set srcfile ${testfile}.c
|
||||
lappend opts debug optimize=-O2
|
||||
} elseif { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
|
||||
verbose "Skipping mi2-amd64-entry-value."
|
||||
return
|
||||
}
|
||||
|
||||
set executable ${testfile}
|
||||
set binfile ${objdir}/${subdir}/${executable}
|
||||
|
||||
if [build_executable ${testfile}.exp ${executable} ${srcfile} $opts] {
|
||||
return -1
|
||||
}
|
||||
|
||||
mi_gdb_reinitialize_dir $srcdir/$subdir
|
||||
mi_gdb_load ${binfile}
|
||||
|
||||
foreach name {different breakhere_different breakhere_validity breakhere_invalid} {
|
||||
mi_create_breakpoint $name .* .* .* .* .* .* "break $name"
|
||||
}
|
||||
|
||||
|
||||
# Test various kinds of `set print entry-values'.
|
||||
|
||||
if {[mi_runto main] == -1} {
|
||||
return -1
|
||||
}
|
||||
mi_gdb_test "-gdb-set print entry-values no" {\^done} "no: set print entry-values"
|
||||
mi_send_resuming_command "exec-continue" "no: entry_equal: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="5"}} .* .* {.* disp="keep"} "no: entry_equal: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="5"}\]} "no: entry_equal: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "no: entry_different: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="6"}} .* .* {.* disp="keep"} "no: entry_different: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="6"}\]} "no: entry_different: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "no: validity: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="lost",value="<optimized out>"},{name="born",value="10"}} .* .* {.* disp="keep"} "no: validity: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="lost",arg="1",value="<optimized out>"},{name="born",arg="1",value="10"}\]} "no: validity: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "no: invalid: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="inv",value="<optimized out>"}} .* .* {.* disp="keep"} "no: invalid: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="inv",arg="1",value="<optimized out>"}\]} "no: invalid: -stack-list-variables"
|
||||
|
||||
if {[mi_runto main] == -1} {
|
||||
return -1
|
||||
}
|
||||
mi_gdb_test "-gdb-set print entry-values only" {\^done} "only: set print entry-values"
|
||||
mi_send_resuming_command "exec-continue" "only: entry_equal: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val@entry",value="5"}} .* .* {.* disp="keep"} "only: entry_equal: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val@entry",arg="1",value="5"}\]} "only: entry_equal: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "only: entry_different: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val@entry",value="5"}} .* .* {.* disp="keep"} "only: entry_different: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val@entry",arg="1",value="5"}\]} "only: entry_different: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "only: validity: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="lost@entry",value="5"},{name="born@entry",value="<optimized out>"}} .* .* {.* disp="keep"} "only: validity: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="lost@entry",arg="1",value="5"},{name="born@entry",arg="1",value="<optimized out>"}\]} "only: validity: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "only: invalid: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="inv@entry",value="<optimized out>"}} .* .* {.* disp="keep"} "only: invalid: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="inv@entry",arg="1",value="<optimized out>"}\]} "only: invalid: -stack-list-variables"
|
||||
|
||||
if {[mi_runto main] == -1} {
|
||||
return -1
|
||||
}
|
||||
mi_gdb_test "-gdb-set print entry-values preferred" {\^done} "preferred: set print entry-values"
|
||||
mi_send_resuming_command "exec-continue" "preferred: entry_equal: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val@entry",value="5"}} .* .* {.* disp="keep"} "preferred: entry_equal: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val@entry",arg="1",value="5"}\]} "preferred: entry_equal: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "preferred: entry_different: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val@entry",value="5"}} .* .* {.* disp="keep"} "preferred: entry_different: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val@entry",arg="1",value="5"}\]} "preferred: entry_different: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "preferred: validity: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="lost@entry",value="5"},{name="born",value="10"}} .* .* {.* disp="keep"} "preferred: validity: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="lost@entry",arg="1",value="5"},{name="born",arg="1",value="10"}\]} "preferred: validity: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "preferred: invalid: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="inv@entry",value="<optimized out>"}} .* .* {.* disp="keep"} "preferred: invalid: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="inv@entry",arg="1",value="<optimized out>"}\]} "preferred: invalid: -stack-list-variables"
|
||||
|
||||
if {[mi_runto main] == -1} {
|
||||
return -1
|
||||
}
|
||||
mi_gdb_test "-gdb-set print entry-values if-needed" {\^done} "if-needed: set print entry-values"
|
||||
mi_send_resuming_command "exec-continue" "if-needed: entry_equal: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="5"}} .* .* {.* disp="keep"} "if-needed: entry_equal: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="5"}\]} "if-needed: entry_equal: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "if-needed: entry_different: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="6"}} .* .* {.* disp="keep"} "if-needed: entry_different: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="6"}\]} "if-needed: entry_different: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "if-needed: validity: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="lost@entry",value="5"},{name="born",value="10"}} .* .* {.* disp="keep"} "if-needed: validity: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="lost@entry",arg="1",value="5"},{name="born",arg="1",value="10"}\]} "if-needed: validity: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "if-needed: invalid: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="inv",value="<optimized out>"}} .* .* {.* disp="keep"} "if-needed: invalid: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="inv",arg="1",value="<optimized out>"}\]} "if-needed: invalid: -stack-list-variables"
|
||||
|
||||
if {[mi_runto main] == -1} {
|
||||
return -1
|
||||
}
|
||||
mi_gdb_test "-gdb-set print entry-values both" {\^done} "both: set print entry-values"
|
||||
mi_send_resuming_command "exec-continue" "both: entry_equal: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="5"},{name="val@entry",value="5"}} .* .* {.* disp="keep"} "both: entry_equal: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="5"},{name="val@entry",arg="1",value="5"}\]} "both: entry_equal: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "both: entry_different: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="6"},{name="val@entry",value="5"}} .* .* {.* disp="keep"} "both: entry_different: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="6"},{name="val@entry",arg="1",value="5"}\]} "both: entry_different: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "both: validity: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="lost",value="<optimized out>"},{name="lost@entry",value="5"},{name="born",value="10"},{name="born@entry",value="<optimized out>"}} .* .* {.* disp="keep"} "both: validity: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="lost",arg="1",value="<optimized out>"},{name="lost@entry",arg="1",value="5"},{name="born",arg="1",value="10"},{name="born@entry",arg="1",value="<optimized out>"}\]} "both: validity: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "both: invalid: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="inv",value="<optimized out>"},{name="inv@entry",value="<optimized out>"}} .* .* {.* disp="keep"} "both: invalid: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="inv",arg="1",value="<optimized out>"},{name="inv@entry",arg="1",value="<optimized out>"}\]} "both: invalid: -stack-list-variables"
|
||||
|
||||
if {[mi_runto main] == -1} {
|
||||
return -1
|
||||
}
|
||||
mi_gdb_test "-gdb-set print entry-values compact" {\^done} "compact: set print entry-values"
|
||||
mi_send_resuming_command "exec-continue" "compact: entry_equal: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="5"},{name="val@entry",value="5"}} .* .* {.* disp="keep"} "compact: entry_equal: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="5"},{name="val@entry",arg="1",value="5"}\]} "compact: entry_equal: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "compact: entry_different: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="6"},{name="val@entry",value="5"}} .* .* {.* disp="keep"} "compact: entry_different: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="6"},{name="val@entry",arg="1",value="5"}\]} "compact: entry_different: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "compact: validity: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="lost@entry",value="5"},{name="born",value="10"}} .* .* {.* disp="keep"} "compact: validity: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="lost@entry",arg="1",value="5"},{name="born",arg="1",value="10"}\]} "compact: validity: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "compact: invalid: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="inv",value="<optimized out>"}} .* .* {.* disp="keep"} "compact: invalid: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="inv",arg="1",value="<optimized out>"}\]} "compact: invalid: -stack-list-variables"
|
||||
|
||||
if {[mi_runto main] == -1} {
|
||||
return -1
|
||||
}
|
||||
mi_gdb_test "-gdb-set print entry-values default" {\^done} "default: set print entry-values"
|
||||
mi_send_resuming_command "exec-continue" "default: entry_equal: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="5"},{name="val@entry",value="5"}} .* .* {.* disp="keep"} "default: entry_equal: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="5"},{name="val@entry",arg="1",value="5"}\]} "default: entry_equal: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "default: entry_different: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="val",value="6"},{name="val@entry",value="5"}} .* .* {.* disp="keep"} "default: entry_different: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="val",arg="1",value="6"},{name="val@entry",arg="1",value="5"}\]} "default: entry_different: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "default: validity: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="lost",value="<optimized out>"},{name="lost@entry",value="5"},{name="born",value="10"}} .* .* {.* disp="keep"} "default: validity: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="lost",arg="1",value="<optimized out>"},{name="lost@entry",arg="1",value="5"},{name="born",arg="1",value="10"}\]} "default: validity: -stack-list-variables"
|
||||
mi_send_resuming_command "exec-continue" "default: invalid: continue"
|
||||
mi_expect_stop "breakpoint-hit" .* {{name="inv",value="<optimized out>"}} .* .* {.* disp="keep"} "default: invalid: stop"
|
||||
mi_gdb_test "-stack-list-variables --all-values" {\^done,variables=\[{name="inv",arg="1",value="<optimized out>"}\]} "default: invalid: -stack-list-variables"
|
Loading…
x
Reference in New Issue
Block a user