mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-02 02:35:00 +08:00
all remaining *.c *.h files from hp merge.
This commit is contained in:
644
gdb/stack.c
644
gdb/stack.c
@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include "defs.h"
|
||||
#include "gdb_string.h"
|
||||
#include "value.h"
|
||||
@ -53,13 +53,17 @@ static void return_command PARAMS ((char *, int));
|
||||
|
||||
static void down_command PARAMS ((char *, int));
|
||||
|
||||
static void down_silently_base PARAMS ((char *));
|
||||
|
||||
static void down_silently_command PARAMS ((char *, int));
|
||||
|
||||
static void up_command PARAMS ((char *, int));
|
||||
|
||||
static void up_silently_base PARAMS ((char *));
|
||||
|
||||
static void up_silently_command PARAMS ((char *, int));
|
||||
|
||||
static void frame_command PARAMS ((char *, int));
|
||||
void frame_command PARAMS ((char *, int));
|
||||
|
||||
static void select_frame_command PARAMS ((char *, int));
|
||||
|
||||
@ -67,21 +71,31 @@ static void print_frame_arg_vars PARAMS ((struct frame_info *, GDB_FILE *));
|
||||
|
||||
static void catch_info PARAMS ((char *, int));
|
||||
|
||||
static void print_frame_label_vars PARAMS ((struct frame_info *, int,
|
||||
static void args_plus_locals_info PARAMS ((char *, int));
|
||||
|
||||
static void print_frame_label_vars PARAMS ((struct frame_info *,
|
||||
int,
|
||||
GDB_FILE *));
|
||||
|
||||
static void print_frame_local_vars PARAMS ((struct frame_info *, GDB_FILE *));
|
||||
static void print_frame_local_vars PARAMS ((struct frame_info *,
|
||||
int,
|
||||
GDB_FILE *));
|
||||
|
||||
static int print_block_frame_labels PARAMS ((struct block *, int *,
|
||||
GDB_FILE *));
|
||||
|
||||
static int print_block_frame_locals PARAMS ((struct block *,
|
||||
struct frame_info *,
|
||||
int,
|
||||
GDB_FILE *));
|
||||
|
||||
static void print_frame_info_base PARAMS ((struct frame_info *, int, int, int));
|
||||
|
||||
static void print_stack_frame_base PARAMS ((struct frame_info *, int, int));
|
||||
|
||||
static void backtrace_command PARAMS ((char *, int));
|
||||
|
||||
static struct frame_info *parse_frame_specification PARAMS ((char *));
|
||||
struct frame_info *parse_frame_specification PARAMS ((char *));
|
||||
|
||||
static void frame_info PARAMS ((char *, int));
|
||||
|
||||
@ -116,21 +130,122 @@ struct print_stack_frame_args {
|
||||
int args;
|
||||
};
|
||||
|
||||
static int print_stack_frame_stub PARAMS ((char *));
|
||||
static int print_stack_frame_base_stub PARAMS ((char *));
|
||||
|
||||
/* Pass the args the way catch_errors wants them. */
|
||||
/* Show and print the frame arguments.
|
||||
Pass the args the way catch_errors wants them. */
|
||||
static int
|
||||
show_and_print_stack_frame_stub (args)
|
||||
char *args;
|
||||
{
|
||||
struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
|
||||
|
||||
/* Reversed order of these so tuiDo() doesn't occur
|
||||
* in the middle of "Breakpoint 1 ... [location]" printing = RT
|
||||
*/
|
||||
if (tui_version)
|
||||
print_frame_info_base (p->fi, p->level, p->source, p->args);
|
||||
print_frame_info (p->fi, p->level, p->source, p->args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Show or print the frame arguments.
|
||||
Pass the args the way catch_errors wants them. */
|
||||
static int
|
||||
print_stack_frame_stub (args)
|
||||
char *args;
|
||||
{
|
||||
struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
|
||||
|
||||
print_frame_info (p->fi, p->level, p->source, p->args);
|
||||
if (tui_version)
|
||||
print_frame_info (p->fi, p->level, p->source, p->args);
|
||||
else
|
||||
print_frame_info_base (p->fi, p->level, p->source, p->args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print a stack frame briefly. FRAME_INFI should be the frame info
|
||||
and LEVEL should be its level in the stack (or -1 for level not defined).
|
||||
|
||||
/* Pass the args the way catch_errors wants them. */
|
||||
static int
|
||||
print_stack_frame_base_stub (args)
|
||||
char *args;
|
||||
{
|
||||
struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
|
||||
|
||||
print_frame_info_base (p->fi, p->level, p->source, p->args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* print the frame arguments to the terminal.
|
||||
Pass the args the way catch_errors wants them. */
|
||||
static int
|
||||
print_only_stack_frame_stub (args)
|
||||
char *args;
|
||||
{
|
||||
struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
|
||||
|
||||
print_frame_info_base (p->fi, p->level, p->source, p->args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print a stack frame briefly. FRAME_INFI should be the frame info
|
||||
and LEVEL should be its level in the stack (or -1 for level not defined).
|
||||
This prints the level, the function executing, the arguments,
|
||||
and the file name and line number.
|
||||
If the pc is not at the beginning of the source line,
|
||||
the actual pc is printed at the beginning.
|
||||
|
||||
If SOURCE is 1, print the source line as well.
|
||||
If SOURCE is -1, print ONLY the source line. */
|
||||
|
||||
static void
|
||||
print_stack_frame_base (fi, level, source)
|
||||
struct frame_info *fi;
|
||||
int level;
|
||||
int source;
|
||||
{
|
||||
struct print_stack_frame_args args;
|
||||
|
||||
args.fi = fi;
|
||||
args.level = level;
|
||||
args.source = source;
|
||||
args.args = 1;
|
||||
|
||||
catch_errors (print_stack_frame_stub, (char *)&args, "", RETURN_MASK_ALL);
|
||||
}
|
||||
|
||||
/* Show and print a stack frame briefly. FRAME_INFI should be the frame info
|
||||
and LEVEL should be its level in the stack (or -1 for level not defined).
|
||||
This prints the level, the function executing, the arguments,
|
||||
and the file name and line number.
|
||||
If the pc is not at the beginning of the source line,
|
||||
the actual pc is printed at the beginning.
|
||||
|
||||
If SOURCE is 1, print the source line as well.
|
||||
If SOURCE is -1, print ONLY the source line. */
|
||||
|
||||
void
|
||||
show_and_print_stack_frame (fi, level, source)
|
||||
struct frame_info *fi;
|
||||
int level;
|
||||
int source;
|
||||
{
|
||||
struct print_stack_frame_args args;
|
||||
|
||||
args.fi = fi;
|
||||
args.level = level;
|
||||
args.source = source;
|
||||
args.args = 1;
|
||||
|
||||
catch_errors (show_and_print_stack_frame_stub, (char *)&args, "", RETURN_MASK_ALL);
|
||||
}
|
||||
|
||||
|
||||
/* Show or print a stack frame briefly. FRAME_INFI should be the frame info
|
||||
and LEVEL should be its level in the stack (or -1 for level not defined).
|
||||
This prints the level, the function executing, the arguments,
|
||||
and the file name and line number.
|
||||
If the pc is not at the beginning of the source line,
|
||||
@ -155,6 +270,33 @@ print_stack_frame (fi, level, source)
|
||||
catch_errors (print_stack_frame_stub, (char *)&args, "", RETURN_MASK_ALL);
|
||||
}
|
||||
|
||||
/* Print a stack frame briefly. FRAME_INFI should be the frame info
|
||||
and LEVEL should be its level in the stack (or -1 for level not defined).
|
||||
This prints the level, the function executing, the arguments,
|
||||
and the file name and line number.
|
||||
If the pc is not at the beginning of the source line,
|
||||
the actual pc is printed at the beginning.
|
||||
|
||||
If SOURCE is 1, print the source line as well.
|
||||
If SOURCE is -1, print ONLY the source line. */
|
||||
|
||||
void
|
||||
print_only_stack_frame (fi, level, source)
|
||||
struct frame_info *fi;
|
||||
int level;
|
||||
int source;
|
||||
{
|
||||
struct print_stack_frame_args args;
|
||||
|
||||
args.fi = fi;
|
||||
args.level = level;
|
||||
args.source = source;
|
||||
args.args = 1;
|
||||
|
||||
catch_errors (print_only_stack_frame_stub,
|
||||
(char *)&args, "", RETURN_MASK_ALL);
|
||||
}
|
||||
|
||||
struct print_args_args {
|
||||
struct symbol *func;
|
||||
struct frame_info *fi;
|
||||
@ -176,13 +318,20 @@ print_args_stub (args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* LEVEL is the level of the frame, or -1 if it is the innermost frame
|
||||
but we don't want to print the level. */
|
||||
/* Print information about a frame for frame "fi" at level "level".
|
||||
* Used in "where" output, also used to emit breakpoint or step messages.
|
||||
* LEVEL is the level of the frame, or -1 if it is the innermost frame
|
||||
* but we don't want to print the level.
|
||||
* The meaning of the SOURCE argument is:
|
||||
* -1: Print only source line
|
||||
* 0: Print only location
|
||||
* 1: Print location and source line
|
||||
*/
|
||||
|
||||
void
|
||||
print_frame_info (fi, level, source, args)
|
||||
static void
|
||||
print_frame_info_base (fi, level, source, args)
|
||||
struct frame_info *fi;
|
||||
register int level;
|
||||
int level;
|
||||
int source;
|
||||
int args;
|
||||
{
|
||||
@ -288,8 +437,31 @@ print_frame_info (fi, level, source, args)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* I'd like to use SYMBOL_SOURCE_NAME() here, to display
|
||||
* the demangled name that we already have stored in
|
||||
* the symbol table, but we stored a version with
|
||||
* DMGL_PARAMS turned on, and here we don't want
|
||||
* to display parameters. So call the demangler again,
|
||||
* with DMGL_ANSI only. RT
|
||||
* (Yes, I know that printf_symbol_filtered() will
|
||||
* again try to demangle the name on the fly, but
|
||||
* the issue is that if cplus_demangle() fails here,
|
||||
* it'll fail there too. So we want to catch the failure
|
||||
* ("demangled==NULL" case below) here, while we still
|
||||
* have our hands on the function symbol.)
|
||||
*/
|
||||
char * demangled;
|
||||
funname = SYMBOL_NAME (func);
|
||||
funlang = SYMBOL_LANGUAGE (func);
|
||||
if (funlang == language_cplus) {
|
||||
demangled = cplus_demangle (funname, DMGL_ANSI);
|
||||
if (demangled == NULL)
|
||||
/* If the demangler fails, try the demangled name
|
||||
* from the symbol table. This'll have parameters,
|
||||
* but that's preferable to diplaying a mangled name.
|
||||
*/
|
||||
funname = SYMBOL_SOURCE_NAME (func);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -357,7 +529,7 @@ print_frame_info (fi, level, source, args)
|
||||
}
|
||||
#endif
|
||||
#ifdef PC_SOLIB
|
||||
if (!funname)
|
||||
if (!funname || (!sal.symtab || !sal.symtab->filename))
|
||||
{
|
||||
char *lib = PC_SOLIB (fi->pc);
|
||||
if (lib)
|
||||
@ -380,14 +552,14 @@ print_frame_info (fi, level, source, args)
|
||||
fi->pc);
|
||||
if (!done)
|
||||
{
|
||||
if (addressprint && mid_statement)
|
||||
if (addressprint && mid_statement && !tui_version)
|
||||
{
|
||||
print_address_numeric (fi->pc, 1, gdb_stdout);
|
||||
printf_filtered ("\t");
|
||||
}
|
||||
if (print_frame_info_listing_hook)
|
||||
print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
|
||||
else
|
||||
else if (!tui_version)
|
||||
print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
|
||||
}
|
||||
current_source_line = max (sal.line - lines_to_list/2, 1);
|
||||
@ -399,12 +571,53 @@ print_frame_info (fi, level, source, args)
|
||||
|
||||
gdb_flush (gdb_stdout);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
stack_publish_stopped_with_no_frame()
|
||||
{
|
||||
TUIDO(((TuiOpaqueFuncPtr)tuiUpdateOnEnd));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Show or print the frame info. If this is the tui, it will be shown in
|
||||
the source display */
|
||||
void
|
||||
print_frame_info(fi, level, source, args)
|
||||
struct frame_info *fi;
|
||||
register int level;
|
||||
int source;
|
||||
int args;
|
||||
{
|
||||
if (!tui_version)
|
||||
print_frame_info_base(fi, level, source, args);
|
||||
else
|
||||
{
|
||||
if (fi && (frame_in_dummy(fi) || fi->signal_handler_caller))
|
||||
print_frame_info_base(fi, level, source, args);
|
||||
else
|
||||
{
|
||||
TUIDO(((TuiOpaqueFuncPtr)tui_vShowFrameInfo, fi));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Show the frame info. If this is the tui, it will be shown in
|
||||
the source display otherwise, nothing is done */
|
||||
void
|
||||
show_stack_frame(fi)
|
||||
struct frame_info *fi;
|
||||
{
|
||||
TUIDO(((TuiOpaqueFuncPtr)tui_vShowFrameInfo, fi));
|
||||
}
|
||||
|
||||
|
||||
/* Read a frame specification in whatever the appropriate format is.
|
||||
Call error() if the specification is in any way invalid (i.e.
|
||||
this function never returns NULL). */
|
||||
|
||||
static struct frame_info *
|
||||
struct frame_info *
|
||||
parse_frame_specification (frame_exp)
|
||||
char *frame_exp;
|
||||
{
|
||||
@ -525,7 +738,6 @@ frame_info (addr_exp, from_tty)
|
||||
int from_tty;
|
||||
{
|
||||
struct frame_info *fi;
|
||||
struct frame_saved_regs fsr;
|
||||
struct symtab_and_line sal;
|
||||
struct symbol *func;
|
||||
struct symtab *s;
|
||||
@ -549,8 +761,32 @@ frame_info (addr_exp, from_tty)
|
||||
s = find_pc_symtab(fi->pc);
|
||||
if (func)
|
||||
{
|
||||
funname = SYMBOL_NAME (func);
|
||||
funlang = SYMBOL_LANGUAGE (func);
|
||||
/* I'd like to use SYMBOL_SOURCE_NAME() here, to display
|
||||
* the demangled name that we already have stored in
|
||||
* the symbol table, but we stored a version with
|
||||
* DMGL_PARAMS turned on, and here we don't want
|
||||
* to display parameters. So call the demangler again,
|
||||
* with DMGL_ANSI only. RT
|
||||
* (Yes, I know that printf_symbol_filtered() will
|
||||
* again try to demangle the name on the fly, but
|
||||
* the issue is that if cplus_demangle() fails here,
|
||||
* it'll fail there too. So we want to catch the failure
|
||||
* ("demangled==NULL" case below) here, while we still
|
||||
* have our hands on the function symbol.)
|
||||
*/
|
||||
char * demangled;
|
||||
funname = SYMBOL_NAME (func);
|
||||
funlang = SYMBOL_LANGUAGE (func);
|
||||
if (funlang == language_cplus)
|
||||
{
|
||||
demangled = cplus_demangle (funname, DMGL_ANSI);
|
||||
/* If the demangler fails, try the demangled name
|
||||
* from the symbol table. This'll have parameters,
|
||||
* but that's preferable to diplaying a mangled name.
|
||||
*/
|
||||
if (demangled == NULL)
|
||||
funname = SYMBOL_SOURCE_NAME (func);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -666,36 +902,39 @@ frame_info (addr_exp, from_tty)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (FRAME_FIND_SAVED_REGS)
|
||||
get_frame_saved_regs (fi, &fsr);
|
||||
/* The sp is special; what's returned isn't the save address, but
|
||||
actually the value of the previous frame's sp. */
|
||||
printf_filtered (" Previous frame's sp is ");
|
||||
print_address_numeric (fsr.regs[SP_REGNUM], 1, gdb_stdout);
|
||||
printf_filtered ("\n");
|
||||
count = 0;
|
||||
numregs = ARCH_NUM_REGS;
|
||||
for (i = 0; i < numregs; i++)
|
||||
if (fsr.regs[i] && i != SP_REGNUM)
|
||||
{
|
||||
if (count == 0)
|
||||
puts_filtered (" Saved registers:\n ");
|
||||
else
|
||||
puts_filtered (",");
|
||||
wrap_here (" ");
|
||||
printf_filtered (" %s at ", REGISTER_NAME (i));
|
||||
print_address_numeric (fsr.regs[i], 1, gdb_stdout);
|
||||
count++;
|
||||
}
|
||||
if (count)
|
||||
puts_filtered ("\n");
|
||||
#else /* Have FRAME_FIND_SAVED_REGS. */
|
||||
/* We could get some information about saved registers by calling
|
||||
get_saved_register on each register. Which info goes with which frame
|
||||
is necessarily lost, however, and I suspect that the users don't care
|
||||
whether they get the info. */
|
||||
puts_filtered ("\n");
|
||||
#endif /* Have FRAME_FIND_SAVED_REGS. */
|
||||
FRAME_INIT_SAVED_REGS (fi);
|
||||
if (fi->saved_regs != NULL)
|
||||
{
|
||||
/* The sp is special; what's returned isn't the save address, but
|
||||
actually the value of the previous frame's sp. */
|
||||
printf_filtered (" Previous frame's sp is ");
|
||||
print_address_numeric (fi->saved_regs[SP_REGNUM], 1, gdb_stdout);
|
||||
printf_filtered ("\n");
|
||||
count = 0;
|
||||
numregs = ARCH_NUM_REGS;
|
||||
for (i = 0; i < numregs; i++)
|
||||
if (fi->saved_regs[i] && i != SP_REGNUM)
|
||||
{
|
||||
if (count == 0)
|
||||
puts_filtered (" Saved registers:\n ");
|
||||
else
|
||||
puts_filtered (",");
|
||||
wrap_here (" ");
|
||||
printf_filtered (" %s at ", REGISTER_NAME (i));
|
||||
print_address_numeric (fi->saved_regs[i], 1, gdb_stdout);
|
||||
count++;
|
||||
}
|
||||
if (count)
|
||||
puts_filtered ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We could get some information about saved registers by
|
||||
calling get_saved_register on each register. Which info goes
|
||||
with which frame is necessarily lost, however, and I suspect
|
||||
that the users don't care whether they get the info. */
|
||||
puts_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -732,8 +971,9 @@ backtrace_limit_info (arg, from_tty)
|
||||
/* Print briefly all stack frames or just the innermost COUNT frames. */
|
||||
|
||||
static void
|
||||
backtrace_command (count_exp, from_tty)
|
||||
backtrace_command_1 (count_exp, show_locals, from_tty)
|
||||
char *count_exp;
|
||||
int show_locals;
|
||||
int from_tty;
|
||||
{
|
||||
struct frame_info *fi;
|
||||
@ -814,25 +1054,104 @@ backtrace_command (count_exp, from_tty)
|
||||
means further attempts to backtrace would fail (on the other
|
||||
hand, perhaps the code does or could be fixed to make sure
|
||||
the frame->prev field gets set to NULL in that case). */
|
||||
print_frame_info (fi, trailing_level + i, 0, 1);
|
||||
print_frame_info_base (fi, trailing_level + i, 0, 1);
|
||||
if (show_locals)
|
||||
print_frame_local_vars(fi, 1, gdb_stdout);
|
||||
}
|
||||
|
||||
/* If we've stopped before the end, mention that. */
|
||||
if (fi && from_tty)
|
||||
printf_filtered ("(More stack frames follow...)\n");
|
||||
}
|
||||
|
||||
static void
|
||||
backtrace_command (arg, from_tty)
|
||||
char *arg;
|
||||
int from_tty;
|
||||
{
|
||||
struct cleanup *old_chain = (struct cleanup *)NULL;
|
||||
char **argv = (char **)NULL;
|
||||
int argIndicatingFullTrace = (-1), totArgLen = 0, argc = 0;
|
||||
char *argPtr = arg;
|
||||
|
||||
if (arg != (char *)NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
argv = buildargv(arg);
|
||||
old_chain = make_cleanup(freeargv, (char *)argv);
|
||||
argc = 0;
|
||||
for (i = 0; (argv[i] != (char *)NULL); i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; (j < strlen(argv[i])); j++)
|
||||
argv[i][j] = tolower(argv[i][j]);
|
||||
|
||||
if (argIndicatingFullTrace < 0 && subsetCompare(argv[i], "full"))
|
||||
argIndicatingFullTrace = argc;
|
||||
else
|
||||
{
|
||||
argc++;
|
||||
totArgLen += strlen(argv[i]);
|
||||
}
|
||||
}
|
||||
totArgLen += argc;
|
||||
if (argIndicatingFullTrace >= 0)
|
||||
{
|
||||
if (totArgLen > 0)
|
||||
{
|
||||
argPtr = (char *)xmalloc(totArgLen + 1);
|
||||
if (!argPtr)
|
||||
nomem(0);
|
||||
else
|
||||
{
|
||||
memset(argPtr, 0, totArgLen + 1);
|
||||
for (i = 0; (i < (argc + 1)); i++)
|
||||
{
|
||||
if (i != argIndicatingFullTrace)
|
||||
{
|
||||
strcat(argPtr, argv[i]);
|
||||
strcat(argPtr, " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
argPtr = (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
backtrace_command_1 (argPtr, (argIndicatingFullTrace >= 0), from_tty);
|
||||
|
||||
if (argIndicatingFullTrace >= 0 && totArgLen > 0)
|
||||
free(argPtr);
|
||||
|
||||
if (old_chain)
|
||||
do_cleanups(old_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
backtrace_full_command (arg, from_tty)
|
||||
char *arg;
|
||||
int from_tty;
|
||||
{
|
||||
backtrace_command_1 (arg, 1, from_tty);
|
||||
}
|
||||
|
||||
|
||||
/* Print the local variables of a block B active in FRAME.
|
||||
Return 1 if any variables were printed; 0 otherwise. */
|
||||
|
||||
static int
|
||||
print_block_frame_locals (b, fi, stream)
|
||||
print_block_frame_locals (b, fi, num_tabs, stream)
|
||||
struct block *b;
|
||||
register struct frame_info *fi;
|
||||
int num_tabs;
|
||||
register GDB_FILE *stream;
|
||||
{
|
||||
int nsyms;
|
||||
register int i;
|
||||
register int i, j;
|
||||
register struct symbol *sym;
|
||||
register int values_printed = 0;
|
||||
|
||||
@ -848,6 +1167,8 @@ print_block_frame_locals (b, fi, stream)
|
||||
case LOC_STATIC:
|
||||
case LOC_BASEREG:
|
||||
values_printed = 1;
|
||||
for (j = 0; j < num_tabs; j++)
|
||||
fputs_filtered("\t", stream);
|
||||
fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
|
||||
fputs_filtered (" = ", stream);
|
||||
print_variable_value (sym, fi, stream);
|
||||
@ -913,8 +1234,9 @@ print_block_frame_labels (b, have_default, stream)
|
||||
on the function running in FRAME. */
|
||||
|
||||
static void
|
||||
print_frame_local_vars (fi, stream)
|
||||
print_frame_local_vars (fi, num_tabs, stream)
|
||||
register struct frame_info *fi;
|
||||
register int num_tabs;
|
||||
register GDB_FILE *stream;
|
||||
{
|
||||
register struct block *block = get_frame_block (fi);
|
||||
@ -928,7 +1250,7 @@ print_frame_local_vars (fi, stream)
|
||||
|
||||
while (block != 0)
|
||||
{
|
||||
if (print_block_frame_locals (block, fi, stream))
|
||||
if (print_block_frame_locals (block, fi, num_tabs, stream))
|
||||
values_printed = 1;
|
||||
/* After handling the function's top-level block, stop.
|
||||
Don't continue to its superblock, the block of
|
||||
@ -1024,7 +1346,7 @@ locals_info (args, from_tty)
|
||||
{
|
||||
if (!selected_frame)
|
||||
error ("No frame selected.");
|
||||
print_frame_local_vars (selected_frame, gdb_stdout);
|
||||
print_frame_local_vars (selected_frame, 0, gdb_stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1032,9 +1354,29 @@ catch_info (ignore, from_tty)
|
||||
char *ignore;
|
||||
int from_tty;
|
||||
{
|
||||
struct symtab_and_line * sal;
|
||||
|
||||
/* Check for target support for exception handling */
|
||||
sal = target_enable_exception_callback (EX_EVENT_CATCH, 1);
|
||||
if (sal)
|
||||
{
|
||||
/* Currently not handling this */
|
||||
/* Ideally, here we should interact with the C++ runtime
|
||||
system to find the list of active handlers, etc. */
|
||||
fprintf_filtered (gdb_stdout, "Info catch not supported with this target/compiler combination.\n");
|
||||
#if 0
|
||||
if (!selected_frame)
|
||||
error ("No frame selected.");
|
||||
print_frame_label_vars (selected_frame, 0, gdb_stdout);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assume g++ compiled code -- old v 4.16 behaviour */
|
||||
if (!selected_frame)
|
||||
error ("No frame selected.");
|
||||
|
||||
print_frame_label_vars (selected_frame, 0, gdb_stdout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1112,6 +1454,16 @@ args_info (ignore, from_tty)
|
||||
print_frame_arg_vars (selected_frame, gdb_stdout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
args_plus_locals_info(ignore, from_tty)
|
||||
char *ignore;
|
||||
int from_tty;
|
||||
{
|
||||
args_info(ignore, from_tty);
|
||||
locals_info(ignore, from_tty);
|
||||
}
|
||||
|
||||
|
||||
/* Select frame FI, and note that its stack level is LEVEL.
|
||||
LEVEL may be -1 if an actual level number is not known. */
|
||||
@ -1139,9 +1491,48 @@ select_frame (fi, level)
|
||||
&& language_mode == language_mode_auto) {
|
||||
set_language(s->language);
|
||||
}
|
||||
/* elz: this if here fixes the problem with the pc not being displayed
|
||||
in the tui asm layout, with no debug symbols. The value of s
|
||||
would be 0 here, and select_source_symtab would abort the
|
||||
command by calling the 'error' function*/
|
||||
if (s)
|
||||
{
|
||||
TUIDO(((TuiOpaqueFuncPtr)tui_vSelectSourceSymtab, s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Select frame FI, noting that its stack level is LEVEL. Also print
|
||||
the stack frame and show the source if this is the tui version. */
|
||||
void
|
||||
select_and_print_frame(fi, level)
|
||||
struct frame_info *fi;
|
||||
int level;
|
||||
{
|
||||
select_frame(fi, level);
|
||||
if (fi)
|
||||
{
|
||||
print_stack_frame(fi, level, 1);
|
||||
TUIDO(((TuiOpaqueFuncPtr)tui_vCheckDataValues, fi));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Select frame FI, noting that its stack level is LEVEL. Be silent if
|
||||
not the TUI */
|
||||
void
|
||||
select_and_maybe_print_frame(fi, level)
|
||||
struct frame_info *fi;
|
||||
int level;
|
||||
{
|
||||
if (!tui_version)
|
||||
select_frame(fi, level);
|
||||
else
|
||||
select_and_print_frame(fi, level);
|
||||
}
|
||||
|
||||
|
||||
/* Store the selected frame and its level into *FRAMEP and *LEVELP.
|
||||
If there is no selected frame, *FRAMEP is set to NULL. */
|
||||
|
||||
@ -1249,23 +1640,34 @@ select_frame_command (level_exp, from_tty)
|
||||
With arg, behaves like select_frame and then prints the selected
|
||||
frame. */
|
||||
|
||||
static void
|
||||
void
|
||||
frame_command (level_exp, from_tty)
|
||||
char *level_exp;
|
||||
int from_tty;
|
||||
{
|
||||
select_frame_command (level_exp, from_tty);
|
||||
print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
}
|
||||
|
||||
/* The XDB Compatibility command to print the current frame. */
|
||||
|
||||
void
|
||||
current_frame_command (level_exp, from_tty)
|
||||
char *level_exp;
|
||||
int from_tty;
|
||||
{
|
||||
if (target_has_stack == 0 || selected_frame == 0)
|
||||
error ("No stack.");
|
||||
print_only_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
}
|
||||
|
||||
/* Select the frame up one or COUNT stack levels
|
||||
from the previously selected frame, and print it briefly. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
up_silently_command (count_exp, from_tty)
|
||||
up_silently_base (count_exp)
|
||||
char *count_exp;
|
||||
int from_tty;
|
||||
{
|
||||
register struct frame_info *fi;
|
||||
int count = 1, count1;
|
||||
@ -1282,13 +1684,23 @@ up_silently_command (count_exp, from_tty)
|
||||
select_frame (fi, selected_frame_level + count - count1);
|
||||
}
|
||||
|
||||
static void
|
||||
up_silently_command (count_exp, from_tty)
|
||||
char *count_exp;
|
||||
int from_tty;
|
||||
{
|
||||
up_silently_base(count_exp);
|
||||
if (tui_version)
|
||||
print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
up_command (count_exp, from_tty)
|
||||
char *count_exp;
|
||||
int from_tty;
|
||||
{
|
||||
up_silently_command (count_exp, from_tty);
|
||||
print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
up_silently_base (count_exp);
|
||||
show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
}
|
||||
|
||||
/* Select the frame down one or COUNT stack levels
|
||||
@ -1296,9 +1708,8 @@ up_command (count_exp, from_tty)
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
down_silently_command (count_exp, from_tty)
|
||||
down_silently_base (count_exp)
|
||||
char *count_exp;
|
||||
int from_tty;
|
||||
{
|
||||
register struct frame_info *frame;
|
||||
int count = -1, count1;
|
||||
@ -1324,14 +1735,24 @@ down_silently_command (count_exp, from_tty)
|
||||
select_frame (frame, selected_frame_level + count - count1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
down_silently_command (count_exp, from_tty)
|
||||
char *count_exp;
|
||||
int from_tty;
|
||||
{
|
||||
down_silently_base (count_exp);
|
||||
if (tui_version)
|
||||
print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
down_command (count_exp, from_tty)
|
||||
char *count_exp;
|
||||
int from_tty;
|
||||
{
|
||||
down_silently_command (count_exp, from_tty);
|
||||
print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
down_silently_base (count_exp);
|
||||
show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1416,6 +1837,66 @@ return_command (retval_exp, from_tty)
|
||||
select_frame_command ("0", 0);
|
||||
}
|
||||
|
||||
/* Sets the scope to input function name, provided that the
|
||||
function is within the current stack frame */
|
||||
typedef struct function_bounds
|
||||
{
|
||||
CORE_ADDR low, high;
|
||||
};
|
||||
|
||||
static void
|
||||
func_command (arg, from_tty)
|
||||
char *arg;
|
||||
int from_tty;
|
||||
{
|
||||
if (arg != (char *)NULL)
|
||||
{
|
||||
struct frame_info *fp;
|
||||
int found = 0;
|
||||
struct symtabs_and_lines sals;
|
||||
int i;
|
||||
int level = 1;
|
||||
struct function_bounds *funcBounds = (struct function_bounds *)NULL;
|
||||
|
||||
fp = parse_frame_specification("0");
|
||||
sals = decode_line_spec(arg, 1);
|
||||
funcBounds = (struct function_bounds *)xmalloc(
|
||||
sizeof(struct function_bounds) * sals.nelts);
|
||||
for (i = 0; (i < sals.nelts && !found); i++)
|
||||
{
|
||||
if (sals.sals[i].pc == (CORE_ADDR)0 ||
|
||||
find_pc_partial_function(sals.sals[i].pc,
|
||||
(char **)NULL,
|
||||
&funcBounds[i].low,
|
||||
&funcBounds[i].high) == 0)
|
||||
{
|
||||
funcBounds[i].low =
|
||||
funcBounds[i].high = (CORE_ADDR)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
for (i = 0; (i < sals.nelts && !found); i++)
|
||||
found = (fp->pc >= funcBounds[i].low &&
|
||||
fp->pc < funcBounds[i].high);
|
||||
if (!found)
|
||||
{
|
||||
level = 1;
|
||||
fp = find_relative_frame(fp, &level);
|
||||
}
|
||||
} while (!found && level == 0);
|
||||
|
||||
if (funcBounds)
|
||||
free(funcBounds);
|
||||
|
||||
if (!found)
|
||||
printf_filtered("'%s' not within current stack frame.\n", arg);
|
||||
else if (fp != selected_frame) /* set the stack frame here! */
|
||||
select_and_print_frame(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Gets the language of the current frame. */
|
||||
|
||||
enum language
|
||||
@ -1477,6 +1958,12 @@ a command file or a user-defined command.");
|
||||
|
||||
add_com_alias ("f", "frame", class_stack, 1);
|
||||
|
||||
if (xdb_commands)
|
||||
{
|
||||
add_com("L", class_stack, current_frame_command,
|
||||
"Print the current stack frame.\n");
|
||||
add_com_alias ("V", "frame", class_stack, 1);
|
||||
}
|
||||
add_com ("select-frame", class_stack, select_frame_command,
|
||||
"Select a stack frame without printing anything.\n\
|
||||
An argument specifies the frame to select.\n\
|
||||
@ -1484,8 +1971,19 @@ It can be a stack frame number or the address of the frame.\n");
|
||||
|
||||
add_com ("backtrace", class_stack, backtrace_command,
|
||||
"Print backtrace of all stack frames, or innermost COUNT frames.\n\
|
||||
With a negative argument, print outermost -COUNT frames.");
|
||||
With a negative argument, print outermost -COUNT frames.\n\
|
||||
Use of the 'full' qualifier also prints the values of the local variables.\n");
|
||||
add_com_alias ("bt", "backtrace", class_stack, 0);
|
||||
if (xdb_commands)
|
||||
{
|
||||
add_com_alias ("t", "backtrace", class_stack, 0);
|
||||
add_com ("T", class_stack, backtrace_full_command,
|
||||
"Print backtrace of all stack frames, or innermost COUNT frames \n\
|
||||
and the values of the local variables.\n\
|
||||
With a negative argument, print outermost -COUNT frames.\n\
|
||||
Usage: T <count>\n");
|
||||
}
|
||||
|
||||
add_com_alias ("where", "backtrace", class_alias, 0);
|
||||
add_info ("stack", backtrace_command,
|
||||
"Backtrace of the stack, or innermost COUNT frames.");
|
||||
@ -1497,6 +1995,14 @@ With a negative argument, print outermost -COUNT frames.");
|
||||
"Local variables of current stack frame.");
|
||||
add_info ("args", args_info,
|
||||
"Argument variables of current stack frame.");
|
||||
if (xdb_commands)
|
||||
add_com("l", class_info, args_plus_locals_info,
|
||||
"Argument and local variables of current stack frame.");
|
||||
|
||||
if (dbx_commands)
|
||||
add_com("func", class_stack, func_command,
|
||||
"Select the stack frame that contains <func>.\nUsage: func <name>\n");
|
||||
|
||||
add_info ("catch", catch_info,
|
||||
"Exceptions that can be caught in the current stack frame.");
|
||||
|
||||
|
Reference in New Issue
Block a user