mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
gdb/
* tracepoint.c: Include stack.h. (struct add_local_symbols_data): New. (do_collect_symbol): New. (add_local_symbols): Rewrite using iterate_over_block_arg_vars and iterate_over_block_local_vars. * stack.c (print_block_frame_locals): Rewrite as ... (iterate_over_block_locals): ... this. Take a callback function pointer and generic data pointer, and call that instead of print_variable_and_value. (struct print_variable_and_value_data): New. (do_print_variable_and_value): New. (iterate_over_block_local_vars): New, abstracted out from print_frame_local_vars. (print_frame_local_vars): Rewrite using iterate_over_block_local_vars. (iterate_over_block_arg_vars): New, abstracted out from print_frame_arg_vars. (print_frame_arg_vars): Rewrite using iterate_over_block_arg_vars. * stack.h (iterate_over_block_arg_local_vars_cb): New typedef. (iterate_over_block_arg_vars, iterate_over_block_local_vars): Declare. gdb/testsuite/ * gdb.trace/collection.c (local_test_func): Define a local struct, and instanciate it.
This commit is contained in:
parent
f2faa8006c
commit
2c58c0a9a5
@ -1,3 +1,26 @@
|
||||
2010-04-01 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* tracepoint.c: Include stack.h.
|
||||
(struct add_local_symbols_data): New.
|
||||
(do_collect_symbol): New.
|
||||
(add_local_symbols): Rewrite using iterate_over_block_arg_vars and
|
||||
iterate_over_block_local_vars.
|
||||
* stack.c (print_block_frame_locals): Rewrite as ...
|
||||
(iterate_over_block_locals): ... this. Take a callback function
|
||||
pointer and generic data pointer, and call that instead of
|
||||
print_variable_and_value.
|
||||
(struct print_variable_and_value_data): New.
|
||||
(do_print_variable_and_value): New.
|
||||
(iterate_over_block_local_vars): New, abstracted out from
|
||||
print_frame_local_vars.
|
||||
(print_frame_local_vars): Rewrite using
|
||||
iterate_over_block_local_vars.
|
||||
(iterate_over_block_arg_vars): New, abstracted out from
|
||||
print_frame_arg_vars.
|
||||
(print_frame_arg_vars): Rewrite using iterate_over_block_arg_vars.
|
||||
* stack.h (iterate_over_block_arg_local_vars_cb): New typedef.
|
||||
(iterate_over_block_arg_vars, iterate_over_block_local_vars): Declare.
|
||||
|
||||
2010-03-31 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm-tdep.c (thumb_get_next_pc_raw): Correctly detect TBH
|
||||
|
141
gdb/stack.c
141
gdb/stack.c
@ -1455,17 +1455,16 @@ backtrace_full_command (char *arg, int from_tty)
|
||||
}
|
||||
|
||||
|
||||
/* Print the local variables of a block B active in FRAME on STREAM.
|
||||
Return 1 if any variables were printed; 0 otherwise. */
|
||||
/* Iterate over the local variables of a block B, calling CB with
|
||||
CB_DATA. */
|
||||
|
||||
static int
|
||||
print_block_frame_locals (struct block *b, struct frame_info *frame,
|
||||
int num_tabs, struct ui_file *stream)
|
||||
static void
|
||||
iterate_over_block_locals (struct block *b,
|
||||
iterate_over_block_arg_local_vars_cb cb,
|
||||
void *cb_data)
|
||||
{
|
||||
struct dict_iterator iter;
|
||||
struct symbol *sym;
|
||||
int values_printed = 0;
|
||||
int j;
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
@ -1477,8 +1476,7 @@ print_block_frame_locals (struct block *b, struct frame_info *frame,
|
||||
case LOC_COMPUTED:
|
||||
if (SYMBOL_IS_ARGUMENT (sym))
|
||||
break;
|
||||
values_printed = 1;
|
||||
print_variable_and_value (NULL, sym, frame, stream, 4 * num_tabs);
|
||||
(*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1486,8 +1484,6 @@ print_block_frame_locals (struct block *b, struct frame_info *frame,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return values_printed;
|
||||
}
|
||||
|
||||
|
||||
@ -1539,39 +1535,75 @@ print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print on STREAM all the local variables in frame FRAME, including
|
||||
all the blocks active in that frame at its current PC.
|
||||
/* Iterate over all the local variables in block B, including all its
|
||||
superblocks, stopping when the top-level block is reached. */
|
||||
|
||||
Returns 1 if the job was done, or 0 if nothing was printed because
|
||||
we have no info on the function running in FRAME. */
|
||||
void
|
||||
iterate_over_block_local_vars (struct block *block,
|
||||
iterate_over_block_arg_local_vars_cb cb,
|
||||
void *cb_data)
|
||||
{
|
||||
while (block)
|
||||
{
|
||||
iterate_over_block_locals (block, cb, cb_data);
|
||||
/* After handling the function's top-level block, stop. Don't
|
||||
continue to its superblock, the block of per-file
|
||||
symbols. */
|
||||
if (BLOCK_FUNCTION (block))
|
||||
break;
|
||||
block = BLOCK_SUPERBLOCK (block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Data to be passed around in the calls to the locals and args
|
||||
iterators. */
|
||||
|
||||
struct print_variable_and_value_data
|
||||
{
|
||||
struct frame_info *frame;
|
||||
int num_tabs;
|
||||
struct ui_file *stream;
|
||||
int values_printed;
|
||||
};
|
||||
|
||||
/* The callback for the locals and args iterators */
|
||||
|
||||
static void
|
||||
do_print_variable_and_value (const char *print_name,
|
||||
struct symbol *sym,
|
||||
void *cb_data)
|
||||
{
|
||||
struct print_variable_and_value_data *p = cb_data;
|
||||
|
||||
print_variable_and_value (print_name, sym,
|
||||
p->frame, p->stream, p->num_tabs);
|
||||
p->values_printed = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
print_frame_local_vars (struct frame_info *frame, int num_tabs,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
struct block *block = get_frame_block (frame, 0);
|
||||
int values_printed = 0;
|
||||
struct print_variable_and_value_data cb_data;
|
||||
struct block *block;
|
||||
|
||||
block = get_frame_block (frame, 0);
|
||||
if (block == 0)
|
||||
{
|
||||
fprintf_filtered (stream, "No symbol table info available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (block)
|
||||
{
|
||||
if (print_block_frame_locals (block, frame, num_tabs, stream))
|
||||
values_printed = 1;
|
||||
/* After handling the function's top-level block, stop. Don't
|
||||
continue to its superblock, the block of per-file symbols.
|
||||
Also do not continue to the containing function of an inlined
|
||||
function. */
|
||||
if (BLOCK_FUNCTION (block))
|
||||
break;
|
||||
block = BLOCK_SUPERBLOCK (block);
|
||||
}
|
||||
cb_data.frame = frame;
|
||||
cb_data.num_tabs = 4 * num_tabs;
|
||||
cb_data.stream = stream;
|
||||
cb_data.values_printed = 0;
|
||||
|
||||
if (!values_printed)
|
||||
iterate_over_block_local_vars (block,
|
||||
do_print_variable_and_value,
|
||||
&cb_data);
|
||||
|
||||
if (!cb_data.values_printed)
|
||||
fprintf_filtered (stream, _("No locals.\n"));
|
||||
}
|
||||
|
||||
@ -1668,29 +1700,23 @@ catch_info (char *ignore, int from_tty)
|
||||
0, gdb_stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
|
||||
/* Iterate over all the argument variables in block B.
|
||||
|
||||
Returns 1 if any argument was walked; 0 otherwise. */
|
||||
|
||||
void
|
||||
iterate_over_block_arg_vars (struct block *b,
|
||||
iterate_over_block_arg_local_vars_cb cb,
|
||||
void *cb_data)
|
||||
{
|
||||
struct symbol *func = get_frame_function (frame);
|
||||
struct block *b;
|
||||
struct dict_iterator iter;
|
||||
struct symbol *sym, *sym2;
|
||||
int values_printed = 0;
|
||||
|
||||
if (func == 0)
|
||||
{
|
||||
fprintf_filtered (stream, _("No symbol table info available.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
b = SYMBOL_BLOCK_VALUE (func);
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
/* Don't worry about things which aren't arguments. */
|
||||
if (SYMBOL_IS_ARGUMENT (sym))
|
||||
{
|
||||
values_printed = 1;
|
||||
|
||||
/* We have to look up the symbol because arguments can have
|
||||
two entries (one a parameter, one a local) and the one we
|
||||
want is the local, which lookup_symbol will find for us.
|
||||
@ -1704,12 +1730,33 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
|
||||
|
||||
sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
|
||||
b, VAR_DOMAIN, NULL);
|
||||
print_variable_and_value (SYMBOL_PRINT_NAME (sym), sym2,
|
||||
frame, stream, 0);
|
||||
(*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!values_printed)
|
||||
static void
|
||||
print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
|
||||
{
|
||||
struct print_variable_and_value_data cb_data;
|
||||
struct symbol *func;
|
||||
|
||||
func = get_frame_function (frame);
|
||||
if (func == NULL)
|
||||
{
|
||||
fprintf_filtered (stream, _("No symbol table info available.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
cb_data.frame = frame;
|
||||
cb_data.num_tabs = 0;
|
||||
cb_data.stream = gdb_stdout;
|
||||
cb_data.values_printed = 0;
|
||||
|
||||
iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func),
|
||||
do_print_variable_and_value, &cb_data);
|
||||
|
||||
if (!cb_data.values_printed)
|
||||
fprintf_filtered (stream, _("No arguments.\n"));
|
||||
}
|
||||
|
||||
|
12
gdb/stack.h
12
gdb/stack.h
@ -27,4 +27,16 @@ void select_frame_command (char *level_exp, int from_tty);
|
||||
void find_frame_funname (struct frame_info *frame, char **funname,
|
||||
enum language *funlang);
|
||||
|
||||
typedef void (*iterate_over_block_arg_local_vars_cb) (const char *symbol_print_name,
|
||||
struct symbol *sym,
|
||||
void *cb_data);
|
||||
|
||||
void iterate_over_block_arg_vars (struct block *block,
|
||||
iterate_over_block_arg_local_vars_cb cb,
|
||||
void *cb_data);
|
||||
|
||||
void iterate_over_block_local_vars (struct block *block,
|
||||
iterate_over_block_arg_local_vars_cb cb,
|
||||
void *cb_data);
|
||||
|
||||
#endif /* #ifndef STACK_H */
|
||||
|
@ -1,3 +1,8 @@
|
||||
2010-04-01 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* gdb.trace/collection.c (local_test_func): Define a local struct,
|
||||
and instanciate it.
|
||||
|
||||
2010-04-01 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* gdb.trace/collection.exp (gdb_collect_args_test)
|
||||
|
@ -93,6 +93,7 @@ int local_test_func () /* test collecting locals */
|
||||
test_struct locst;
|
||||
int locar[4];
|
||||
int i;
|
||||
struct localstruct {} locdefst;
|
||||
|
||||
locst.memberc = 15;
|
||||
locst.memberi = 16;
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "objfiles.h"
|
||||
#include "filenames.h"
|
||||
#include "gdbthread.h"
|
||||
#include "stack.h"
|
||||
|
||||
#include "ax.h"
|
||||
#include "ax-gdb.h"
|
||||
@ -1008,40 +1009,77 @@ collect_symbol (struct collection_list *collect,
|
||||
}
|
||||
}
|
||||
|
||||
/* Data to be passed around in the calls to the locals and args
|
||||
iterators. */
|
||||
|
||||
struct add_local_symbols_data
|
||||
{
|
||||
struct collection_list *collect;
|
||||
struct gdbarch *gdbarch;
|
||||
CORE_ADDR pc;
|
||||
long frame_regno;
|
||||
long frame_offset;
|
||||
int count;
|
||||
};
|
||||
|
||||
/* The callback for the locals and args iterators */
|
||||
|
||||
static void
|
||||
do_collect_symbol (const char *print_name,
|
||||
struct symbol *sym,
|
||||
void *cb_data)
|
||||
{
|
||||
struct add_local_symbols_data *p = cb_data;
|
||||
|
||||
collect_symbol (p->collect, sym, p->gdbarch, p->frame_regno,
|
||||
p->frame_offset, p->pc);
|
||||
p->count++;
|
||||
}
|
||||
|
||||
/* Add all locals (or args) symbols to collection list */
|
||||
static void
|
||||
add_local_symbols (struct collection_list *collect,
|
||||
struct gdbarch *gdbarch, CORE_ADDR pc,
|
||||
long frame_regno, long frame_offset, int type)
|
||||
{
|
||||
struct symbol *sym;
|
||||
struct block *block;
|
||||
struct dict_iterator iter;
|
||||
int count = 0;
|
||||
struct add_local_symbols_data cb_data;
|
||||
|
||||
block = block_for_pc (pc);
|
||||
while (block != 0)
|
||||
cb_data.collect = collect;
|
||||
cb_data.gdbarch = gdbarch;
|
||||
cb_data.pc = pc;
|
||||
cb_data.frame_regno = frame_regno;
|
||||
cb_data.frame_offset = frame_offset;
|
||||
cb_data.count = 0;
|
||||
|
||||
if (type == 'L')
|
||||
{
|
||||
QUIT; /* allow user to bail out with ^C */
|
||||
ALL_BLOCK_SYMBOLS (block, iter, sym)
|
||||
block = block_for_pc (pc);
|
||||
if (block == NULL)
|
||||
{
|
||||
if (SYMBOL_IS_ARGUMENT (sym)
|
||||
? type == 'A' /* collecting Arguments */
|
||||
: type == 'L') /* collecting Locals */
|
||||
{
|
||||
count++;
|
||||
collect_symbol (collect, sym, gdbarch,
|
||||
frame_regno, frame_offset, pc);
|
||||
}
|
||||
warning (_("Can't collect locals; "
|
||||
"no symbol table info available.\n"));
|
||||
return;
|
||||
}
|
||||
if (BLOCK_FUNCTION (block))
|
||||
break;
|
||||
else
|
||||
block = BLOCK_SUPERBLOCK (block);
|
||||
|
||||
iterate_over_block_local_vars (block, do_collect_symbol, &cb_data);
|
||||
if (cb_data.count == 0)
|
||||
warning (_("No locals found in scope."));
|
||||
}
|
||||
else
|
||||
{
|
||||
pc = get_pc_function_start (pc);
|
||||
block = block_for_pc (pc);
|
||||
if (block == NULL)
|
||||
{
|
||||
warning (_("Can't collect args; no symbol table info available.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
iterate_over_block_arg_vars (block, do_collect_symbol, &cb_data);
|
||||
if (cb_data.count == 0)
|
||||
warning (_("No args found in scope."));
|
||||
}
|
||||
if (count == 0)
|
||||
warning (_("No %s found in scope."),
|
||||
type == 'L' ? "locals" : "args");
|
||||
}
|
||||
|
||||
/* worker function */
|
||||
|
Loading…
Reference in New Issue
Block a user