URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/trunk/gdb-5.0/gdb/mi
- from Rev 107 to Rev 1765
- ↔ Reverse comparison
Rev 107 → Rev 1765
/mi-cmds.h
0,0 → 1,129
/* MI Command Set. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#ifndef MI_CMDS_H |
#define MI_CMDS_H |
|
/* An MI command can return any of the following. */ |
|
enum mi_cmd_result |
{ |
/* Report the command as ``done''. Display both the ``NNN^done'' |
message and the completion prompt. */ |
MI_CMD_DONE = 0, |
/* The command is still running in the forground. Main loop should |
display the completion prompt. */ |
MI_CMD_FORGROUND, |
/* An error condition was detected and an error message was |
asprintf'd into the mi_error_message buffer. The main loop will |
display the error message and the completion prompt. */ |
MI_CMD_ERROR, |
/* An error condition was detected and caught. The error message is |
in the global error message buffer. The main loop will display |
the error message and the completion prompt. */ |
MI_CMD_CAUGHT_ERROR, |
/* The MI command has already displayed its completion message. |
Main loop will not display a completion message but will display |
the completion prompt. */ |
MI_CMD_QUIET |
}; |
|
typedef enum mi_cmd_result (mi_cmd_argv_ftype) (char *command, char **argv, int argc); |
|
/* Older MI commands have this interface. Retained until all old |
commands are flushed. */ |
|
typedef enum mi_cmd_result (mi_cmd_args_ftype) ( /*ui */ char *args, int from_tty); |
|
/* Function implementing each command */ |
extern mi_cmd_argv_ftype mi_cmd_break_insert; |
extern mi_cmd_argv_ftype mi_cmd_break_watch; |
extern mi_cmd_argv_ftype mi_cmd_disassemble; |
extern mi_cmd_argv_ftype mi_cmd_data_evaluate_expression; |
extern mi_cmd_argv_ftype mi_cmd_data_list_register_names; |
extern mi_cmd_argv_ftype mi_cmd_data_list_register_values; |
extern mi_cmd_argv_ftype mi_cmd_data_list_changed_registers; |
extern mi_cmd_argv_ftype mi_cmd_data_read_memory; |
extern mi_cmd_argv_ftype mi_cmd_data_write_memory; |
extern mi_cmd_argv_ftype mi_cmd_data_write_register_values; |
extern mi_cmd_args_ftype mi_cmd_exec_continue; |
extern mi_cmd_args_ftype mi_cmd_exec_finish; |
extern mi_cmd_args_ftype mi_cmd_exec_next; |
extern mi_cmd_args_ftype mi_cmd_exec_next_instruction; |
extern mi_cmd_args_ftype mi_cmd_exec_return; |
extern mi_cmd_args_ftype mi_cmd_exec_run; |
extern mi_cmd_args_ftype mi_cmd_exec_step; |
extern mi_cmd_args_ftype mi_cmd_exec_step_instruction; |
extern mi_cmd_args_ftype mi_cmd_exec_until; |
extern mi_cmd_args_ftype mi_cmd_exec_interrupt; |
extern mi_cmd_argv_ftype mi_cmd_gdb_exit; |
extern mi_cmd_argv_ftype mi_cmd_stack_info_depth; |
extern mi_cmd_argv_ftype mi_cmd_stack_list_args; |
extern mi_cmd_argv_ftype mi_cmd_stack_list_frames; |
extern mi_cmd_argv_ftype mi_cmd_stack_list_locals; |
extern mi_cmd_argv_ftype mi_cmd_stack_select_frame; |
extern mi_cmd_args_ftype mi_cmd_target_download; |
extern mi_cmd_args_ftype mi_cmd_target_select; |
extern mi_cmd_argv_ftype mi_cmd_thread_list_ids; |
extern mi_cmd_argv_ftype mi_cmd_thread_select; |
extern mi_cmd_argv_ftype mi_cmd_var_assign; |
extern mi_cmd_argv_ftype mi_cmd_var_create; |
extern mi_cmd_argv_ftype mi_cmd_var_delete; |
extern mi_cmd_argv_ftype mi_cmd_var_evaluate_expression; |
extern mi_cmd_argv_ftype mi_cmd_var_info_expression; |
extern mi_cmd_argv_ftype mi_cmd_var_info_num_children; |
extern mi_cmd_argv_ftype mi_cmd_var_info_type; |
extern mi_cmd_argv_ftype mi_cmd_var_list_children; |
extern mi_cmd_argv_ftype mi_cmd_var_set_format; |
extern mi_cmd_argv_ftype mi_cmd_var_show_attributes; |
extern mi_cmd_argv_ftype mi_cmd_var_show_format; |
extern mi_cmd_argv_ftype mi_cmd_var_update; |
|
/* Description of a single command. */ |
|
struct mi_cmd |
{ |
/* official name of the command */ |
const char *name; |
/* If non-null, the corresponding CLI command that can be used to |
implement this MI command */ |
const char *cli; |
/* If non-null, the function implementing the MI command */ |
mi_cmd_args_ftype *args_func; |
/* If non-null, the function implementing the MI command */ |
mi_cmd_argv_ftype *argv_func; |
}; |
|
/* Lookup a command in the mi comand table */ |
|
extern struct mi_cmd *mi_lookup (const char *command); |
|
/* Debug flag */ |
extern int mi_debug_p; |
|
/* Raw console output - FIXME: should this be a parameter? */ |
extern struct ui_file *raw_stdout; |
|
#endif |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-getopt.c
0,0 → 1,80
/* MI Command Set - MI Option Parser. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "mi-getopt.h" |
#include "string.h" |
|
int |
mi_getopt (const char *prefix, |
int argc, char **argv, |
struct mi_opt *opts, |
int *optind, char **optarg) |
{ |
char *arg; |
struct mi_opt *opt; |
/* We assume that argv/argc are ok. */ |
if (*optind > argc || *optind < 0) |
internal_error ("mi_getopt_long: optind out of bounds"); |
if (*optind == argc) |
return -1; |
arg = argv[*optind]; |
/* ``--''? */ |
if (strcmp (arg, "--") == 0) |
{ |
*optind += 1; |
*optarg = NULL; |
return -1; |
} |
/* End of option list. */ |
if (arg[0] != '-') |
{ |
*optarg = NULL; |
return -1; |
} |
/* Look the option up. */ |
for (opt = opts; opt->name != NULL; opt++) |
{ |
if (strcmp (opt->name, arg + 1) != 0) |
continue; |
if (opt->arg_p) |
{ |
/* A non-simple optarg option. */ |
if (argc < *optind + 2) |
error ("%s: Option %s requires an argument", prefix, arg); |
*optarg = argv[(*optind) + 1]; |
*optind = (*optind) + 2; |
return opt->index; |
} |
else |
{ |
*optarg = NULL; |
*optind = (*optind) + 1; |
return opt->index; |
} |
} |
error ("%s: Unknown option ``%s''", prefix, arg + 1); |
} |
|
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-console.c
0,0 → 1,118
/* MI Console code. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "mi-console.h" |
#include <string.h> |
|
/* Convenience macro for allocting typesafe memory. */ |
|
#undef XMALLOC |
#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) |
|
/* MI-console: send output to std-out but correcty encapsulated */ |
|
static ui_file_fputs_ftype mi_console_file_fputs; |
static ui_file_flush_ftype mi_console_file_flush; |
static ui_file_delete_ftype mi_console_file_delete; |
|
struct mi_console_file |
{ |
int *magic; |
struct ui_file *raw; |
struct ui_file *buffer; |
const char *prefix; |
}; |
|
int mi_console_file_magic; |
|
struct ui_file * |
mi_console_file_new (struct ui_file *raw, |
const char *prefix) |
{ |
struct ui_file *ui_file = ui_file_new (); |
struct mi_console_file *mi_console = XMALLOC (struct mi_console_file); |
mi_console->magic = &mi_console_file_magic; |
mi_console->raw = raw; |
mi_console->buffer = mem_fileopen (); |
mi_console->prefix = prefix; |
set_ui_file_fputs (ui_file, mi_console_file_fputs); |
set_ui_file_flush (ui_file, mi_console_file_flush); |
set_ui_file_data (ui_file, mi_console, mi_console_file_delete); |
return ui_file; |
} |
|
static void |
mi_console_file_delete (struct ui_file *file) |
{ |
struct mi_console_file *mi_console = ui_file_data (file); |
if (mi_console->magic != &mi_console_file_magic) |
internal_error ("mi_console_file_delete: bad magic number"); |
free (mi_console); |
} |
|
static void |
mi_console_file_fputs (const char *buf, |
struct ui_file *file) |
{ |
struct mi_console_file *mi_console = ui_file_data (file); |
if (mi_console->magic != &mi_console_file_magic) |
internal_error ("mi_console_file_fputs: bad magic number"); |
/* Append the text to our internal buffer */ |
fputs_unfiltered (buf, mi_console->buffer); |
/* Flush when an embedded \n */ |
if (strchr (buf, '\n') != NULL) |
gdb_flush (file); |
} |
|
/* Transform a byte sequence into a console output packet. */ |
static void |
mi_console_raw_packet (void *data, |
const char *buf, |
long length_buf) |
{ |
struct mi_console_file *mi_console = data; |
if (mi_console->magic != &mi_console_file_magic) |
internal_error ("mi_console_file_transform: bad magic number"); |
|
if (length_buf > 0) |
{ |
fputs_unfiltered (mi_console->prefix, mi_console->raw); |
fputs_unfiltered ("\"", mi_console->raw); |
fputstrn_unfiltered (buf, length_buf, '"', mi_console->raw); |
fputs_unfiltered ("\"\n", mi_console->raw); |
gdb_flush (mi_console->raw); |
} |
} |
|
static void |
mi_console_file_flush (struct ui_file *file) |
{ |
struct mi_console_file *mi_console = ui_file_data (file); |
if (mi_console->magic != &mi_console_file_magic) |
internal_error ("mi_console_file_flush: bad magic number"); |
ui_file_put (mi_console->buffer, mi_console_raw_packet, mi_console); |
ui_file_rewind (mi_console->buffer); |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-cmd-disas.c
0,0 → 1,498
/* MI Command Set - disassemble commands. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "target.h" |
#include "value.h" |
#include "mi-cmds.h" |
#include "mi-getopt.h" |
#include "ui-out.h" |
|
static int gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, unsigned int len, |
disassemble_info * info); |
static int compare_lines (const PTR mle1p, const PTR mle2p); |
|
/* Disassemble functions. FIXME: these do not really belong here. We |
should get rid of all the duplicate code in gdb that does the same |
thing: disassemble_command() and the gdbtk variation. */ |
|
/* This Structure is used in mi_cmd_disassemble. |
We need a different sort of line table from the normal one cuz we can't |
depend upon implicit line-end pc's for lines to do the |
reordering in this function. */ |
|
struct dis_line_entry |
{ |
int line; |
CORE_ADDR start_pc; |
CORE_ADDR end_pc; |
}; |
|
/* This variable determines where memory used for disassembly is read from. */ |
int gdb_disassemble_from_exec = -1; |
|
/* This is the memory_read_func for gdb_disassemble when we are |
disassembling from the exec file. */ |
static int |
gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, |
unsigned int len, disassemble_info * info) |
{ |
extern struct target_ops exec_ops; |
int res; |
|
errno = 0; |
res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops); |
|
if (res == len) |
return 0; |
else if (errno == 0) |
return EIO; |
else |
return errno; |
} |
|
static int |
compare_lines (const PTR mle1p, const PTR mle2p) |
{ |
struct dis_line_entry *mle1, *mle2; |
int val; |
|
mle1 = (struct dis_line_entry *) mle1p; |
mle2 = (struct dis_line_entry *) mle2p; |
|
val = mle1->line - mle2->line; |
|
if (val != 0) |
return val; |
|
return mle1->start_pc - mle2->start_pc; |
} |
|
/* The arguments to be passed on the command line and parsed here are: |
|
either: |
|
START-ADDRESS: address to start the disassembly at. |
END-ADDRESS: address to end the disassembly at. |
|
or: |
|
FILENAME: The name of the file where we want disassemble from. |
LINE: The line around which we want to disassemble. It will |
disassemble the function that contins that line. |
HOW_MANY: Number of disassembly lines to display. In mixed mode, it |
is the number of disassembly lines only, not counting the source |
lines. |
|
always required: |
|
MODE: 0 or 1 for disassembly only, or mixed source and disassembly, |
respectively. */ |
|
enum mi_cmd_result |
mi_cmd_disassemble (char *command, char **argv, int argc) |
{ |
CORE_ADDR pc; |
CORE_ADDR start; |
CORE_ADDR low = 0; |
CORE_ADDR high = 0; |
|
int how_many = -1; |
int mixed_source_and_assembly; |
int num_displayed; |
int line_num; |
|
char *file_string; |
static disassemble_info di; |
static int di_initialized; |
|
struct symtab *s; |
|
/* To collect the instruction outputted from opcodes. */ |
static struct ui_stream *stb = NULL; |
|
/* parts of the symbolic representation of the address */ |
int line; |
int offset; |
int unmapped; |
char *filename = NULL; |
char *name = NULL; |
|
/* Which options have we processed? */ |
int file_seen = 0; |
int line_seen = 0; |
int num_seen = 0; |
int start_seen = 0; |
int end_seen = 0; |
|
/* Options processing stuff. */ |
int optind = 0; |
char *optarg; |
enum opt |
{ |
FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT |
}; |
static struct mi_opt opts[] = |
{ |
{"f", FILE_OPT, 1}, |
{"l", LINE_OPT, 1}, |
{"n", NUM_OPT, 1}, |
{"s", START_OPT, 1}, |
{"e", END_OPT, 1}, |
0 |
}; |
|
/* Get the options with their arguments. Keep track of what we |
encountered. */ |
while (1) |
{ |
int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts, |
&optind, &optarg); |
if (opt < 0) |
break; |
switch ((enum opt) opt) |
{ |
case FILE_OPT: |
file_string = xstrdup (optarg); |
file_seen = 1; |
break; |
case LINE_OPT: |
line_num = atoi (optarg); |
line_seen = 1; |
break; |
case NUM_OPT: |
how_many = atoi (optarg); |
num_seen = 1; |
break; |
case START_OPT: |
low = parse_and_eval_address (optarg); |
start_seen = 1; |
break; |
case END_OPT: |
high = parse_and_eval_address (optarg); |
end_seen = 1; |
break; |
} |
} |
argv += optind; |
argc -= optind; |
|
/* Allow only filename + linenum (with how_many which is not |
required) OR start_addr + and_addr */ |
|
if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen) |
|| (line_seen && file_seen && !num_seen && !start_seen && !end_seen) |
|| (!line_seen && !file_seen && !num_seen && start_seen && end_seen))) |
error ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode."); |
|
if (argc != 1) |
error ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode."); |
|
mixed_source_and_assembly = atoi (argv[0]); |
if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1)) |
error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1."); |
|
/* We must get the function beginning and end where line_num is |
contained. */ |
|
if (line_seen && file_seen) |
{ |
s = lookup_symtab (file_string); |
if (s == NULL) |
error ("mi_cmd_disassemble: Invalid filename."); |
if (!find_line_pc (s, line_num, &start)) |
error ("mi_cmd_disassemble: Invalid line number"); |
if (find_pc_partial_function (start, NULL, &low, &high) == 0) |
error ("mi_cmd_disassemble: No function contains specified address"); |
} |
|
if (!di_initialized) |
{ |
/* We don't add a cleanup for this, because the allocation of |
the stream is done once only for each gdb run, and we need to |
keep it around until the end. Hopefully there won't be any |
errors in the init code below, that make this function bail |
out. */ |
stb = ui_out_stream_new (uiout); |
INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream, |
(fprintf_ftype) fprintf_unfiltered); |
di.flavour = bfd_target_unknown_flavour; |
di.memory_error_func = dis_asm_memory_error; |
di.print_address_func = dis_asm_print_address; |
di_initialized = 1; |
} |
|
di.mach = TARGET_PRINT_INSN_INFO->mach; |
if (TARGET_BYTE_ORDER == BIG_ENDIAN) |
di.endian = BFD_ENDIAN_BIG; |
else |
di.endian = BFD_ENDIAN_LITTLE; |
|
/* If gdb_disassemble_from_exec == -1, then we use the following heuristic to |
determine whether or not to do disassembly from target memory or from the |
exec file: |
|
If we're debugging a local process, read target memory, instead of the |
exec file. This makes disassembly of functions in shared libs work |
correctly. Also, read target memory if we are debugging native threads. |
|
Else, we're debugging a remote process, and should disassemble from the |
exec file for speed. However, this is no good if the target modifies its |
code (for relocation, or whatever). |
*/ |
|
if (gdb_disassemble_from_exec == -1) |
{ |
if (strcmp (target_shortname, "child") == 0 |
|| strcmp (target_shortname, "procfs") == 0 |
|| strcmp (target_shortname, "vxprocess") == 0 |
|| strstr (target_shortname, "-threads") != NULL) |
gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */ |
else |
gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */ |
} |
|
if (gdb_disassemble_from_exec) |
di.read_memory_func = gdb_dis_asm_read_memory; |
else |
di.read_memory_func = dis_asm_read_memory; |
|
/* If just doing straight assembly, all we need to do is disassemble |
everything between low and high. If doing mixed source/assembly, |
we've got a totally different path to follow. */ |
|
if (mixed_source_and_assembly) |
{ |
/* Come here for mixed source/assembly */ |
/* The idea here is to present a source-O-centric view of a |
function to the user. This means that things are presented |
in source order, with (possibly) out of order assembly |
immediately following. */ |
struct symtab *symtab; |
struct linetable_entry *le; |
int nlines; |
int newlines; |
struct dis_line_entry *mle; |
struct symtab_and_line sal; |
int i; |
int out_of_order; |
int next_line; |
|
/* Assume symtab is valid for whole PC range */ |
symtab = find_pc_symtab (low); |
|
if (!symtab || !symtab->linetable) |
goto assembly_only; |
|
/* First, convert the linetable to a bunch of my_line_entry's. */ |
|
le = symtab->linetable->item; |
nlines = symtab->linetable->nitems; |
|
if (nlines <= 0) |
goto assembly_only; |
|
mle = (struct dis_line_entry *) alloca (nlines * sizeof (struct dis_line_entry)); |
|
out_of_order = 0; |
|
/* Copy linetable entries for this function into our data |
structure, creating end_pc's and setting out_of_order as |
appropriate. */ |
|
/* First, skip all the preceding functions. */ |
|
for (i = 0; i < nlines - 1 && le[i].pc < low; i++); |
|
/* Now, copy all entries before the end of this function. */ |
|
newlines = 0; |
for (; i < nlines - 1 && le[i].pc < high; i++) |
{ |
if (le[i].line == le[i + 1].line |
&& le[i].pc == le[i + 1].pc) |
continue; /* Ignore duplicates */ |
|
mle[newlines].line = le[i].line; |
if (le[i].line > le[i + 1].line) |
out_of_order = 1; |
mle[newlines].start_pc = le[i].pc; |
mle[newlines].end_pc = le[i + 1].pc; |
newlines++; |
} |
|
/* If we're on the last line, and it's part of the function, |
then we need to get the end pc in a special way. */ |
|
if (i == nlines - 1 |
&& le[i].pc < high) |
{ |
mle[newlines].line = le[i].line; |
mle[newlines].start_pc = le[i].pc; |
sal = find_pc_line (le[i].pc, 0); |
mle[newlines].end_pc = sal.end; |
newlines++; |
} |
|
/* Now, sort mle by line #s (and, then by addresses within |
lines). */ |
|
if (out_of_order) |
qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines); |
|
/* Now, for each line entry, emit the specified lines (unless |
they have been emitted before), followed by the assembly code |
for that line. */ |
|
next_line = 0; /* Force out first line */ |
ui_out_list_begin (uiout, "asm_insns"); |
num_displayed = 0; |
for (i = 0; i < newlines; i++) |
{ |
int close_list = 1; |
/* Print out everything from next_line to the current line. */ |
if (mle[i].line >= next_line) |
{ |
if (next_line != 0) |
{ |
/* Just one line to print. */ |
if (next_line == mle[i].line) |
{ |
ui_out_list_begin (uiout, "src_and_asm_line"); |
print_source_lines (symtab, next_line, mle[i].line + 1, 0); |
} |
else |
{ |
/* Several source lines w/o asm instructions associated. */ |
for (; next_line < mle[i].line; next_line++) |
{ |
ui_out_list_begin (uiout, "src_and_asm_line"); |
print_source_lines (symtab, next_line, mle[i].line + 1, 0); |
ui_out_list_begin (uiout, "line_asm_insn"); |
ui_out_list_end (uiout); |
ui_out_list_end (uiout); |
} |
/* Print the last line and leave list open for |
asm instructions to be added. */ |
ui_out_list_begin (uiout, "src_and_asm_line"); |
print_source_lines (symtab, next_line, mle[i].line + 1, 0); |
} |
} |
else |
{ |
ui_out_list_begin (uiout, "src_and_asm_line"); |
print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0); |
} |
|
next_line = mle[i].line + 1; |
ui_out_list_begin (uiout, "line_asm_insn"); |
if (i + 1 < newlines && mle[i + 1].line <= mle[i].line) |
close_list = 0; |
} |
for (pc = mle[i].start_pc; pc < mle[i].end_pc;) |
{ |
QUIT; |
if (how_many >= 0) |
{ |
if (num_displayed >= how_many) |
break; |
else |
num_displayed++; |
} |
ui_out_list_begin (uiout, NULL); |
ui_out_field_core_addr (uiout, "address", pc); |
|
if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped)) |
{ |
/* We don't care now about line, filename and |
unmapped, but we might in the future. */ |
ui_out_field_string (uiout, "func-name", name); |
ui_out_field_int (uiout, "offset", offset); |
} |
if (filename != NULL) |
free (filename); |
if (name != NULL) |
free (name); |
|
ui_file_rewind (stb->stream); |
pc += (*tm_print_insn) (pc, &di); |
ui_out_field_stream (uiout, "inst", stb); |
ui_file_rewind (stb->stream); |
ui_out_list_end (uiout); |
} |
if (close_list) |
{ |
ui_out_list_end (uiout); |
ui_out_list_end (uiout); |
close_list = 0; |
} |
if (how_many >= 0) |
if (num_displayed >= how_many) |
break; |
} |
ui_out_list_end (uiout); |
} |
else |
{ |
assembly_only: |
ui_out_list_begin (uiout, "asm_insns"); |
num_displayed = 0; |
for (pc = low; pc < high;) |
{ |
QUIT; |
if (how_many >= 0) |
{ |
if (num_displayed >= how_many) |
break; |
else |
num_displayed++; |
} |
ui_out_list_begin (uiout, NULL); |
ui_out_field_core_addr (uiout, "address", pc); |
|
if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped)) |
{ |
/* We don't care now about line, filename and |
unmapped. But we might in the future. */ |
ui_out_field_string (uiout, "func-name", name); |
ui_out_field_int (uiout, "offset", offset); |
} |
if (filename != NULL) |
free (filename); |
if (name != NULL) |
free (name); |
|
ui_file_rewind (stb->stream); |
pc += (*tm_print_insn) (pc, &di); |
ui_out_field_stream (uiout, "inst", stb); |
ui_file_rewind (stb->stream); |
ui_out_list_end (uiout); |
} |
ui_out_list_end (uiout); |
} |
gdb_flush (gdb_stdout); |
|
return MI_CMD_DONE; |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-cmd-stack.c
0,0 → 1,317
/* MI Command Set - stack commands. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "target.h" |
#include "frame.h" |
#include "value.h" |
#include "mi-cmds.h" |
#include "ui-out.h" |
|
#ifdef UI_OUT |
/* FIXME: these should go in some .h file but stack.c doesn't have a |
corresponding .h file. These wrappers will be obsolete anyway, once |
we pull the plug on the sanitization. */ |
extern void select_frame_command_wrapper (char *, int); |
#endif |
|
static void list_args_or_locals (int locals, int values, struct frame_info *fi); |
|
/* Print a list of the stack frames. Args can be none, in which case |
we want to print the whole backtrace, or a pair of numbers |
specifying the frame numbers at which to start and stop the |
display. If the two numbers are equal, a single frame will be |
displayed. */ |
enum mi_cmd_result |
mi_cmd_stack_list_frames (char *command, char **argv, int argc) |
{ |
int frame_low; |
int frame_high; |
int i; |
struct frame_info *fi; |
|
if (!target_has_stack) |
error ("mi_cmd_stack_list_frames: No stack."); |
|
if (argc > 2 || argc == 1) |
error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]"); |
|
if (argc == 2) |
{ |
frame_low = atoi (argv[0]); |
frame_high = atoi (argv[1]); |
} |
else |
{ |
/* Called with no arguments, it means we want the whole |
backtrace. */ |
frame_low = -1; |
frame_high = -1; |
} |
|
/* Let's position fi on the frame at which to start the |
display. Could be the innermost frame if the whole stack needs |
displaying, or if frame_low is 0. */ |
for (i = 0, fi = get_current_frame (); |
fi && i < frame_low; |
i++, fi = get_prev_frame (fi)); |
|
if (fi == NULL) |
error ("mi_cmd_stack_list_frames: Not enough frames in stack."); |
|
ui_out_list_begin (uiout, "stack"); |
|
/* Now let;s print the frames up to frame_high, or until there are |
frames in the stack. */ |
for (; |
fi && (i <= frame_high || frame_high == -1); |
i++, fi = get_prev_frame (fi)) |
{ |
QUIT; |
/* level == i: always print the level 'i' |
source == LOC_AND_ADDRESS: print the location and the address |
always, even for level 0. |
args == 0: don't print the arguments. */ |
print_frame_info (fi /* frame info */ , |
i /* level */ , |
LOC_AND_ADDRESS /* source */ , |
0 /* args */ ); |
} |
|
ui_out_list_end (uiout); |
if (i < frame_high) |
error ("mi_cmd_stack_list_frames: Not enough frames in stack."); |
|
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_stack_info_depth (char *command, char **argv, int argc) |
{ |
int frame_high; |
int i; |
struct frame_info *fi; |
|
if (!target_has_stack) |
error ("mi_cmd_stack_info_depth: No stack."); |
|
if (argc > 1) |
error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]"); |
|
if (argc == 1) |
frame_high = atoi (argv[0]); |
else |
/* Called with no arguments, it means we want the real depth of |
the stack. */ |
frame_high = -1; |
|
for (i = 0, fi = get_current_frame (); |
fi && (i < frame_high || frame_high == -1); |
i++, fi = get_prev_frame (fi)) |
QUIT; |
|
ui_out_field_int (uiout, "depth", i); |
|
return MI_CMD_DONE; |
} |
|
/* Print a list of the locals for the current frame. With argument of |
0, print only the names, with argument of 1 print also the |
values. */ |
enum mi_cmd_result |
mi_cmd_stack_list_locals (char *command, char **argv, int argc) |
{ |
if (argc != 1) |
error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES"); |
|
list_args_or_locals (1, atoi (argv[0]), selected_frame); |
return MI_CMD_DONE; |
} |
|
/* Print a list of the arguments for the current frame. With argument |
of 0, print only the names, with argument of 1 print also the |
values. */ |
enum mi_cmd_result |
mi_cmd_stack_list_args (char *command, char **argv, int argc) |
{ |
int frame_low; |
int frame_high; |
int i; |
struct frame_info *fi; |
|
if (argc < 1 || argc > 3 || argc == 2) |
error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]"); |
|
if (argc == 3) |
{ |
frame_low = atoi (argv[1]); |
frame_high = atoi (argv[2]); |
} |
else |
{ |
/* Called with no arguments, it means we want args for the whole |
backtrace. */ |
frame_low = -1; |
frame_high = -1; |
} |
|
/* Let's position fi on the frame at which to start the |
display. Could be the innermost frame if the whole stack needs |
displaying, or if frame_low is 0. */ |
for (i = 0, fi = get_current_frame (); |
fi && i < frame_low; |
i++, fi = get_prev_frame (fi)); |
|
if (fi == NULL) |
error ("mi_cmd_stack_list_args: Not enough frames in stack."); |
|
ui_out_list_begin (uiout, "stack-args"); |
|
/* Now let's print the frames up to frame_high, or until there are |
frames in the stack. */ |
for (; |
fi && (i <= frame_high || frame_high == -1); |
i++, fi = get_prev_frame (fi)) |
{ |
QUIT; |
ui_out_list_begin (uiout, "frame"); |
ui_out_field_int (uiout, "level", i); |
list_args_or_locals (0, atoi (argv[0]), fi); |
ui_out_list_end (uiout); |
} |
|
ui_out_list_end (uiout); |
if (i < frame_high) |
error ("mi_cmd_stack_list_args: Not enough frames in stack."); |
|
return MI_CMD_DONE; |
} |
|
/* Print a list of the locals or the arguments for the currently |
selected frame. If the argument passed is 0, printonly the names |
of the variables, if an argument of 1 is passed, print the values |
as well. */ |
static void |
list_args_or_locals (int locals, int values, struct frame_info *fi) |
{ |
struct block *block; |
struct symbol *sym; |
int i, nsyms; |
int print_me = 0; |
static struct ui_stream *stb = NULL; |
|
stb = ui_out_stream_new (uiout); |
|
block = get_frame_block (fi); |
|
ui_out_list_begin (uiout, locals ? "locals" : "args"); |
|
while (block != 0) |
{ |
nsyms = BLOCK_NSYMS (block); |
for (i = 0; i < nsyms; i++) |
{ |
sym = BLOCK_SYM (block, i); |
switch (SYMBOL_CLASS (sym)) |
{ |
default: |
case LOC_UNDEF: /* catches errors */ |
case LOC_CONST: /* constant */ |
case LOC_TYPEDEF: /* local typedef */ |
case LOC_LABEL: /* local label */ |
case LOC_BLOCK: /* local function */ |
case LOC_CONST_BYTES: /* loc. byte seq. */ |
case LOC_UNRESOLVED: /* unresolved static */ |
case LOC_OPTIMIZED_OUT: /* optimized out */ |
print_me = 0; |
break; |
|
case LOC_ARG: /* argument */ |
case LOC_REF_ARG: /* reference arg */ |
case LOC_REGPARM: /* register arg */ |
case LOC_REGPARM_ADDR: /* indirect register arg */ |
case LOC_LOCAL_ARG: /* stack arg */ |
case LOC_BASEREG_ARG: /* basereg arg */ |
if (!locals) |
print_me = 1; |
break; |
|
case LOC_LOCAL: /* stack local */ |
case LOC_BASEREG: /* basereg local */ |
case LOC_STATIC: /* static */ |
case LOC_REGISTER: /* register */ |
if (locals) |
print_me = 1; |
break; |
} |
if (print_me) |
{ |
if (values) |
ui_out_list_begin (uiout, NULL); |
ui_out_field_string (uiout, "name", SYMBOL_NAME (sym)); |
|
if (values) |
{ |
struct symbol *sym2; |
if (!locals) |
sym2 = lookup_symbol (SYMBOL_NAME (sym), |
block, VAR_NAMESPACE, |
(int *) NULL, |
(struct symtab **) NULL); |
else |
sym2 = sym; |
print_variable_value (sym2, fi, stb->stream); |
ui_out_field_stream (uiout, "value", stb); |
ui_out_list_end (uiout); |
} |
} |
} |
if (BLOCK_FUNCTION (block)) |
break; |
else |
block = BLOCK_SUPERBLOCK (block); |
} |
ui_out_list_end (uiout); |
ui_out_stream_delete (stb); |
} |
|
enum mi_cmd_result |
mi_cmd_stack_select_frame (char *command, char **argv, int argc) |
{ |
#ifdef UI_OUT |
if (!target_has_stack) |
error ("mi_cmd_stack_select_frame: No stack."); |
|
if (argc > 1) |
error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]"); |
|
/* with no args, don't change frame */ |
if (argc == 0) |
select_frame_command_wrapper (0, 1 /* not used */ ); |
else |
select_frame_command_wrapper (argv[0], 1 /* not used */ ); |
#endif |
return MI_CMD_DONE; |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/ChangeLog-mi
0,0 → 1,1401
2000-05-07 Eli Zaretskii <eliz@is.elta.co.il> |
|
* gdbmi.texinfo: Lots of typos and grammar fixes from Brian |
Youmans <3diff@gnu.org>. |
|
Wed Apr 26 18:35:19 2000 Andrew Cagney <cagney@b1.cygnus.com> |
|
* gdbmi.texinfo (GDB/MI Output Syntax v2.0): Convert Draft 2.0 |
Output Syntax into a new section. Cross reference. |
(menu): Fix tipo. GDB/MI Compatibility with CLI. |
|
2000-04-23 Eli Zaretskii <eliz@is.elta.co.il> |
|
* gdbmi.texinfo: Lots of changes, to include this document as part |
of the GDB manual. |
|
2000-03-13 James Ingham <jingham@leda.cygnus.com> |
|
* mi-cmd-var.c (mi_cmd_var_create): Add special frame cookie "@" |
to indicate an "USE_CURRENT_FRAME" variable. |
(varobj_update_one): Add "in_scope" and "type_changed" to the |
result. |
|
2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.h: Export mi_cmd_data_write_register_values. |
|
* mi-cmds.c (mi_cmds): Implement data-write-register-values with |
mi_cmd_data_write_register_values. |
|
* mi-main.c (mi_cmd_data_write_register_values): New |
function. Write a value into a register. |
|
2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Update data-disassemble documentation. |
|
2000-03-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmd-disas.c (mi_cmd_disassemble): Use |
ui_out_field_core_addr() instead of print_address_numeric(), to |
maintain consistency throughout MI. |
|
Wed Feb 23 17:09:39 2000 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmd-break.c, mi-cmd-disas.c, mi-cmd-stack.c, mi-cmd-var.c, |
mi-cmds.c, mi-cmds.h, mi-console.c, mi-console.h, mi-getopt.c, |
mi-getopt.h, mi-main.c, mi-out.c, mi-out.h, mi-parse.c, |
mi-parse.h: Update copyright information. |
|
Wed Feb 23 13:31:16 2000 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmd-disas.c (gdb_dis_asm_read_memory): Change LEN to unsigned |
long. Match ../include/dis-asm.h change. |
|
Wed Feb 23 10:30:55 2000 Andrew Cagney <cagney@b1.cygnus.com> |
|
* gdbmi.texinfo: Update copyright - FSF. Update version |
information. |
|
mi-cmd-break.c, mi-cmd-disas.c, mi-cmd-stack.c, mi-cmd-var.c, |
mi-cmds.h, mi-main.c, mi-parse.c, mi-parse.h: Re-format using GNU |
indent. |
|
2000-02-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c: Add include of gdbcore.h for write_memory() |
prototype. |
|
2000-02-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmd-disas.c (mi_cmd_disassemble): Change syntax of |
command. Now use options. |
Instead of printing the symbolic address of instructions via |
print_address_symbolic(), use build_address_symbolic() and format |
properly for output. |
(gdb_do_disassmble): Delete. |
|
2000-02-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmd-disas.c (mi_cmd_disassemble): |
|
2000-02-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_data_write_memory): New function. Write a |
value into target memory. |
|
* mi-cmds.h (mi_cmd_data_write_memory): Export. |
|
* mi-cmds.c (mi_cmds): Hook up data-write-memory to |
mi_cmd_data_write_memory(). |
|
2000-02-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_target_download): Correct error message to |
report right function name. |
(mi_cmd_target_select): Add doing exec cleanups at end. |
(mi_cmd_data_read_memory): Correct typo. |
(mi_cmd_execute): Do not simply free last_async_command, but reset |
it to NULL as well. |
(free_and_reset): New function, free the argument and set it to |
NULL. |
(mi_cmd_target_select_continuation): Delete prototype. |
|
Tue Feb 1 00:17:12 2000 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmd-disas.c, mi-cmds.h, mi-console.c, mi-console.h, |
mi-main.c, mi-out.c, mi-out.h: Update to reflect rename of |
gdb-file / GDB_FILE to ui-file / ``struct ui_file''. |
|
Mon Jan 31 18:33:28 2000 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_command_loop): Delete reference to |
fputs_unfiltered_hook. |
|
2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Update entries for |
mi_cmd_data_list_register_names, |
mi_cmd_data_list_changed_registers, |
mi_cmd_data_list_register_values. |
|
* mi-cmds.h (mi_cmd_data_list_register_names, |
mi_cmd_data_list_changed_registers, |
mi_cmd_data_list_register_values): Update to mi_cmd_argv_ftype. |
|
* mi-main.c (mi_cmd_data_list_register_names, |
mi_cmd_data_list_changed_registers, |
mi_cmd_data_list_register_values): Update to use argc, argv |
parameters. |
|
2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_data_read_memory): Correct the computation of |
next-row. |
|
2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmd-var.c (mi_cmd_var_create): Test for NULL type. |
(mi_cmd_var_set_format, mi_cmd_var_show_format, |
mi_cmd_var_info_num_children, mi_cmd_var_list_children, |
mi_cmd_var_info_type, mi_cmd_var_info_expression, |
mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression, |
mi_cmd_var_assign, mi_cmd_var_update): Prevent possibility of memory |
leak on error. |
|
2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c (mi_field_string): Test for NULL string pointer. |
|
2000-01-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmd-stack.c (mi_cmd_stack_list_frames): Call |
print_frmae_info() with the correct arguments. |
|
* mi-main.c (mi_cmd_exec_return): Call |
show_and_print_stack_frame() with LOC_AND_ADDRESS, so it does the |
right thing. Update Copyright. |
|
2000-01-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c: Move disassemble commands from here. |
|
* mi-cmd-disas.c: To here. New file. |
|
2000-01-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmd-stack.c: Remove include of mi-out.h. |
|
* mi-main.c (mi_cmd_disassemble): Update function to use argc/argv |
interface. |
|
* mi-cmds.h: Ditto. |
|
* mi-cmds.c: Ditto. |
|
2000-01-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Update stack commands descriptions. |
Add thread commands descriptions and examples. |
|
* mi-main.c (mi_cmd_thread_list_ids): Fix typo. |
|
2000-01-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_thread_list_ids): New function, print a list |
of currently known threads ids, and the total number of threads. |
(mi_cmd_thread_select): New function. Switch current thread. |
|
* mi-cmds.c (mi_cmds): Implement thread-list-ids by |
mi_cmd_thread_list_ids, and thread-select by mi_cmd_thread_select. |
|
* mi-cmds.h (mi_cmd_thread_select, mi_cmd_thread_list_ids): Export. |
|
2000-01-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c: Move stack commands from here. |
|
* mi-cmd-stack.c: To here. New file. |
|
2000-01-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (list_args_or_locals): Add a new paramter, the frame |
for which to display args or locals. Don't use selected_frame |
anymore, use the new parameter instead. Return void instead of |
mi_cmd_result, let callers do so. |
(mi_cmd_stack_list_args): Change interface. Now accept low and |
high frame numbers to display args for a range of frames. Without |
these two, display args for the whole stack. |
(mi_cmd_stack_list_locals): Adapt to new interface for |
list_args_or_locals. |
|
2000-01-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_stack_info_depth, mi_cmd_stack_list_args, |
mi_cmd_stack_list_frames, mi_cmd_stack_list_locals, |
mi_cmd_stack_select_frame): Change to use argv type of parameters. |
|
* mi-cmds.c (mi_cmds): Change stack-info-depth, |
stack-list-arguments, stack-list-frames, stack-list-locals, |
stack-select-frame to use argv parameters. |
|
* mi-cmds.h (mi_cmd_stack_info_depth, mi_cmd_stack_list_args, |
mi_cmd_stack_list_frames, mi_cmd_stack_list_locals, |
mi_cmd_stack_select_frame): Update definitions. |
|
Tue Jan 4 12:38:54 2000 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_command_loop): Force the MI interface to use seven |
bit strings. |
* gdbmi.texinfo: Make it clear that a quoted C string is seven |
bit. |
|
Thu Dec 30 14:15:22 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-getopt.c (mi_getopt): Rewrite. Allow long options. |
* mi-getopt.h (struct mi_opt): Declare. |
(mi_getopt): Update. |
|
* mi-main.c (mi_cmd_data_read_memory), mi-cmd-break.c |
(mi_cmd_break_insert, mi_cmd_break_watch): Update. |
|
Wed Dec 29 23:38:35 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmd-break.c (mi_cmd_break_insert): Add support for -c |
<condition>, -i <ignore-count> and -p <thread>. |
(breakpoint_notify): New function. |
(mi_cmd_break_insert): Wrap GDB call with callback hooks so that |
MI is notified when ever a breakpoint is created. |
|
* gdbmi.texinfo: Update. |
|
Fri Dec 24 11:23:22 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (gdb_do_disassemble): Strip out more useless #ifdef |
UI_OUTs. |
|
1999-12-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (gdb_do_disassemble): Fix output. Lines that have no |
assembly instructions must still be outputted, to keep the source |
line numbering correct. |
Remove #ifdef UI_OUT's, they are useless. |
|
1999-12-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (gdb_do_disassemble): Don't print a new list in mixed |
mode, every time. Just do it when we actually encounter a new |
source line. |
|
1999-12-17 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmd-var.c (mi_cmd_var_list_children): Add test for C++ pseudo |
variable objects (private, public, protected) as these do not have |
a type and the -var-list-children operation was dumping core. |
|
Fri Dec 17 20:23:33 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* gdbmi.texinfo: Document recommended syntax for options. |
|
* mi-main.c (mi_cmd_data_read_memory): Add support for ``-o |
<offset>''. |
* gdbmi.texinfo: Document. |
|
Wed Dec 15 17:43:08 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-getopt.h (mi_getopt): Change optarg to a char pointer. Check |
optind. |
* mi-cmd-break.c (mi_cmd_break_insert): Update. |
|
* mi-main.c (mi_cmd_data_read_memory): Add fields "next-row-addr", |
"prev-row-addr", "next-page-addr", "prev-page-addr" and a per row |
"addr". |
* gdbmi.texinfo: Update. |
|
Wed Dec 15 01:05:40 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h (mi_cmd_result): Add MI_CMD_CAUGHT_ERROR for when the |
error is caught. |
|
* mi-main.c (captured_mi_execute_command): When |
MI_CMD_CAUGHT_ERROR return 0 rethrowing the eror. |
|
1999-12-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmd-break.c (mi_cmd_break_insert): Remove unused var. |
|
* mi-cmd-var.c (mi_cmd_var_update): Remove unused variables. |
|
Mon Dec 13 18:43:36 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-parse.c (mi_parse): Quote the command when printing it. |
(mi_parse_argv): Fix handling of quoted strings. Was not |
de-quoting them. |
(mi_parse_argv): Make static. |
|
Mon Dec 13 18:30:03 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h (mi_cmd_break_insert, mi_cmd_break_watch): Change type |
to mi_cmd_argv_ftype. |
* mi-cmds.c (mi_cmds): Update. |
* mi-cmd-break.c (mi_cmd_break_insert, mi_cmd_break_watch): Change |
to new style of arguments with argc and argv. Parse arguments |
using mi_getopt. |
|
* mi-cmd-break.c (mi_cmd_break_insert): Wrap body in #ifdef UI_OUT |
to avoid non-ui compile problems. |
|
Mon Dec 13 15:08:36 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-getopt.h, mi-getopt.c: New files. Similar to getopt but with |
well defined semantics. |
|
Mon Dec 13 14:22:21 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_cmd_break_insert, mi_cmd_break_watch, enum |
wp_type, enum bp_type): Move from here. |
* mi-cmd-break.c: To here. New file. |
(mi_cmd_break_insert, mi_cmd_break_insert, mi_cmd_break_watch): |
Use error to report problems. |
|
1999-12-09 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Update description of exec-interrupt. |
|
* mi-main.c (mi_cmd_exec_interrupt): If the program is not |
executing, don't try to interrupt it, but error out instead. Make |
sure previous_async_command is not null before duplicating it into |
last_async_command. |
|
* gdbmi.texinfo: Add examples for data-evaluate-expression. |
|
1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmd-var.c (mi_cmd_var_assign, mi_cmd_var_create, |
mi_cmd_var_delete, mi_cmd_var_evaluate_expression, |
mi_cmd_var_info_expression, mi_cmd_var_info_num_children, |
mi_cmd_var_info_type, mi_cmd_var_list_children, |
mi_cmd_var_set_format, mi_cmd_var_show_attributes, |
mi_cmd_var_show_format, mi_cmd_var_update): Change to use new |
style of arguments with argc and argv. |
(next_arg): Delete. |
(which_var): Delete. |
|
* mi-cmds.c (mi_cmds): Update entries for mi_cmd_var_assign, |
mi_cmd_var_create, mi_cmd_var_delete, |
mi_cmd_var_evaluate_expression, mi_cmd_var_info_expression, |
mi_cmd_var_info_num_children, mi_cmd_var_info_type, |
mi_cmd_var_list_children, mi_cmd_var_set_format, |
mi_cmd_var_show_attributes, mi_cmd_var_show_format, |
mi_cmd_var_update. |
|
* mi-cmds.h (mi_cmd_var_assign, mi_cmd_var_create, |
mi_cmd_var_delete, mi_cmd_var_evaluate_expression, |
mi_cmd_var_info_expression, mi_cmd_var_info_num_children, |
mi_cmd_var_info_type, mi_cmd_var_list_children, |
mi_cmd_var_set_format, mi_cmd_var_show_attributes, |
mi_cmd_var_show_format, mi_cmd_var_update): Update declarations. |
|
1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Comment out -data-assign command. * mi-main.c |
(mi_cmd_data_assign): Do not use, comment out. * mi-cmds.h |
(mi_cmd_data_assign): Remove. * mi-cmds.c: Remove -data-assign |
command from MI interface. |
|
1999-12-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-parse.c (mi_parse): Add '\n' at end of error messages, so |
that prompt comes out on new line. |
|
* gdbmi.texinfo: Update disassembly command output. |
|
1999-12-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (gdb_do_disassemble): Update output for UI_OUT case. |
|
1999-12-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Update exec-until output, including the reason |
for stopping. |
|
Thu Dec 2 17:17:22 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.c: Include <string.h> for memset. |
|
1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_exec_return): ifdef the references to |
return_command_wrapper(). |
|
1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_interrupt, |
mi_cmd_target_select, mi_execute_async_cli_command, |
mi_exec_async_cli_cmd_continuation, mi_load_progress): Don't print |
last_async_command if it is NULL. |
(mi_cmd_exec_return): |
|
1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_exec_return): Reimplement using |
return_command() instead of mi_execute_async_cli_command(). |
|
1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.h: Export mi_cmd_data_assign and |
mi_cmd_data_evaluate_expression. |
|
* mi-cmds.c (mi_cmds): Hook data-assign to mi_cmd_data_assign and |
data-evaluate-expression to mi_cmd_data_evaluate_expression. |
|
* mi-main.c (mi_cmd_data_assign): New function. Implement |
data-assign command. |
(mi_cmd_data_evaluate_expression): New function. Implement |
data-evaluate-expression command. |
|
1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Fix some texinfo formatting errors. |
|
1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Update data-list-register-values description. |
|
* mi-cmds.h: Export mi_cmd_data_list_register_values. |
|
* mi-cmds.c (mi_cmds): Hook data-list-register-values to |
mi_cmd_data_list_register_values. |
|
* mi-main.c (mi_cmd_data_list_register_values): New |
function. Implements the -data-list-register-values command. |
(get_register): New function. Output the contents of a given |
register. |
|
Wed Dec 1 20:27:22 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_execute_async_cli_command): Append missing "\n" |
for synchronous stopped message. |
|
1999-11-30 James Ingham <jingham@leda.cygnus.com> |
|
* gdbmi.texinfo: Fix obvious typo in @end statement. |
|
Wed Dec 1 12:36:27 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmd-var.c: Include "value.h". |
* mi-console.c: Include <string.h>. |
|
Wed Dec 1 00:21:03 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (captured_mi_execute_command): For a CLI command, pass |
"%s" to mi_execute_cli_command to stop core dumps. |
(captured_mi_execute_command): Echo CLI commands on gdb_stdlog. |
|
Wed Dec 1 00:10:07 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* gdbmi.texinfo: Explain NR-BYTES and ADDR. |
|
Tue Nov 30 23:31:57 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmd-var.c (mi_cmd_var_create, mi_cmd_var_delete, |
mi_cmd_var_set_format, mi_cmd_var_show_format, |
mi_cmd_var_info_num_children, mi_cmd_var_list_children, |
mi_cmd_var_info_type, mi_cmd_var_info_expression, |
mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression, |
mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one, next_arg, |
which_var): New file. Move varobj commands to here from |
mi-main.c. |
|
* mi-console.h, mi-console.c (mi_console_file_new, |
mi_console_file_delete, mi_console_file_fputs, |
mi_console_raw_packet, mi_console_file_flush): New files. Move |
mi_console_file to here from mi-main.c. |
|
Tue Nov 30 19:37:25 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (captured_mi_execute_command): Use fputstr_unfiltered |
when printing error messages. |
(mi_cmd_execute): Ditto. |
|
1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Describe -data-list-changed-registers, |
-data-list-register-names. Add examples for |
-exec-next-instruction, exec-step-instruction, -exec-run, |
-exec-until. Format examples for -data-read-memory. |
update example for -target-download. |
|
1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Remove mentioning of inaccurate watchpoint hit |
count. |
|
Mon Nov 29 19:28:55 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_execute_async_cli_command): Return ``enum |
mi_cmd_cmd_result''. mi_cmd_exec_run, mi_cmd_exec_next, |
mi_cmd_exec_step, mi_cmd_exec_step_instruction, |
mi_cmd_exec_finish, mi_cmd_exec_until, mi_cmd_exec_return, |
mi_cmd_exec_continue): Update call. |
(mi_execute_async_cli_command): When target is synchronous, fake |
asynchronous behavour (ulgh). Allows tests to be run on built-in |
simulator and native targets. |
|
Mon Nov 29 15:15:16 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h (mi_cmd_gdb_exit), mi-cmds.c (mi_cmds), mi-main.c |
(mi_cmd_gdb_exit): Change function signature to mi_cmd_argv_ftype. |
|
1999-11-28 Andew Cagney <cagney@rat-in-a-hat.cygnus.com> |
|
* mi-parse.c: Include <ctype.h> and <string.h> |
|
1999-11-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* gdbmi.texinfo: Added watchpoint command descriptions and |
examples. |
|
* mi-main.c (mi_load_progress): Add parameter for total sent so far. |
Print it as well. |
|
Fri Nov 26 10:17:49 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* gdbmi.texinfo (section Output Syntax): For lists, the <string> |
part of a <result> is optional. Clarify syntax. |
(appendix Proposed v2.0 Output Syntax): New section. Provide |
record of discussion of possible changes to syntax. |
|
Wed Nov 24 19:41:35 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_cmd_data_read_memory): Simplify. Fix coredump |
when arguments were bad. |
(mi_cmd_execute): Change parameter to ``struct mi_parse''. Handle |
case of argv_func as well as args_func. |
(captured_mi_execute_command): Update. |
|
* mi-cmds.c (struct mi_cmd): Add field for mi_cmd_argv_ftype. |
(mi_cmds): Update mi_cmd_data_read_memory. |
(mi_lookup): Return |
|
* mi-cmds.h (mi_cmd_args_ftype): Rename mi_cmd_ftype. Make all |
functions of type this type. |
(mi_cmd_argv_ftype): Declare. |
(mi_cmd_data_read_memory): Change type to mi_cmd_argv_fytpe. |
(struct mi_cmd): Move declaration to here from mi-cmds.c. |
(mi_lookup): Return a pointer to ``struct mi_cmd''. |
|
Wed Nov 24 15:03:34 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-parse.c (mi_parse): Initialize TOKEN when a CLI command. |
|
* gdbmi.texinfo: Allow a <token> before a CLI command. |
|
* mi-parse.h (struct mi_parse): Declare. |
(mi_parse): Change to return a ``struct mi_parse''. |
(enum mi_command_type): Delete PARSE_ERROR. |
|
* mi-main.c (struct mi_execute_command_context): Delete. |
(captured_mi_execute_command): Update |
(mi_execute_command): Update. Check for mi_parse returning NULL. |
|
Wed Nov 24 12:57:14 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-parse.h: Remove const, from cmd parameter. Causes cascading |
warnings. |
|
Wed Nov 24 15:03:34 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-parse.c (mi_parse): New function. Move parse code to here. |
* mi-main.c (parse): From here. Delete. |
|
Wed Nov 24 12:57:14 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-parse.c, mi-parse.h: New files. Implement mi_parse_env. |
|
Wed Nov 24 11:24:05 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-out.c (mi_field_string): Make string parameter constant. |
|
1999-11-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.h (mi_cmd_target_download): Export. |
|
* mi-cmds.c (mi_cmds): Add mi_cmd_target_download. |
|
* mi-main.c: Include <sys/time.h>. |
(mi_cmd_target_download): New function, implement the |
target-download command. |
(mi_load_progress): New function. Called via the |
show_load_progress hook. Prints updates every 0.5 secs. |
(mi_command_loop): Initialize the show_load_progress hook. |
|
1999-11-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_exec_until): New function. Implement until |
command. |
(mi_cmd_exec_step_instruction): New function. Implement stepi |
command. |
(mi_cmd_exec_next_instruction): New function. Implement nexti |
command. |
|
* mi-cmds.c (mi_cmds): Add mi_cmd_exec_step_instruction, |
mi_cmd_exec_next_instruction, mi_cmd_exec_until. |
|
* mi-cmds.h (mi_cmd_exec_step_instruction, |
mi_cmd_exec_next_instruction, mi_cmd_exec_until): Export. |
|
Tue Nov 23 00:30:37 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi/gdbmi.texinfo: Document -data-read-memory. |
|
* mi-main.c (mi_cmd_data_read_memory): Fix off-by-one check of |
argc. |
(mi_cmd_data_read_memory): Label the output table with "memory". |
|
Thu Nov 18 18:15:53 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_cmd_exec_interrupt, mi_cmd_break_insert, |
mi_cmd_break_watch, mi_cmd_disassemble, mi_cmd_execute): Replace |
strdup with xstrdup. |
|
Thu Nov 18 20:50:09 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_cmd_data_read_memory): New function. Implement |
data-read-memory. |
|
* mi-cmds.h, mi-cmds.c: Add mi_cmd_data_read_memory. |
* mi-cmds.c (mi_cmds): Ditto. |
|
1999-11-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.h (mi_cmd_break_watch): Export. |
|
* mi-cmds.c (mi_cmds): Hook up break-watch to function |
mi_cmd_break_watch. |
|
* mi-main.c (wp_type): New enumeration for the possible types of |
watchpoints. |
(mi_cmd_break_watch): New function, implements the break-watch |
command. |
|
1999-11-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_break_insert): Handle case in which the command is |
just a -break-insert w/o args. |
|
Fri Nov 12 00:01:52 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-out.c (mi_field_string): Always quote the string. |
|
1999-11-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.h(mi_cmd_data_list_changed_registers, |
mi_cmd_data_list_register_names): Export. |
|
* mi-cmds.c (mi_cmds): Hook up data-list-changed-registers to |
mi_cmd_data_list_changed_registers and data-list-register-names to |
mi_cmd_data_list_register_names. |
|
* mi-main.c (mi_cmd_data_list_changed_registers): New function, |
implements the data-list-changed-registers command. |
(mi_cmd_data_list_register_names): New function, implements the |
data-list-register-names command. |
(register_changed_p): New function. Decide whether the register |
contents have changed. |
(setup_architecture_data): New function. Initialize registers |
memory. |
(_initialize_mi_main): Call setup_architecture_data(), and |
register_gdbarch_swap(). |
|
Wed Nov 10 18:35:08 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_execute_command): Correctly quote error messages. |
|
Wed Nov 10 11:05:14 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi/gdbmi.texinfo: Delete <stream-output>. Replaced by |
<c-string>. |
|
* mi-main.c (mi_console_raw_packet): Always quote console output. |
|
Tue Nov 9 17:53:05 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_console_file_new), mi-out.c (mi_out_new): Replace |
the tui_file with a mem_file. Ya! |
|
* mi-out.c (do_write): New function, wrapper to gdb_file_write. |
(mi_out_put): Pass do_write to gdb_file_put. |
|
* mi-main.c (mi_console_file_flush): Rewrite. Use |
mi_console_raw_packet to send data to the console. |
(mi_console_raw_packet): New function. Correctly |
create quoted C string packets. |
|
1999-11-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Break-insert is now implemented by |
mi_cmd_break_insert. |
* mi-cmds.h (mi_cmd_break_insert): Export. |
* mi-main.c (bp_type): New enumeration. |
(mi_cmd_break_insert): New function. Implements all flavors of |
breakpoint insertion. |
|
Mon Nov 8 17:49:17 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_console_file_flush): Replace gdb_file_get_strbuf |
with tui_file_get_strbuf. |
|
Fri Nov 5 17:06:07 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_console_file_delete, mi_console_file_fputs, |
mi_console_file_flush): Call internal_error instead of error. |
|
Thu Nov 4 19:53:32 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (captured_mi_execute_command): New function. |
(mi_execute_command): Rewrite. Replace SET_TOP_LEVEL() with call |
to captured_mi_execute_command via catch_errors. |
|
Thu Nov 4 20:33:58 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (clean): Delete. |
(mi_command_loop): Delete extern declaration of |
mi_execute_command. |
|
1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_stack_select_frame): Conditionalize the body |
on UI_OUT, because select_frame_command_wrapper is only defined if |
UI_OUT is. |
(mi_cmd_exec_interrupt): Conditionalize the body on UI_OUT, |
because interrupt_target_command_wrapper is only defined if UI_OUT is. |
|
* mi-cmds.c (mi_cmds): Implement command exec-interrupt by |
mi_cmd_exec_interrupt. |
|
* mi-main.c (mi_cmd_exec_interrupt): New function. Implements |
exec-interrupt command. |
(mi_cmd_execute): If the target is running save execution command |
token in previous_async_command. If the command is not 'interrupt' |
and the target is running, reject it. |
(clean): New function. Free the arg and reset it to NULL. |
|
* mi-cmds.h (mi_cmd_exec_interrupt):Export. |
|
1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Implement command stack-select-frame by |
mi_cmd_stack_select_frame. |
|
* mi-main.c (mi_cmd_stack_select_frame): New function. Implements |
stack-select-frame command. |
|
* mi-cmds.h (mi_cmd_select_frame):Export. |
|
1999-10-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Implement commands stack-list-locals and |
stack-list-arguments by mi_cmd_stack_list_locals and |
mi_cmd_stack_list_args. |
|
* mi-main.c (mi_cmd_stack_list_locals): New function. Implements |
stack-list-locals command. |
(mi_cmd_stack_list_args): New function. Implements |
stack-list-arguments command. |
(list_args_or_locals): New function. Do all the work for the |
listing of locals or arguments. |
|
* mi-cmds.h (mi_cmd_stack_list_args,mi_cmd_stack_list_locals) : |
Export. |
|
1999-10-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Add new command stack-info-depth. |
|
* mi-main.c (mi_cmd_stack_info_depth): New function. Implements |
the stack-info-depth command. |
* mi-cmds.h (mi_cmd_stack_info_depth): Export. |
|
|
1999-10-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_execute_command): Handle MI_CMD_ERROR case |
properly, for command that return error code and don't set |
mi_error_message. |
|
* mi-cmds.c (mi_cmds): Hook stack-list-frames command to |
mi_cmd_stack_list_frames function. |
* mi-cmds.h (mi_cmd_stack_list_frames): Export. |
|
* mi-main.c (mi_execute_command): Deal with a return code of |
MI_CMD_ERROR from the execution of mi commands. |
(mi_error_message): Static string variable, to contain the error |
message from mi commands. |
(mi_cmd_stack_list_frames): New function. Prints a backtrace. |
|
1999-10-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_disassemble): Handle the new command line |
parameter that specifies the number of disassembly lines to be |
displayed. |
(gdb_do_disassemble): Add new parameter. Count the number of lines |
that have been displayed, and stop when limit is reached. |
|
Wed Oct 13 18:04:13 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_command_loop): Don't initialize ``flush_hook''. |
|
1999-10-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi/gdbmi.texinfo: More reformatting of the grammars. |
|
1999-10-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi/gdbmi.texinfo: More TeX formatting. |
|
1999-10-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi/gdbmi.texinfo: First pass completed. All commands should have |
some comments/info. |
Escape '@' output special char. |
Reformat for TeX. |
|
1999-10-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi/gdbmi.texinfo: Filled in part of file command section, and |
stack section. |
|
1999-10-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi/gdbmi.texinfo: Filled in some sections about execution |
commands. |
|
Tue Oct 5 15:27:28 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h: Sort table |
* mi-cmds.c: Ditto. |
(MI_TABLE_SIZE): Increase to 251. |
|
1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_cmd_var_create, mi_cmd_var_delete): Add missing |
cleanups. |
|
1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (next_arg): Returns lenght as well. |
(which_var, mi_cmd_var_create, mi_cmd_var_delete, |
mi_cmd_var_set_format, mi_cmd_var_update): Do not modify the input |
string, use allocated storage instead. |
(mi_cmd_var_assign): Adjust call to next_arg() to include new |
argument. |
|
1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_execute_command): Fix handling of errors. |
|
1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c (mi_out_new): Call tui_sfileopen() instead of |
deprecated gdb_file_init_astream(). |
* mi-main.c (mi_console_file_new): Ditto. |
|
Mon Oct 4 15:17:29 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h: Sort function declarations. |
(mi_lookup): Add extern. |
|
* mi-cmds.c (mi_lookup): Delete dead code. |
(build_table): Call internal_error instead of error. |
(build_table): Send trace output to gdb_stdlog. |
|
1999-10-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_execute_async_cli_command): Don't do the cleanups |
if target_executing is null. |
|
1999-09-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (async_p): Change var name to event_loop_p. |
|
Mon Sep 27 15:11:00 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_execute_async_cli_command, mi_execute_command): |
Replace target_has_async with function target_can_async_p. |
|
Sun Sep 26 00:12:52 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_cmd_target_select_continuation): Delete function. |
(mi_cmd_target_select): Simplify. target-connect is guarenteed to |
be synchronous. |
|
Sun Sep 26 00:12:52 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h (mi_cmd_ftype): Replace mi_impl_ftype. |
(enum mi_cmd_result): Define. |
* mi-cmds.c (struct mi_cmd): Update. |
(mi_lookup): Update. |
* mi-main.c (mi_cmd_execute): Update. |
|
* mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_run, mi_cmd_exec_next, |
mi_cmd_exec_step, mi_cmd_target_select, mi_cmd_exec_continue, |
mi_cmd_exec_return, mi_cmd_exec_finish, mi_cmd_disassemble, |
mi_cmd_var_create, mi_cmd_var_delete, mi_cmd_var_set_format, |
mi_cmd_var_show_format, mi_cmd_var_info_num_children, |
mi_cmd_var_list_children, mi_cmd_var_info_type, |
mi_cmd_var_info_expression, mi_cmd_var_show_attributes, |
mi_cmd_var_evaluate_expression, mi_cmd_var_update): Update. |
Return MI_CMD_DONE. |
|
1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_cmd_var_create): Use paddr() to format address |
on trace output. |
|
1999-09-21 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_cmd_var_create): Test for varobjdebug before |
printing trace and send it to gdb_stdlog. |
|
Mon Sep 20 13:41:04 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* Makefile.in (mi-out.o): Add dependency list. |
* mi-out.c: Include "mi-out.h". |
|
1999-09-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (_initialize_mi_main): Events on stadin are now |
handled by stdin_event_handler. |
|
1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Add var-* commands. |
|
1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_cmd_var_create, mi_cmd_var_delete, |
mi_cmd_var_set_format, mi_cmd_var_show_format, |
mi_cmd_var_info_num_children, mi_cmd_var_list_children, |
mi_cmd_var_info_type, mi_cmd_var_info_expression, |
mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression, |
mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one, |
which_var, next_arg): New functions. Implement the -var-* |
commands. |
* mi-cmds.h: Add prototypes for the above. |
|
1999-09-14 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Add detach command. |
|
1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmds.c (lookup_table): Fix typo. |
|
1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmds.c (mi_cmds): Fix typo and missing command. |
|
1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c: Properly align function prototypes. |
(mi_cmd_target_select): Proper check for NULL value. |
|
1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_execute_async_cli_command): Fix for native targets |
that do not have async yet. |
|
1999-09-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_disassemble): Remove unused var. |
(gdb_do_disassemble): Ditto. |
|
1999-08-30 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c: Replace all the occurrences of 'asynch' in variable |
or function names with 'async' to make it consistent with the rest |
of gdb. |
|
Mon Aug 30 18:16:39 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c: #include <ctype.h> for isspace(). |
|
1999-08-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (gdb_do_disassemble): This function returns void, not |
int. |
|
1999-08-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_disassemble): Don't use atoi() on the high |
address string, just treat it same as address low. |
(gdb_do_disassemble): Parse high_address string before seeing if |
it is zero. |
|
1999-08-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_disassemble): New function to produce |
disassembly output for mi. |
(gdb_dis_asm_read_memory): New function. Read the disassembly from |
the executable file, instead of target memory. |
(compare_lines): New function. Compare order of disassembly lines. |
(gdb_do_disassemble): New function. Do the real job of getting the |
assembly code out. |
|
* mi-cmds.c (mi_cmds): Do data-disassemble mi command via the |
mi_cmd_disassemble function. |
|
* mi-cmds.h: Export new function mi_cmd_disassemble. |
|
Wed Aug 25 15:58:31 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_command_loop): Remove references to ui-hooks. |
|
1999-08-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_execute_asynch_cli_command): Fix the incorrect |
usage of strcat(): allocate enough space for the string. |
|
1999-08-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
From Christopher Faylor <cgf@cygnus.com> |
* mi-main.c (mi_execute_command): Make sure we flush all the |
output after each command. |
|
1999-08-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (_initialize_mi_main): Remove casting in call to |
add_file_handler. |
|
Sun Aug 8 17:20:57 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_cmd_target_select, mi_execute_asynch_cli_command): |
Replace call to fatal with call to internal_error. |
|
1999-07-26 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_cmd_execute): Add return code. |
(mi_execute_command): Make appropriate changes when calling the |
function mentioned above. |
(mi_cmd_gdb_exit, mi_cmd_target_select, |
mi_cmd_target_select_continuation, mi_execute_command, |
mi_exec_asynch_cli_cmd, mi_exec_asynch_cli_cmd_continuation): |
Print token, prefix, class and output (if any) in one single group |
of statements. |
(mi_execute_command, mi_cmd_execute): Fix error prefix. |
(mi_cmd_execute): Use exec cleanup for token. |
* mi-out.c (mi_out_rewind): New function. |
* mi-out.h: Prototype for the above. |
|
1999-07-16 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_cmd_gdb_exit): Use buffer for exit message. |
(mi_cmd_execute): Route error messages to correct file. |
(mi_execute_asynch_cli_command): Insert line feed after running |
message. |
|
1999-07-16 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.h (mi_out_buffered): Add extern declaration. |
* mi-out.c (mi_out_buffered): New function. Insert a string at the |
current buffer position. |
* mi-main.c (mi_cmd_target_select, mi_execute_command, |
mi_cmd_execute, mi_execute_asynch_cli_command): Use the above |
function instead of printing to raw_stdout. |
(mi_cmd_target_select, mi_cmd_target_select_continuation, |
mi_execute_command, mi_cmd_execute, mi_execute_cli_command, |
mi_exec_asynch_cli_cmd_continuation): Fix handling of token and |
prefix. |
(mi_execute_cli_command): Remove parameter no longer needed. |
|
1999-07-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c (mi_cmd_target_select_continuation): Print the numeric |
token when we are connected. |
(mi_execute_command): Don't print the token now, do it later. |
(mi_execute_cli_command): Add a new parameter for the numeric |
token. Print the token, the prefix and the class after the |
command has executed, not before. |
(mi_execute_asynch_cli_command): Don't print an extra blank line. |
|
1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_gdb_exit): Add \n at the end. |
|
1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_cmd_execute): New function. Dispatch a mi operation. |
(mi_execute_command): Use the above. |
|
1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c: Fix identation. |
|
1999-07-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* mi-main.c: Include target.h and inferior.h. |
(mi_cmd_target_select): New function to execute the target-select |
mi operation. |
(mi_cmd_target_select_continuation): New function. Continuation |
for the target-select operation. |
(mi_execute_command): In case of an MI command which requires |
asynchronous execution, do not try to display the result now. If |
the execution has to look synchronous don't display the "(gdb)" |
prompt. |
(mi_execute_asynch_cli_command): Invoke real asynchronous |
commands, set up exec_cleanups, and continuations. |
(mi_exec_asynch_cli_cmd_continuation): New function. Continuation |
for all the MI execution commands except 'target-select'. |
(mi_execute_command): Handle null commands by exiting gdb, instead |
of core dumping. |
|
* mi-cmds.c (mi_cmds): Hook up -target-select operation to new mi |
function. |
|
* mi-cmds.h (mi_cmd_target_select): Add extern declaration. |
|
Thu Jul 15 10:31:39 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (struct mi_console_file): Add field ``prefix''. |
(mi_console_file_new): Add argument prefix. Initialize prefix |
field. |
(mi_console_file_flush): Use ``prefix'' instead of "~" as the |
prefix string. |
(mi_command_loop): Update stream output prefixes. gdb_stdout == |
"~", gdb_stderr / gdb_stdlog == "&", gdb_stdtarg == "@". |
|
1999-07-13 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (ui_out_data): New field first_header. Fix output when |
no breakpoints are found. |
(mi_table_begin, mi_table_body, mi_table_header): Test for |
first_header. |
(mi_table_end): Test for supress_field_separator. |
(mi_message): Remove messages from MI output. |
|
1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmds.c (mi_cmds[]): Delete gdb-cli operation. |
* mi-main.c (parse): Remove ifdefs for cli commands parsing. |
(mi-execute-command): Ditto. |
|
Mon Jun 28 13:06:52 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-out.h: New file. |
(mi_out_new, mi_out_put): Move mi specific delcarations to here. |
* ui-out.h: From here. |
|
* mi-main.c: Include "mi-out.h". |
|
1999-06-25 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* top.c (print_gdb_version): Add the word HEADLESS when output |
follows headless format. |
(print_command_lines): Fix typo. |
|
1999-06-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com> |
|
* event-loop.h: Export input_fd. |
* mi-main.c (mi_command_loop): Use the event loop if running |
asynchronously. |
(mi_execute_command_wrapper): New function. |
(_initialize_mi-main): Set things up for running asynchronously. |
|
1999-06-18 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmds.c (mi_lookup): Deleted. |
(lookup_table): New function. Replaces old mi_lookup() for local |
use. |
(mi_lookup): New function. External interface for command table |
searchs. |
(build_table): New definition. |
(mi_cmds[]): Add several command implementations and the gdb-cli |
special operation. |
(mi_cmd_execute): Deleted. |
* mi-cmds.h: Add type definition for command implementation |
function pointers, add declaration for new implementation |
functions and a declaration for mi_lookup(). |
* mi-main.c (mi_execute_asynch_cli_command): New |
function. Captures code that was repeated for all asynch |
operations. |
(mi_cmd_exec_*): Use the above new function. |
(mi_gdb_cmd_exit): Fix the output, printing something appropriate. |
(mi_cmd_exec_finish): New operation implementation function. |
(mi_cmd_exec_return): Ditto. |
(parse): Prepare to remove cli commands. |
(mi_execute_command): Fix the output and change the way mi-cmds is |
used. |
|
1999-06-18 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c (mi_table_begin): Add missing field separator call. |
|
Thu Jun 17 21:05:40 1999 Fernando Nasser <fnasser@tofu.to.cygnus.com> |
|
* breakpoint.c (breakpoint_1): Remove space in breakpoint table |
id. |
(mention): Use ui_out for last new line (forgotten). |
|
1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c (mi_console_file_flush): Prevent prefix printing when |
buffer empty; change prefix to '~'. |
(mi_cmd_exec_*): Prefix normal output with '^' instead of |
','; remove unwanted new lines before "stopped". |
|
1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-cmds.c (struct mi_cmds): Updated entries for -exec-continue |
and exec-next operations. |
(mi_cmd_execute): New text for error messages. |
* mi-cmds.h: Add declaration for mi_cmd_exec_next and |
mi_cmd_exec_continue. |
* mi-main.c (mi_cmd_exec_next): New function. Implements exec-next |
operation. |
(mi_cmd_exec_continue): New function. Implements exec-continue |
operation. |
(mi_execute_comand): Add missing space to prompt. |
(mi_cmd_exec_run): Ditto. |
(mi_cmd_exec_step): Ditto. |
* mi-out.c (mi_out_new): Add flags argument to ui_out_new call. |
(ui_list_end): Reset supress_field_separator flag. |
|
Sat Jun 12 11:49:10 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h. mi-cmds.c (exec step): Command implemented by |
mi_cmd_exec_step instead of cli call. |
* mi-main.c (mi_cmd_exec_step): New function. |
|
* mi-cmds.h. mi-cmds.c (exec run): Command implemented by |
mi_cmd_exec_run instead of cli call. |
* mi-main.c (mi_cmd_exec_run): New function. |
|
* mi-cmds.h. mi-cmds.c (gdb exit): Command implemented by |
mi_cmd_gdb_exit instead of quit_force. |
* mi-main.c (mi_cmd_gdb_exit): New function. |
|
Sat Jun 12 11:33:23 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_command_loop): Pass mi_input to |
simplified_command_loop. |
(mi_input): New function. Calls gdb_readline with no prompt. |
|
Sat Jun 12 11:19:02 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_console_file_fputs): Re-implement. Use a buffer |
to accumulate output. |
|
* mi-main.c (struct mi_console_file): Add a buffer. |
(mi_console_file_new): Create a buffer. |
(mi_console_file_flush): New function. |
|
Sat Jun 12 10:59:39 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-cmds.h (raw_stdout): Declare. Will be moved later. |
* mi-cmds.c (mi_cmd_execute): Send error messages to RAW stdout. |
(mi_cmds): Sort by class. |
|
* mi-main.c (raw_stdout): Make global. |
* mi-main.c: Remove #ifdef UI_OUT. File assumes UI_OUT is |
present. |
* mi-main.c: Include "gdb_string.h". |
(mi_out_put): Delete declaration. |
|
1999-06-11 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-main.c: Add pre-processor test for UI_OUT. |
(mi_execute_command): Add pre-processor test for UI_OUT. |
|
Fri Jun 11 23:11:41 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (raw_stdout): New variable. |
(mi_execute_command): Write mi-out direct to raw_stdout. |
(mi_command_loop): Create raw_stdout. Attach gdb_stdout to the |
console. |
(mi_console_file_fputs, mi_console_file_delete, |
mi_console_file_new): New functions. |
(struct mi_console_file): Declare. |
|
Fri Jun 11 18:34:33 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c (mi_execute_command): Call mi_out_put to display the |
result. |
* mi-out.c (mi_out_put): New function. |
* ui-out.h (mi_out_put): Add declare. Will move later. |
* Makefile.in (mi-cmds.o, mi-main.o): Add dependency on ui-out.h. |
|
* mi-out.c (mi_field_string, mi_field_fmt, mi_message, mi_flush, |
out_field_fmt, list_open, list_close): Replace gdb_stdout with |
data->buffer. |
(field_separator, list_open, list_close): Add uiout parameter. |
(mi_table_begin, mi_table_body, mi_table_end, mi_list_begin, |
mi_list_end, mi_field_string, mi_field_fmt, out_field_fmt, |
out_field_fmt): Update. |
|
* mi-out.c (mi_out_new): Initialize supress_field_separator. |
(supress_field_separator): Move into mi-out local data object. |
(mi_table_begin, mi_list_begin, field_separator): Update. |
|
Fri Jun 11 16:08:37 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-out.c (mi_out_new): New function, replace init_mi_out. |
* mi-main.c (mi_command_loop): Call mi_out_new(). |
|
* ui-out.h (mi_out_new): Add declaration. Will move later. |
(mi_ui_out_impl): Delete. |
|
Wed Jun 9 16:42:16 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* mi-main.c: Include "ui-hooks.h". |
(mi_init_ui, mi_command_loop): New functions. |
(_initialize_mi_main): Install ``mi'' as the interpreter when |
selected. |
|
Mon Jun 7 18:43:43 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
From Fernando Nasser <fnasser@totem.to.cygnus.com> |
* mi-cmds.c (build_table): Clean up error message. |
* mi-cmds.c (mi_cmd_execute), mi-main.c (mi_execute_command): Only |
print debug information when mi_debug_p. |
* mi-cmds.h (mi_debug_p), mi-main.c: Global, control debug messages. |
|
Thu Jun 3 00:44:52 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
From Fernando Nasser <fnasser@totem.to.cygnus.com>: |
* mi-cmds.c: Add CLI definitions for "exec-arguments", |
"exec-next", "gdb-exit", "break-list", "break-info", "exec-step" |
and "stack-list-frames" to mi_cmds. |
(struct mi_command): Add ``from_tty'' argument to func. |
* mi-cmds.h (quit_force): Declare. |
|
1999-05-31 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c (mi_table_end): Remove unwanted "\n". |
|
Thu May 27 14:59:06 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* top.c: Include "ui-hooks.h". |
(call_interp_loop): Tempoary. Pass mi_execute_command to |
simplified_command_loop. Initialize gdb_stdout & gdb_stderr to |
stdio gdb_file streams. Force all hooks to null. |
|
* mi-cmds.h, mi-main.c, mi-cmds.c: New files. |
* Makefile.in (SFILES): Add mi-main.c, mi-cmds.c |
(COMMON_OBS): Add mi-main.o, mi-cmds.o. |
(mi_cmds_h): Define. |
|
Wed May 26 12:39:49 1999 Andrew Cagney <cagney@b1.cygnus.com> |
|
* top.c (call_interp_loop): Hack. Add extern declaration for |
mi_ui_out_impl. |
|
1999-05-25 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c: New table syntax. |
|
Mon May 24 16:16:29 1999 Andrew Cagney <cagney@amy.cygnus.com> |
|
mi-out.c (_initialize_mi_out): Add external declaration. |
|
1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c (mi_table_begin): Added missing parameter. |
|
1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c: Changed table markers and added table id. |
|
1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com> |
|
* mi-out.c: New file. Implements low-level ui-out primitives for |
CLI-based interaction. |
|
|
Local Variables: |
mode: change-log |
left-margin: 8 |
fill-column: 74 |
version-control: never |
End: |
/mi-out.c
0,0 → 1,401
/* MI Command Set - output generating routines. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "ui-out.h" |
#include "mi-out.h" |
|
/* Convenience macro for allocting typesafe memory. */ |
|
#ifndef XMALLOC |
#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) |
#endif |
|
struct ui_out_data |
{ |
int supress_field_separator; |
int first_header; |
struct ui_file *buffer; |
}; |
|
/* These are the MI output functions */ |
|
static void mi_table_begin (struct ui_out *uiout, int nbrofcols, char *tblid); |
static void mi_table_body (struct ui_out *uiout); |
static void mi_table_end (struct ui_out *uiout); |
static void mi_table_header (struct ui_out *uiout, int width, |
enum ui_align alig, char *colhdr); |
static void mi_list_begin (struct ui_out *uiout, int list_flag, char *lstid); |
static void mi_list_end (struct ui_out *uiout, int list_flag); |
static void mi_field_int (struct ui_out *uiout, int fldno, int width, |
enum ui_align alig, char *fldname, int value); |
static void mi_field_skip (struct ui_out *uiout, int fldno, int width, |
enum ui_align alig, char *fldname); |
static void mi_field_string (struct ui_out *uiout, int fldno, int width, |
enum ui_align alig, char *fldname, |
const char *string); |
static void mi_field_fmt (struct ui_out *uiout, int fldno, |
int width, enum ui_align align, |
char *fldname, char *format, va_list args); |
static void mi_spaces (struct ui_out *uiout, int numspaces); |
static void mi_text (struct ui_out *uiout, char *string); |
static void mi_message (struct ui_out *uiout, int verbosity, char *format, |
va_list args); |
static void mi_wrap_hint (struct ui_out *uiout, char *identstring); |
static void mi_flush (struct ui_out *uiout); |
|
/* This is the MI ui-out implementation functions vector */ |
|
/* FIXME: This can be initialized dynamically after default is set to |
handle initial output in main.c */ |
|
struct ui_out_impl mi_ui_out_impl = |
{ |
mi_table_begin, |
mi_table_body, |
mi_table_end, |
mi_table_header, |
mi_list_begin, |
mi_list_end, |
mi_field_int, |
mi_field_skip, |
mi_field_string, |
mi_field_fmt, |
mi_spaces, |
mi_text, |
mi_message, |
mi_wrap_hint, |
mi_flush |
}; |
|
/* Prototypes for local functions */ |
|
extern void _initialize_mi_out PARAMS ((void)); |
static void field_separator (struct ui_out *uiout); |
static void list_open (struct ui_out *uiout); |
static void list_close (struct ui_out *uiout); |
|
static void out_field_fmt (struct ui_out *uiout, int fldno, char *fldname, |
char *format,...); |
|
/* Mark beginning of a table */ |
|
void |
mi_table_begin (uiout, nbrofcols, tblid) |
struct ui_out *uiout; |
int nbrofcols; |
char *tblid; |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
field_separator (uiout); |
if (tblid) |
fprintf_unfiltered (data->buffer, "%s=", tblid); |
list_open (uiout); |
data->first_header = 0; |
data->supress_field_separator = 1; |
} |
|
/* Mark beginning of a table body */ |
|
void |
mi_table_body (uiout) |
struct ui_out *uiout; |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
/* close the table header line if there were any headers */ |
if (data->first_header) |
list_close (uiout); |
} |
|
/* Mark end of a table */ |
|
void |
mi_table_end (uiout) |
struct ui_out *uiout; |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
list_close (uiout); |
/* If table was empty this flag did not get reset yet */ |
data->supress_field_separator = 0; |
} |
|
/* Specify table header */ |
|
void |
mi_table_header (uiout, width, alignment, colhdr) |
struct ui_out *uiout; |
int width; |
int alignment; |
char *colhdr; |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
if (!data->first_header++) |
{ |
fputs_unfiltered ("hdr=", data->buffer); |
list_open (uiout); |
} |
mi_field_string (uiout, 0, width, alignment, 0, colhdr); |
} |
|
/* Mark beginning of a list */ |
|
void |
mi_list_begin (uiout, list_flag, lstid) |
struct ui_out *uiout; |
int list_flag; |
char *lstid; |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
field_separator (uiout); |
data->supress_field_separator = 1; |
if (lstid) |
fprintf_unfiltered (data->buffer, "%s=", lstid); |
list_open (uiout); |
} |
|
/* Mark end of a list */ |
|
void |
mi_list_end (uiout, list_flag) |
struct ui_out *uiout; |
int list_flag; |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
list_close (uiout); |
/* If list was empty this flag did not get reset yet */ |
data->supress_field_separator = 0; |
} |
|
/* output an int field */ |
|
void |
mi_field_int (uiout, fldno, width, alignment, fldname, value) |
struct ui_out *uiout; |
int fldno; |
int width; |
int alignment; |
char *fldname; |
int value; |
{ |
char buffer[20]; /* FIXME: how many chars long a %d can become? */ |
|
sprintf (buffer, "%d", value); |
mi_field_string (uiout, fldno, width, alignment, fldname, buffer); |
} |
|
/* used to ommit a field */ |
|
void |
mi_field_skip (uiout, fldno, width, alignment, fldname) |
struct ui_out *uiout; |
int fldno; |
int width; |
int alignment; |
char *fldname; |
{ |
mi_field_string (uiout, fldno, width, alignment, fldname, ""); |
} |
|
/* other specific mi_field_* end up here so alignment and field |
separators are both handled by mi_field_string */ |
|
void |
mi_field_string (struct ui_out *uiout, |
int fldno, |
int width, |
int align, |
char *fldname, |
const char *string) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
field_separator (uiout); |
if (fldname) |
fprintf_unfiltered (data->buffer, "%s=", fldname); |
fprintf_unfiltered (data->buffer, "\""); |
if (string) |
fputstr_unfiltered (string, '"', data->buffer); |
fprintf_unfiltered (data->buffer, "\""); |
} |
|
/* This is the only field function that does not align */ |
|
void |
mi_field_fmt (struct ui_out *uiout, int fldno, |
int width, enum ui_align align, |
char *fldname, char *format, va_list args) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
field_separator (uiout); |
if (fldname) |
fprintf_unfiltered (data->buffer, "%s=\"", fldname); |
else |
fputs_unfiltered ("\"", data->buffer); |
vfprintf_unfiltered (data->buffer, format, args); |
fputs_unfiltered ("\"", data->buffer); |
} |
|
void |
mi_spaces (uiout, numspaces) |
struct ui_out *uiout; |
int numspaces; |
{ |
} |
|
void |
mi_text (uiout, string) |
struct ui_out *uiout; |
char *string; |
{ |
} |
|
void |
mi_message (struct ui_out *uiout, int verbosity, char *format, va_list args) |
{ |
} |
|
void |
mi_wrap_hint (uiout, identstring) |
struct ui_out *uiout; |
char *identstring; |
{ |
wrap_here (identstring); |
} |
|
void |
mi_flush (uiout) |
struct ui_out *uiout; |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
gdb_flush (data->buffer); |
} |
|
/* local functions */ |
|
/* Like mi_field_fmt, but takes a variable number of args |
and makes a va_list and does not insert a separator */ |
|
/* VARARGS */ |
static void |
out_field_fmt (struct ui_out *uiout, int fldno, char *fldname, |
char *format,...) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
va_list args; |
|
field_separator (uiout); |
if (fldname) |
fprintf_unfiltered (data->buffer, "%s=\"", fldname); |
else |
fputs_unfiltered ("\"", data->buffer); |
|
va_start (args, format); |
vfprintf_unfiltered (data->buffer, format, args); |
|
fputs_unfiltered ("\"", data->buffer); |
|
va_end (args); |
} |
|
/* access to ui_out format private members */ |
|
static void |
field_separator (struct ui_out *uiout) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
if (data->supress_field_separator) |
data->supress_field_separator = 0; |
else |
fputc_unfiltered (',', data->buffer); |
} |
|
static void |
list_open (struct ui_out *uiout) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
fputc_unfiltered ('{', data->buffer); |
} |
|
static void |
list_close (struct ui_out *uiout) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
fputc_unfiltered ('}', data->buffer); |
} |
|
/* add a string to the buffer */ |
|
void |
mi_out_buffered (struct ui_out *uiout, char *string) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
fprintf_unfiltered (data->buffer, "%s", string); |
} |
|
/* clear the buffer */ |
|
void |
mi_out_rewind (struct ui_out *uiout) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
ui_file_rewind (data->buffer); |
} |
|
/* dump the buffer onto the specified stream */ |
|
static void |
do_write (void *data, const char *buffer, long length_buffer) |
{ |
ui_file_write (data, buffer, length_buffer); |
} |
|
void |
mi_out_put (struct ui_out *uiout, |
struct ui_file *stream) |
{ |
struct ui_out_data *data = ui_out_data (uiout); |
ui_file_put (data->buffer, do_write, stream); |
ui_file_rewind (data->buffer); |
} |
|
/* initalize private members at startup */ |
|
struct ui_out * |
mi_out_new (void) |
{ |
int flags = 0; |
struct ui_out_data *data = XMALLOC (struct ui_out_data); |
data->supress_field_separator = 0; |
/* FIXME: This code should be using a ``string_file'' and not the |
TUI buffer hack. */ |
data->buffer = mem_fileopen (); |
return ui_out_new (&mi_ui_out_impl, data, flags); |
} |
|
/* standard gdb initialization hook */ |
void |
_initialize_mi_out () |
{ |
/* nothing happens here */ |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-getopt.h
0,0 → 1,64
/* MI Option Parser. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#ifndef MI_GETOPT_H |
#define MI_GETOPT_H |
|
/* Like getopt() but with simpler semantics. |
|
An option has the form ``-<name>''. The special option ``--'' |
denotes the end of the option list. An option can be followed by a |
separate argument (on a per option basis). |
|
On entry OPTIND contains the index of the next element of ARGV that |
needs parsing. OPTIND is updated to indicate the index of the next |
argument before mi_getopt() returns. |
|
If ARGV[OPTIND] is an option, that options INDEX is returned. |
OPTARG is set to the options argument or NULL. OPTIND is updated. |
|
If ARGV[OPTIND] is not an option, -1 is returned and OPTIND updated |
to specify the non-option argument. OPTARG is set to NULL. |
|
mi_getopt() calls ``error("%s: Unknown option %c", prefix, |
option)'' if an unknown option is encountered. */ |
|
struct mi_opt; |
extern int mi_getopt (const char *prefix, int argc, char **argv, |
struct mi_opt *opt, int *optind, char **optarg); |
|
/* The option list. Terminated by NAME==NULL. ARG_P that the option |
requires an argument. INDEX is returned to identify th option. */ |
|
struct mi_opt |
{ |
const char *name; |
int index; |
int arg_p; |
}; |
|
struct mi_opt; |
|
#endif |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-console.h
0,0 → 1,31
/* MI Command Set - MI Console. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#ifndef MI_CONSOLE_H |
#define MI_CONSOLE_H |
|
extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix); |
|
#endif |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/gdbmi.texinfo
0,0 → 1,3900
@c \input texinfo @c -*-texinfo-*- |
@c @c %**start of header |
@c @setfilename gdbmi.info |
@c @settitle GDB/MI Machine Interface |
@c @setchapternewpage off |
@c @c %**end of header |
|
@c @ifinfo |
@c This file documents GDB/MI, a Machine Interface to GDB. |
|
@c Copyright (C) 2000, Free Software Foundation, Inc. |
@c Contributed by Cygnus Solutions. |
|
@c Permission is granted to make and distribute verbatim copies of this |
@c manual provided the copyright notice and this permission notice are |
@c preserved on all copies. |
|
@c @ignore |
@c Permission is granted to process this file through TeX and print the |
@c results, provided the printed document carries copying permission notice |
@c identical to this one except for the removal of this paragraph (this |
@c paragraph not being relevant to the printed manual). |
|
@c @end ignore |
@c Permission is granted to copy and distribute modified versions of this |
@c manual under the conditions for verbatim copying, provided also that the |
@c entire resulting derived work is distributed under the terms of a |
@c permission notice identical to this one. |
|
@c Permission is granted to copy and distribute translations of this manual |
@c into another language, under the above conditions for modified versions. |
@c @end ifinfo |
|
@c @c This title page illustrates only one of the |
@c @c two methods of forming a title page. |
|
@c @titlepage |
@c @title GDB/MI |
@c @subtitle Version 0.2 |
@c @subtitle Feb 2000 |
@c @author Andrew Cagney, Fernando Nasser and Elena Zannoni |
|
@c @c The following two commands |
@c @c start the copyright page. |
@c @page |
@c @vskip 0pt plus 1filll |
@c Permission is granted to make and distribute verbatim copies of this |
@c manual provided the copyright notice and this permission notice are |
@c preserved on all copies. |
|
@c Copyright @copyright{} 2000, Free Software Foundation, Inc. |
@c @end titlepage |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI |
@chapter The @sc{gdb/mi} Interface |
|
@unnumberedsec Function and Purpose |
|
@cindex @sc{gdb/mi}, its purpose |
@sc{gdb/mi} is a line based machine oriented text interface to GDB. It is |
specifically intended to support the development of systems which use |
the debugger as just one small component of a larger system. |
|
This chapter is a specification of the @sc{gdb/mi} interface. It is written |
in the form of a reference manual. |
|
Note that @sc{gdb/mi} is still under construction, so some of the |
features described below are incomplete and subject to change. |
|
@unnumberedsec Notation and Terminology |
|
@cindex notational conventions, for @sc{gdb/mi} |
This chapter uses the following notation: |
|
@itemize @bullet |
@item |
@code{|} separates two alternatives. |
|
@item |
@code{[ @var{something} ]} indicates that @var{something} is optional: |
it may or may not be given. |
|
@item |
@code{( @var{group} )*} means that @var{group} inside the parentheses |
may repeat zero or more times. |
|
@item |
@code{( @var{group} )+} means that @var{group} inside the parentheses |
may repeat one or more times. |
|
@item |
@code{"@var{string}"} means a literal @var{string}. |
@end itemize |
|
@ignore |
@heading Dependencies |
@end ignore |
|
@heading Acknowledgments |
|
In alphabetic order: Andrew Cagney, Fernando Nasser, Stan Shebs and |
Elena Zannoni. |
|
@menu |
* GDB/MI Command Syntax:: |
* GDB/MI Compatibility with CLI:: |
* GDB/MI Output Records:: |
* GDB/MI Command Description Format:: |
* GDB/MI Breakpoint Table Commands:: |
* GDB/MI Data Manipulation:: |
* GDB/MI Program Control:: |
* GDB/MI Miscellaneous Commands:: |
* GDB/MI Stack Manipulation:: |
* GDB/MI Symbol Query:: |
* GDB/MI Target Manipulation:: |
* GDB/MI Thread Commands:: |
* GDB/MI Tracepoint Commands:: |
* GDB/MI Variable Objects:: |
* GDB/MI Draft Changes to Output Syntax:: |
@end menu |
|
@c When these are implemented, they should be moved to be between Misc and |
@c Stack Manipulation in the above menu. They are now outside the menu |
@c because makeinfo 3.12 barfs if it sees @ignore or @comments in the |
@c middle of a menu. |
@ignore |
* GDB/MI Kod Commands:: |
* GDB/MI Memory Overlay Commands:: |
* GDB/MI Signal Handling Commands:: |
@end ignore |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Command Syntax |
@section @sc{gdb/mi} Command Syntax |
|
@menu |
* GDB/MI Input Syntax:: |
* GDB/MI Output Syntax:: |
* GDB/MI Simple Examples:: |
@end menu |
|
@node GDB/MI Input Syntax |
@subsection @sc{gdb/mi} Input Syntax |
|
@cindex input syntax for @sc{gdb/mi} |
@cindex @sc{gdb/mi}, input syntax |
@table @code |
@item @var{command} @expansion{} |
@code{@var{cli-command} | @var{mi-command}} |
|
@item @var{cli-command} @expansion{} |
@code{[ @var{token} ] @var{cli-command} @var{nl}}, where |
@var{cli-command} is any existing GDB CLI command. |
|
@item @var{mi-command} @expansion{} |
@code{[ @var{token} ] "-" @var{operation} ( " " @var{option} )* |
@code{[} " --" @code{]} ( " " @var{parameter} )* @var{nl}} |
|
@item @var{token} @expansion{} |
@code{"any sequence of digits"} |
|
@item @var{option} @expansion{} |
@code{"-" @var{parameter} [ " " @var{parameter} ]} |
|
@item @var{parameter} @expansion{} |
@code{@var{non-blank-sequence} | @var{c-string}} |
|
@item @var{operation} @expansion{} |
@emph{any of the operations described in this document} |
|
@item @var{non-blank-sequence} @expansion{} |
@emph{anything, provided it doesn't contain special characters such as |
"-", @var{nl}, """ and of course " "} |
|
@item @var{c-string} @expansion{} |
@code{""" @var{seven-bit-iso-c-string-content} """} |
|
@item @var{nl} @expansion{} |
@code{CR | CR-LF} |
@end table |
|
Notes: |
|
@itemize @bullet |
@item |
The CLI commands are still handled by the @sc{mi} interpreter; their |
output is described below. |
|
@item |
The @code{@var{token}}, when present, is passed back when the command |
finishes. |
|
@item |
Some @sc{mi} commands accept optional arguments as part of the parameter |
list. Each option is identified by a leading @samp{-} (dash) and may be |
followed by an optional argument parameter. Options occur first in the |
parameter list and can be delimited from normal parameters using |
@samp{--} (this is useful when some parameters begin with a dash). |
@end itemize |
|
Pragmatics: |
|
@itemize @bullet |
@item |
We want easy access to the existing CLI syntax (for debugging). |
|
@item |
We want it to be easy to spot a @sc{mi} operation. |
@end itemize |
|
@node GDB/MI Output Syntax |
@subsection @sc{gdb/mi} Output Syntax |
|
@cindex output syntax of @sc{gdb/mi} |
@cindex @sc{gdb/mi}, output syntax |
The output from @sc{gdb/mi} consists of zero or more out-of-band records |
followed, optionally, by a single result record. This result record |
is for the most recent command. The sequence of output records is |
terminated by @samp{(gdb)}. |
|
If an input command was prefixed with a @code{@var{token}} then the |
corresponding output for that command will also be prefixed by that same |
@var{token}. |
|
@table @code |
@item @var{output} @expansion{} |
@code{( @var{out-of-band-record} )* [ @var{result-record} ] "(gdb)" @var{nl}} |
|
@item @var{result-record} @expansion{} |
@code{ [ @var{token} ] "^" @var{result-class} ( "," @var{result} )* @var{nl}} |
|
@item @var{out-of-band-record} @expansion{} |
@code{@var{async-record} | @var{stream-record}} |
|
@item @var{async-record} @expansion{} |
@code{@var{exec-async-output} | @var{status-async-output} | @var{notify-async-output}} |
|
@item @var{exec-async-output} @expansion{} |
@code{[ @var{token} ] "*" @var{async-output}} |
|
@item @var{status-async-output} @expansion{} |
@code{[ @var{token} ] "+" @var{async-output}} |
|
@item @var{notify-async-output} @expansion{} |
@code{[ @var{token} ] "=" @var{async-output}} |
|
@item @var{async-output} @expansion{} |
@code{@var{async-class} ( "," @var{result} )* @var{nl}} |
|
@item @var{result-class} @expansion{} |
@code{"done" | "running" | "connected" | "error" | "exit"} |
|
@item @var{async-class} @expansion{} |
@code{"stopped" | @var{others}} (where @var{others} will be added |
depending on the needs---this is still in development). |
|
@item @var{result} @expansion{} |
@code{[ @var{string} "=" ] @var{value}} |
|
@item @var{value} @expansion{} |
@code{@var{const} | "@{" @var{result} ( "," @var{result} )* "@}"} |
|
@item @var{const} @expansion{} |
@code{@var{c-string}} |
|
@item @var{stream-record} @expansion{} |
@code{@var{console-stream-output} | @var{target-stream-output} | @var{log-stream-output}} |
|
@item @var{console-stream-output} @expansion{} |
@code{"~" @var{c-string}} |
|
@item @var{target-stream-output} @expansion{} |
@code{"@@" @var{c-string}} |
|
@item @var{log-stream-output} @expansion{} |
@code{"&" @var{c-string}} |
|
@item @var{nl} @expansion{} |
@code{CR | CR-LF} |
|
@item @var{token} @expansion{} |
@emph{any sequence of digits}. |
@end table |
|
In addition, the following are still being developed: |
|
@table @code |
@item @var{query} |
This action is currently undefined. |
@end table |
|
Notes: |
|
@itemize @bullet |
@item |
All output sequences end in a single line containing a period. |
|
@item |
The @code{@var{token}} is from the corresponding request. If an execution |
command is interrupted by the @samp{-exec-interrupt} command, the |
@var{token} associated with the `*stopped' message is the one of the |
original execution command, not the one of the interrupt-command. |
|
@item |
@cindex status output in @sc{gdb/mi} |
@var{status-async-output} contains on-going status information about the |
progress of a slow operation. It can be discarded. All status output is |
prefixed by @samp{+}. |
|
@item |
@cindex async output in @sc{gdb/mi} |
@var{exec-async-output} contains asynchronous state change on the target |
(stopped, started, disappeared). All async output is prefixed by |
@samp{*}. |
|
@item |
@cindex notify output in @sc{gdb/mi} |
@var{notify-async-output} contains supplementary information that the |
client should handle (e.g., a new breakpoint information). All notify |
output is prefixed by @samp{=}. |
|
@item |
@cindex console output in @sc{gdb/mi} |
@var{console-stream-output} is output that should be displayed as is in the |
console. It is the textual response to a CLI command. All the console |
output is prefixed by @samp{~}. |
|
@item |
@cindex target output in @sc{gdb/mi} |
@var{target-stream-output} is the output produced by the target program. |
All the target output is prefixed by @samp{@@}. |
|
@item |
@cindex log output in @sc{gdb/mi} |
@var{log-stream-output} is output text coming from GDB's internals, for |
instance messages that should be displayed as part of an error log. All |
the log output is prefixed by @samp{&}. |
@end itemize |
|
@xref{GDB/MI Stream Records, , @sc{gdb/mi} Stream Records}, for more |
details about the various output records. |
|
@xref{GDB/MI Draft Changes to Output Syntax, , @sc{gdb/mi} Draft Changes |
to Output Syntax}, for proposed revisions to the current output syntax. |
|
@node GDB/MI Simple Examples |
@subsection Simple Examples of @sc{gdb/mi} Interaction |
@cindex @sc{gdb/mi}, simple examples |
|
This subsection presents several simple examples of interaction using |
the @sc{gdb/mi} interface. In these examples, @samp{->} means that the |
following line is passed to @sc{gdb/mi} as input, while @samp{<-} means |
the output received from @sc{gdb/mi}. |
|
@subsubheading Target Stop |
|
Here's an example of stopping the inferior process: |
|
@example |
-> -stop |
<- (gdb) |
@end example |
|
@noindent |
and later: |
|
@example |
<- *stop,reason="stop",address="0x123",source="a.c:123" |
<- (gdb) |
@end example |
|
@subsubheading Simple CLI Command |
|
Here's an example of a simple CLI command being passed through |
@sc{gdb/mi} and on to the CLI. |
|
@example |
-> print 1+2 |
<- ~3\n |
<- (gdb) |
@end example |
|
@subsubheading Command With Side Effects |
|
@example |
-> -symbol-file xyz.exe |
<- *breakpoint,nr="3",address="0x123",source="a.c:123" |
<- (gdb) |
@end example |
|
@subsubheading A Bad Command |
|
Here's what happens if you pass a non-existent command: |
|
@example |
-> -rubbish |
<- error,"Rubbish not found" |
<- (gdb) |
@end example |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Compatibility with CLI |
@section @sc{gdb/mi} Compatibility with CLI |
|
@cindex compatibility, @sc{gdb/mi} and CLI |
@cindex @sc{gdb/mi}, compatibility with CLI |
To help users familiar with GDB's existing CLI interface, @sc{gdb/mi} |
accepts existing CLI commands. As specified by the syntax, such |
commands can be directly entered into the @sc{gdb/mi} interface and GDB will |
respond. |
|
This mechanism is provided as an aid to developers of @sc{gdb/mi} |
clients and not as a reliable interface into the CLI. Since the command |
is being interpreteted in an environment that assumes @sc{gdb/mi} |
behaviour, the exact output of such commands is likely to end up being |
an un-supported hybrid of @sc{gdb/mi} and CLI output. |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Output Records |
@section @sc{gdb/mi} Output Records |
|
@menu |
* GDB/MI Result Records:: |
* GDB/MI Stream Records:: |
* GDB/MI Out-of-band Records:: |
@end menu |
|
@node GDB/MI Result Records |
@subsection @sc{gdb/mi} Result Records |
|
@cindex result records in @sc{gdb/mi} |
@cindex @sc{gdb/mi}, result records |
In addition to a number of out-of-band notifications, the response to a |
@sc{gdb/mi} command includes one of the following result indications: |
|
@table @code |
@findex ^done |
@item "^done" [ "," @var{results} ] |
The synchronous operation was successful, @code{@var{results}} is the return |
value. |
|
@item "^running" |
@findex ^running |
@c Is this one correct? Should it be an out-of-band notification? |
The asynchronous operation was successfully started. The target is |
running. |
|
@item "^error" "," @var{c-string} |
@cindex ^error |
The operation failed. The @code{@var{c-string}} contains the corresponding |
error message. |
@end table |
|
@node GDB/MI Stream Records |
@subsection @sc{gdb/mi} Stream Records |
|
@cindex @sc{gdb/mi}, stream records |
@cindex stream records in @sc{gdb/mi} |
GDB internally maintains a number of output streams: the console, the |
target, and the log. The output intended for each of these streams is |
funneled through the @sc{gdb/mi} interface using @dfn{stream records}. |
|
Each stream record begins with a unique @dfn{prefix character} which |
identifies its stream (@pxref{GDB/MI Output Syntax, , @sc{gdb/mi} Output |
Syntax}). In addition to the prefix, each stream record contains a |
@code{@var{string-output}}. This is either raw text (with an implicit new |
line) or a quoted C string (which does not contain an implicit newline). |
|
@table @code |
@item "~" @var{string-output} |
The console output stream contains text that should be displayed in the |
CLI console window. It contains the textual responses to CLI commands. |
|
@item "@@" @var{string-output} |
The target output stream contains any textual output from the running |
target. |
|
@item "&" @var{string-output} |
The LOG stream contains debugging messages being produced by GDB's |
internals. |
@end table |
|
@node GDB/MI Out-of-band Records |
@subsection @sc{gdb/mi} Out-of-band Records |
|
@cindex out-of-band records in @sc{gdb/mi} |
@cindex @sc{gdb/mi}, out-of-band records |
@dfn{Out-of-band} records are used to notify the @sc{gdb/mi} client of |
additional changes that have occurred. Those changes can either be a |
consequence of @sc{gdb/mi} (e.g., a breakpoint modified) or a result of |
target activity (e.g., target stopped). |
|
The following is a preliminary list of possible out-of-band records. |
|
@table @code |
@item "*" "stop" |
@end table |
|
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Command Description Format |
@section @sc{gdb/mi} Command Description Format |
|
The remaining sections describe blocks of commands. Each block of |
commands is laid out in a fashion similar to this chapter. |
|
Note the the line breaks shown in the examples are here only for |
readability. They don't appear in the real output. |
Also note that the commands with a non-available example (N.A.@:) are |
not yet implemented. |
|
@subheading Motivation |
|
The motivation for this collection of commands |
|
@subheading Introduction |
|
A brief introduction to this collection of commands as a whole. |
|
@subheading Commands |
|
For each command in the block, the following is described: |
|
@subsubheading Synopsis |
|
@example |
-command @var{args}... |
@end example |
|
@subsubheading GDB Command |
|
The corresponding GDB CLI command. |
|
@subsubheading Result |
|
@subsubheading Out-of-band |
|
@subsubheading Notes |
|
@subsubheading Example |
|
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Breakpoint Table Commands |
@section @sc{gdb/mi} Breakpoint table commands |
|
@cindex breakpoint commands for @sc{gdb/mi} |
@cindex @sc{gdb/mi}, breakpoint commands |
This section documents @sc{gdb/mi} commands for manipulating |
breakpoints. |
|
@subheading The @code{-break-after} Command |
@findex -break-after |
|
@subsubheading Synopsis |
|
@example |
-break-after @var{number} @var{count} |
@end example |
|
The breakpoint number @var{number} is not in effect until it has been |
hit @var{count} times. To see how this is reflected in the output of |
the @samp{-break-list} command, see the description of the |
@samp{-break-list} command below. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{ignore}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-break-insert main |
^done,bkpt=@{number="1",addr="0x000100d0",file="hello.c",line="5"@} |
(gdb) |
-break-after 1 3 |
~ |
^done |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", |
addr="0x000100d0",func="main",file="hello.c",line="5",times="0", |
ignore="3"@}@} |
(gdb) |
@end smallexample |
|
@ignore |
@subheading The @code{-break-catch} Command |
@findex -break-catch |
|
@subheading The @code{-break-commands} Command |
@findex -break-commands |
@end ignore |
|
|
@subheading -break-condition |
@findex -break-condition |
|
@subsubheading Synopsis |
|
@example |
-break-condition @var{number} @var{expr} |
@end example |
|
Breakpoint @var{number} will stop the program only if the condition in |
@var{expr} is true. The condition becomes part of the |
@samp{-break-list} output (see the description of the @samp{-break-list} |
command below). |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{condition}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-break-condition 1 1 |
^done |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", |
addr="0x000100d0",func="main",file="hello.c",line="5",cond="1", |
times="0",ignore="3"@}@} |
(gdb) |
@end smallexample |
|
@subheading The @code{-break-delete} Command |
@findex -break-delete |
|
@subsubheading Synopsis |
|
@example |
-break-delete ( @var{breakpoint} )+ |
@end example |
|
Delete the breakpoint(s) whose number(s) are specified in the argument |
list. This is obviously reflected in the breakpoint list. |
|
@subsubheading GDB command |
|
The corresponding GDB command is @samp{delete}. |
|
@subsubheading Example |
|
@example |
(gdb) |
-break-delete 1 |
^done |
(gdb) |
-break-list |
^done,BreakpointTable=@{@} |
(gdb) |
@end example |
|
@subheading The @code{-break-disable} Command |
@findex -break-disable |
|
@subsubheading Synopsis |
|
@example |
-break-disable ( @var{breakpoint} )+ |
@end example |
|
Disable the named @var{breakpoint}(s). The field @samp{enabled} in the |
break list is now set to @samp{n} for the named @var{breakpoint}(s). |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{disable}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-break-disable 2 |
^done |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="2",type="breakpoint",disp="keep",enabled="n", |
addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}@} |
(gdb) |
@end smallexample |
|
@subheading The @code{-break-enable} Command |
@findex -break-enable |
|
@subsubheading Synopsis |
|
@example |
-break-enable ( @var{breakpoint} )+ |
@end example |
|
Enable (previously disabled) @var{breakpoint}(s). |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{enable}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-break-enable 2 |
^done |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y", |
addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}@} |
(gdb) |
@end smallexample |
|
@subheading The @code{-break-info} Command |
@findex -break-info |
|
@subsubheading Synopsis |
|
@example |
-break-info @var{breakpoint} |
@end example |
|
@c REDUNDANT??? |
Get information about a single breakpoint. |
|
@subsubheading GDB command |
|
The corresponding GDB command is @samp{info break @var{breakpoint}}. |
|
@subsubheading Example |
N.A. |
|
@subheading The @code{-break-insert} Command |
@findex -break-insert |
|
@subsubheading Synopsis |
|
@example |
-break-insert [ -t ] [ -h ] [ -r ] |
[ -c @var{condition} ] [ -i @var{ignore-count} ] |
[ -p @var{thread} ] [ @var{line} | @var{addr} ] |
@end example |
|
@noindent |
If specified, @var{line}, can be one of: |
|
@itemize @bullet |
@item function |
@c @item +offset |
@c @item -offset |
@c @item linenum |
@item filename:linenum |
@item filename:function |
@item *address |
@end itemize |
|
The possible optional parameters of this command are: |
|
@table @samp |
@item -t |
Insert a tempoary breakpoint. |
@item -h |
Insert a hardware breakpoint. |
@item -c @var{condition} |
Make the breakpoint conditional on @var{condition}. |
@item -i @var{ignore-count} |
Initialize the @var{ignore-count}. |
@item -r |
Insert a regular breakpoint in all the functions whose names match the |
given regular expression. Other flags are not applicable to regular |
expresson. |
@end table |
|
@subsubheading Result |
|
The result is in the form: |
|
@example |
^done,bkptno="@var{number}",func="@var{funcname}", |
file="@var{filename}",line="@var{lineno}" |
@end example |
|
@noindent |
where @var{number} is the GDB number for this breakpoint, @var{funcname} |
is the name of the function where the breakpoint was inserted, |
@var{filename} is the name of the source file which contains this |
function, and @var{lineno} is the source line number within that file. |
|
Note: this format is open to change. |
@c An out-of-band breakpoint instead of part of the result? |
|
@subsubheading GDB Command |
|
The corresponding GDB commands are @samp{break}, @samp{tbreak}, |
@samp{hbreak}, @samp{thbreak}, and @samp{rbreak}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-break-insert main |
^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@} |
(gdb) |
-break-insert -t foo |
^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c",line="11"@} |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", |
addr="0x0001072c", func="main",file="recursive2.c",line="4",times="0"@}, |
bkpt=@{number="2",type="breakpoint",disp="del",enabled="y", |
addr="0x00010774",func="foo",file="recursive2.c",line="11",times="0"@}@} |
(gdb) |
-break-insert -r foo.* |
~int foo(int, int); |
^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c",line="11"@} |
(gdb) |
@end smallexample |
|
@subheading The @code{-break-list} Command |
@findex -break-list |
|
@subsubheading Synopsis |
|
@example |
-break-list |
@end example |
|
Displays the list of inserted breakpoints, showing the following fields: |
|
@table @samp |
@item Number |
number of the breakpoint |
@item Type |
type of the breakpoint: @samp{breakpoint} or @samp{watchpoint} |
@item Disposition |
should the breakpoint be deleted or disabled when it is hit: @samp{keep} |
or @samp{nokeep} |
@item Enabled |
is the breakpoint enabled or no: @samp{y} or @samp{n} |
@item Address |
memory location at which the breakpoint is set |
@item What |
logical location of the breakpoint, expressed by function name, file |
name, line number |
@item times |
number of times the breakpoint has been hit |
@end table |
|
If there are no breakpoints or watchpoints, the BreakpointTable field is |
an empty list. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{info break}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", |
addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}, |
bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y", |
addr="0x00010114",func="foo",file="hello.c",line="13",times="0"@}@} |
(gdb) |
@end smallexample |
|
Here's an example of the result when there are no breakpoints: |
|
@smallexample |
(gdb) |
-break-list |
^done,BreakpointTable=@{@} |
(gdb) |
@end smallexample |
|
@subheading The @code{-break-watch} Command |
@findex -break-watch |
|
@subsubheading Synopsis |
|
@example |
-break-watch [ -a | -r ] |
@end example |
|
Create a watchpoint. With the @samp{-a} option it will create an |
@dfn{access} watchpoint, i.e. a watchpoint that triggers either on a |
read from or on a write to the memory location. With the @samp{-r} |
option, the watchpoint created is a @dfn{read} watchpoint, i.e. it will |
trigger only when the memory location is accessed for reading. Without |
either of the options, the watchpoint created is a regular watchpoint, |
i.e. it will trigger when the memory location is accessed for writing. |
@xref{Set Watchpoints, , Setting watchpoints}. |
|
Note that @samp{-break-list} will report a single list of watchpoints and |
breakpoints inserted. |
|
@subsubheading GDB Command |
|
The corresponding GDB commands are @samp{watch}, @samp{awatch}, and |
@samp{rwatch}. |
|
@subsubheading Example |
|
Setting a watchpoint on a variable in the @code{main} function: |
|
@smallexample |
(gdb) |
-break-watch x |
^done,wpt=@{number="2",exp="x"@} |
(gdb) |
-exec-continue |
^running |
^done,reason="watchpoint-trigger",wpt=@{number="2",exp="x"@}, |
value=@{old="-268439212",new="55"@}, |
frame=@{func="main",args=@{@},file="recursive2.c",line="5"@} |
(gdb) |
@end smallexample |
|
Setting a watchpoint on a variable local to a function. GDB will stop |
the program execution twice: first for the variable changing value, then |
for the watchpoint going out of scope. |
|
@smallexample |
(gdb) |
-break-watch C |
^done,wpt=@{number="5",exp="C"@} |
(gdb) |
-exec-continue |
^running |
^done,reason="watchpoint-trigger", |
wpt=@{number="5",exp="C"@},value=@{old="-276895068",new="3"@}, |
frame=@{func="callee4",args=@{@}, |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@} |
(gdb) |
-exec-continue |
^running |
^done,reason="watchpoint-scope",wpnum="5", |
frame=@{func="callee3",args=@{@{name="strarg", |
value="0x11940 \"A string argument.\""@}@}, |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@} |
(gdb) |
@end smallexample |
|
Listing breakpoints and watchpoints, at different points in the program |
execution. Note that once the watchpoint goes out of scope, it is |
deleted. |
|
@smallexample |
(gdb) |
-break-watch C |
^done,wpt=@{number="2",exp="C"@} |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", |
addr="0x00010734",func="callee4", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}, |
bkpt=@{number="2",type="watchpoint",disp="keep", |
enabled="y",addr="",what="C",times="0"@}@} |
(gdb) |
-exec-continue |
^running |
^done,reason="watchpoint-trigger",wpt=@{number="2",exp="C"@}, |
value=@{old="-276895068",new="3"@}, |
frame=@{func="callee4",args=@{@}, |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@} |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", |
addr="0x00010734",func="callee4", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}, |
bkpt=@{number="2",type="watchpoint",disp="keep", |
enabled="y",addr="",what="C",times="-5"@}@} |
(gdb) |
-exec-continue |
^running |
^done,reason="watchpoint-scope",wpnum="2", |
frame=@{func="callee3",args=@{@{name="strarg", |
value="0x11940 \"A string argument.\""@}@}, |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@} |
(gdb) |
-break-list |
^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@}, |
bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", |
addr="0x00010734",func="callee4", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}@} |
(gdb) |
@end smallexample |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Data Manipulation |
@section @sc{gdb/mi} Data Manipulation |
|
@cindex data manipulation, in @sc{gdb/mi} |
@cindex @sc{gdb/mi}, data manipulation |
This section describes the @sc{gdb/mi} commands that manipulate data: |
examine memory and registers, evaluate expressions, etc. |
|
@c REMOVED FROM THE INTERFACE. |
@c @subheading -data-assign |
@c Change the value of a program variable. Plenty of side effects. |
@c @subsubheading GDB command |
@c set variable |
@c @subsubheading Example |
@c N.A. |
|
@subheading The @code{-data-disassemble} Command |
@findex -data-disassemble |
|
@subsubheading Synopsis |
|
@example |
-data-disassemble |
[ -s @var{start-addr} -e @var{end-addr} ] |
| [ -f @var{filename} -l @var{linenum} [ -n @var{lines} ] ] |
-- @var{mode} |
@end example |
|
@noindent |
Where: |
|
@table @samp |
@item @var{start-addr} |
is the beginning address (or @code{$pc}) |
@item @var{end-addr} |
is the end address |
@item @var{filename} |
is the name of the file to disassemble |
@item @var{linenum} |
is the line number to disassemble around |
@item @var{lines} |
is the the number of disassembly lines to be produced. If it is -1, |
the whole function will be disassembled, in case no @var{end-addr} is |
specified. If @var{end-addr} is specified as a non-zero value, and |
@var{lines} is lower than the number of disassembly lines between |
@var{start-addr} and @var{end-addr}, only @var{lines} lines are |
displayed; if @var{lines} is higher than the number of lines between |
@var{start-addr} and @var{end-addr}, only the lines up to @var{end-addr} |
are displayed. |
@item @var{mode} |
is either 0 (meaning only disassembly) or 1 (meaning mixed source and |
disassembly) |
@end table |
|
@subsubheading Result |
|
The output for each instruction is composed of two fields: |
|
@itemize @bullet |
@item Address |
@item Func-name |
@item Offset |
@item Instruction |
@end itemize |
|
Note that whatever included in the instruction field, is not manipulated |
directely by flathead, i.e. it is not possible to adjust its format. |
|
@subsubheading GDB Command |
|
There's no direct mapping from this command to the CLI. |
|
@subsubheading Example |
|
Disassemble from the current value of @code{$pc} to @code{$pc + 20}: |
|
@smallexample |
(gdb) |
-data-disassemble -s $pc -e "$pc + 20" -- 0 |
^done, |
asm_insns=@{ |
@{address="0x000107c0",func-name="main",offset="4", |
inst="mov 2, %o0"@}, |
@{address="0x000107c4",func-name="main",offset="8", |
inst="sethi %hi(0x11800), %o2"@}, |
@{address="0x000107c8",func-name="main",offset="12", |
inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"@}, |
@{address="0x000107cc",func-name="main",offset="16", |
inst="sethi %hi(0x11800), %o2"@}, |
@{address="0x000107d0",func-name="main",offset="20", |
inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"@}@} |
(gdb) |
@end smallexample |
|
Disassemble the whole @code{main} function. Line 32 is part of |
@code{main}. |
|
@smallexample |
-data-disassemble -f basics.c -l 32 -- 0 |
^done,asm_insns=@{ |
@{address="0x000107bc",func-name="main",offset="0", |
inst="save %sp, -112, %sp"@}, |
@{address="0x000107c0",func-name="main",offset="4", |
inst="mov 2, %o0"@}, |
@{address="0x000107c4",func-name="main",offset="8", |
inst="sethi %hi(0x11800), %o2"@}, |
[...] |
@{address="0x0001081c",func-name="main",offset="96",inst="ret "@}, |
@{address="0x00010820",func-name="main",offset="100",inst="restore "@}@} |
(gdb) |
@end smallexample |
|
Disassemble 3 instructions from the start of @code{main}: |
|
@smallexample |
(gdb) |
-data-disassemble -f basics.c -l 32 -n 3 -- 0 |
^done,asm_insns=@{ |
@{address="0x000107bc",func-name="main",offset="0", |
inst="save %sp, -112, %sp"@}, |
@{address="0x000107c0",func-name="main",offset="4", |
inst="mov 2, %o0"@}, |
@{address="0x000107c4",func-name="main",offset="8", |
inst="sethi %hi(0x11800), %o2"@}@} |
(gdb) |
@end smallexample |
|
Disassemble 3 instructions from the start of @code{main} in mixed mode: |
|
@smallexample |
(gdb) |
-data-disassemble -f basics.c -l 32 -n 3 -- 1 |
^done,asm_insns=@{ |
src_and_asm_line=@{line="31", |
file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ |
testsuite/gdb.mi/basics.c",line_asm_insn=@{ |
@{address="0x000107bc",func-name="main",offset="0", |
inst="save %sp, -112, %sp"@}@}@}, |
|
src_and_asm_line=@{line="32", |
file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ |
testsuite/gdb.mi/basics.c",line_asm_insn=@{ |
@{address="0x000107c0",func-name="main",offset="4", |
inst="mov 2, %o0"@}, |
@{address="0x000107c4",func-name="main",offset="8", |
inst="sethi %hi(0x11800), %o2"@}@}@}@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-data-evaluate-expression} Command |
@findex -data-evaluate-expression |
|
@subsubheading Synopsis |
|
@example |
-data-evaluate-expression @var{expr} |
@end example |
|
Evaluate @var{expr} as an expression. The expression could contain an |
inferior function call. The function call will execute synchronously. |
If the expression contains spaces, it must be enclosed in double quotes. |
|
@subsubheading GDB Command |
|
The corresponding GDB commands are @samp{print}, @samp{output}, and |
@samp{call}. In @code{gdbtk} only, there's a corresponding |
@samp{gdb_eval} command. |
|
@subsubheading Example |
|
In the following example, the numbers that precede the commands are the |
@dfn{tokens} described in @ref{GDB/MI Command Syntax, , @sc{gdb/mi} |
Command Syntax}. Notice how @sc{gdb/mi} returns the same tokens in its |
output. |
|
@smallexample |
211-data-evaluate-expression A |
211^done,value="1" |
(gdb) |
311-data-evaluate-expression &A |
311^done,value="0xefffeb7c" |
(gdb) |
411-data-evaluate-expression A+3 |
411^done,value="4" |
(gdb) |
511-data-evaluate-expression "A + 3" |
511^done,value="4" |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-data-list-changed-registers} Command |
@findex -data-list-changed-registers |
|
@subsubheading Synopsis |
|
@example |
-data-list-changed-registers |
@end example |
|
Display a list of the registers that have changed. |
|
@subsubheading GDB Command |
|
GDB doesn't have a direct analog for this command; @code{gdbtk} has the |
corresponding command @samp{gdb_changed_register_list}. |
|
@subsubheading Example |
|
On a PPC MBX board: |
|
@smallexample |
(gdb) |
-exec-continue |
^running |
|
(gdb) |
*stopped,reason="breakpoint-hit",bkptno="1",frame=@{func="main", |
args=@{@},file="try.c",line="5"@} |
(gdb) |
-data-list-changed-registers |
^done,changed-registers=@{"0","1","2","4","5","6","7","8","9", |
"10","11","13","14","15","16","17","18","19","20","21","22","23", |
"24","25","26","27","28","30","31","64","65","66","67","69"@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-data-list-register-names} Command |
@findex -data-list-register-names |
|
@subsubheading Synopsis |
|
@example |
-data-list-register-names [ ( @var{regno} )+ ] |
@end example |
|
Show a list of register names for the current target. If no arguments |
are given, it shows a list of the names of all the registers. If |
integer numbers are given as arguments, it will print a list of the |
names of the registers corresponding to the arguments. |
|
@subsubheading GDB Command |
|
GDB does not have a command which corresponds to |
@samp{-data-list-register-names}. In @code{gdbtk} there is a |
corresponding command @samp{gdb_regnames}. |
|
@subsubheading Example |
|
For the PPC MBX board: |
@smallexample |
(gdb) |
-data-list-register-names |
^done,register-names=@{"r0","r1","r2","r3","r4","r5","r6","r7", |
"r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18", |
"r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", |
"r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", |
"f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20", |
"f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31", |
"pc","ps","cr","lr","ctr","xer"@} |
(gdb) |
-data-list-register-names 1 2 3 |
^done,register-names=@{"r1","r2","r3"@} |
(gdb) |
@end smallexample |
|
@subheading The @code{-data-list-register-values} Command |
@findex -data-list-register-values |
|
@subsubheading Synopsis |
|
@example |
-data-list-register-values @var{fmt} [ ( @var{regno} )*] |
@end example |
|
Display the registers' contents. @var{fmt} is the format according to |
which the registers' contents are to be returned, followed by an optional |
list of numbers specifying the registers to display. A missing list of |
numbers indicates that the contents of all the registers must be returned. |
|
Allowed formats for @var{fmt} are: |
|
@table @code |
@item x |
Hexadecimal |
@item o |
Octal |
@item t |
Binary |
@item d |
Decimal |
@item r |
Raw |
@item N |
Natural |
@end table |
|
@subsubheading GDB Command |
|
The corresponding GDB commands are @samp{info reg}, @samp{info all-reg}, |
and (in @code{gdbtk}) @samp{gdb_fetch_registers}. |
|
@subsubheading Example |
|
For a PPC MBX board (note: line breaks are for readability only, they |
don't appear in the actual output): |
|
@smallexample |
(gdb) |
-data-list-register-values r 64 65 |
^done,register-values=@{@{number="64",value="0xfe00a300"@}, |
@{number="65",value="0x00029002"@}@} |
(gdb) |
-data-list-register-values x |
^done,register-values=@{@{number="0",value="0xfe0043c8"@}, |
@{number="1",value="0x3fff88"@},@{number="2",value="0xfffffffe"@}, |
@{number="3",value="0x0"@},@{number="4",value="0xa"@}, |
@{number="5",value="0x3fff68"@},@{number="6",value="0x3fff58"@}, |
@{number="7",value="0xfe011e98"@},@{number="8",value="0x2"@}, |
@{number="9",value="0xfa202820"@},@{number="10",value="0xfa202808"@}, |
@{number="11",value="0x1"@},@{number="12",value="0x0"@}, |
@{number="13",value="0x4544"@},@{number="14",value="0xffdfffff"@}, |
@{number="15",value="0xffffffff"@},@{number="16",value="0xfffffeff"@}, |
@{number="17",value="0xefffffed"@},@{number="18",value="0xfffffffe"@}, |
@{number="19",value="0xffffffff"@},@{number="20",value="0xffffffff"@}, |
@{number="21",value="0xffffffff"@},@{number="22",value="0xfffffff7"@}, |
@{number="23",value="0xffffffff"@},@{number="24",value="0xffffffff"@}, |
@{number="25",value="0xffffffff"@},@{number="26",value="0xfffffffb"@}, |
@{number="27",value="0xffffffff"@},@{number="28",value="0xf7bfffff"@}, |
@{number="29",value="0x0"@},@{number="30",value="0xfe010000"@}, |
@{number="31",value="0x0"@},@{number="32",value="0x0"@}, |
@{number="33",value="0x0"@},@{number="34",value="0x0"@}, |
@{number="35",value="0x0"@},@{number="36",value="0x0"@}, |
@{number="37",value="0x0"@},@{number="38",value="0x0"@}, |
@{number="39",value="0x0"@},@{number="40",value="0x0"@}, |
@{number="41",value="0x0"@},@{number="42",value="0x0"@}, |
@{number="43",value="0x0"@},@{number="44",value="0x0"@}, |
@{number="45",value="0x0"@},@{number="46",value="0x0"@}, |
@{number="47",value="0x0"@},@{number="48",value="0x0"@}, |
@{number="49",value="0x0"@},@{number="50",value="0x0"@}, |
@{number="51",value="0x0"@},@{number="52",value="0x0"@}, |
@{number="53",value="0x0"@},@{number="54",value="0x0"@}, |
@{number="55",value="0x0"@},@{number="56",value="0x0"@}, |
@{number="57",value="0x0"@},@{number="58",value="0x0"@}, |
@{number="59",value="0x0"@},@{number="60",value="0x0"@}, |
@{number="61",value="0x0"@},@{number="62",value="0x0"@}, |
@{number="63",value="0x0"@},@{number="64",value="0xfe00a300"@}, |
@{number="65",value="0x29002"@},@{number="66",value="0x202f04b5"@}, |
@{number="67",value="0xfe0043b0"@},@{number="68",value="0xfe00b3e4"@}, |
@{number="69",value="0x20002b03"@}@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-data-read-memory} Command |
@findex -data-read-memory |
|
@subsubheading Synopsis |
|
@example |
-data-read-memory [ -o @var{byte-offset} ] |
@var{address} @var{word-format} @var{word-size} |
@var{nr-rows} @var{nr-cols} [ @var{aschar} ] |
@end example |
|
@noindent |
where: |
|
@table @samp |
@item @var{address} |
An expression specifying the address of the first memory word to be |
read. Complex expressions containing embedded white space should be |
quoted using the C convention. |
|
@item @var{word-format} |
The format to be used to print the memory words. The notation is the |
same as for GDB's @code{print} command (@pxref{Output Formats, , Output |
formats}). |
|
@item @var{word-size} |
The size of each memory word in bytes. |
|
@item @var{nr-rows} |
The number of rows in the output table. |
|
@item @var{nr-cols} |
The number of columns in the output table. |
|
@item @var{aschar} |
If present, indicates that each row should include an @sc{ascii} dump. The |
value of @var{aschar} is used as a padding character when a byte is not a |
member of the printable @sc{ascii} character set (printable @sc{ascii} |
characters are those whose code is between 32 and 126, inclusively). |
|
@item @var{byte-offset} |
An offset to add to the @var{address} before fetching memory. |
@end table |
|
This command displays memory contents as a table of @var{nr-rows} by |
@var{nr-cols} words, each word being @var{word-size} bytes. In total, |
@code{@var{nr-rows} * @var{nr-cols} * @var{word-size}} bytes are read |
(returned as @samp{total-bytes}). Should less then the requested number |
of bytes be returned by the target, the missing words are identified |
using @samp{N/A}. The number of bytes read from the target is returned |
in @samp{nr-bytes} and the starting address used to read memory in |
@samp{addr}. |
|
The address of the next/previous page or row is available in |
@samp{next-row} and @samp{prev-row}, @samp{next-page} and |
@samp{prev-page}. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{x}. @code{gdbtk} has |
@samp{gdb_get_mem} memory read. |
|
@subsubheading Example |
|
Read six bytes of memory starting at @code{bytes+6} but then offset by |
@code{-6} bytes. Format as three rows of two columns. One byte per |
word. Display each word in hex. |
|
@smallexample |
(gdb) |
9-data-read-memory -o -6 -- bytes+6 x 1 3 2 |
9^done,addr="0x00001390",nr-bytes="6",total-bytes="6", |
next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396", |
prev-page="0x0000138a",memory=@{ |
@{addr="0x00001390",data=@{"0x00","0x01"@}@}, |
@{addr="0x00001392",data=@{"0x02","0x03"@}@}, |
@{addr="0x00001394",data=@{"0x04","0x05"@}@}@} |
(gdb) |
@end smallexample |
|
Read two bytes of memory starting at address @code{shorts + 64} and |
display as a single word formatted in decimal. |
|
@smallexample |
(gdb) |
5-data-read-memory shorts+64 d 2 1 1 |
5^done,addr="0x00001510",nr-bytes="2",total-bytes="2", |
next-row="0x00001512",prev-row="0x0000150e", |
next-page="0x00001512",prev-page="0x0000150e",memory=@{ |
@{addr="0x00001510",data=@{"128"@}@}@} |
(gdb) |
@end smallexample |
|
Read thirty two bytes of memory starting at @code{bytes+16} and format |
as eight rows of four columns. Include a string encoding with @code{x} |
used as the non-printable character. |
|
@smallexample |
(gdb) |
4-data-read-memory bytes+16 x 1 8 4 x |
4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32", |
next-row="0x000013c0",prev-row="0x0000139c", |
next-page="0x000013c0",prev-page="0x00001380",memory=@{ |
@{addr="0x000013a0",data=@{"0x10","0x11","0x12","0x13"@},ascii="xxxx"@}, |
@{addr="0x000013a4",data=@{"0x14","0x15","0x16","0x17"@},ascii="xxxx"@}, |
@{addr="0x000013a8",data=@{"0x18","0x19","0x1a","0x1b"@},ascii="xxxx"@}, |
@{addr="0x000013ac",data=@{"0x1c","0x1d","0x1e","0x1f"@},ascii="xxxx"@}, |
@{addr="0x000013b0",data=@{"0x20","0x21","0x22","0x23"@},ascii=" !\"#"@}, |
@{addr="0x000013b4",data=@{"0x24","0x25","0x26","0x27"@},ascii="$%&'"@}, |
@{addr="0x000013b8",data=@{"0x28","0x29","0x2a","0x2b"@},ascii="()*+"@}, |
@{addr="0x000013bc",data=@{"0x2c","0x2d","0x2e","0x2f"@},ascii=",-./"@}@} |
(gdb) |
@end smallexample |
|
@subheading The @code{-display-delete} Command |
@findex -display-delete |
|
@subsubheading Synopsis |
|
@example |
-display-delete @var{number} |
@end example |
|
Delete the display @var{number}. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{delete display}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-display-disable} Command |
@findex -display-disable |
|
@subsubheading Synopsis |
|
@example |
-display-disable @var{number} |
@end example |
|
Disable display @var{number}. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{disable display}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-display-enable} Command |
@findex -display-enable |
|
@subsubheading Synopsis |
|
@example |
-display-enable @var{number} |
@end example |
|
Enable display @var{number}. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{enable display}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-display-insert} Command |
@findex -display-insert |
|
@subsubheading Synopsis |
|
@example |
-display-insert @var{expression} |
@end example |
|
Display @var{expression} every time the program stops. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{display}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-display-list} Command |
@findex -display-list |
|
@subsubheading Synopsis |
|
@example |
-display-list |
@end example |
|
List the displays. Do not show the current values. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{info display}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-environment-cd} Command |
@findex -environment-cd |
|
@subsubheading Synopsis |
|
@example |
-environment-cd @var{pathdir} |
@end example |
|
Set GDB's working directory. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{cd}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb |
^done |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-environment-directory} Command |
@findex -environment-directory |
|
@subsubheading Synopsis |
|
@example |
-environment-directory @var{pathdir} |
@end example |
|
Add directory @var{pathdir} to beginning of search path for source files. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{dir}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb |
^done |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-environment-path} Command |
@findex -environment-path |
|
@subsubheading Synopsis |
|
@example |
-environment-path ( @var{pathdir} )+ |
@end example |
|
Add directories to beginning of search path for object files. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{path}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb |
^done |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-environment-pwd} Command |
@findex -environment-pwd |
|
@subsubheading Synopsis |
|
@example |
-environment-pwd |
@end example |
|
Show the current working directory. |
|
@subsubheading GDB command |
|
The corresponding GDB command is @samp{pwd}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-environment-pwd |
~Working directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb. |
^done |
(gdb) |
@end smallexample |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Program Control |
@section @sc{gdb/mi} Program control |
|
@subsubheading Program termination |
|
As a result of execution, the inferior program can run to completion, if |
it doesn't encouter any breakpoints. In this case the ouput will |
include an exit code, if the program has exited exceptionally. |
|
@subsubheading Examples: |
|
@noindent |
Program exited normally: |
|
@smallexample |
(gdb) |
-exec-run |
^running |
(gdb) |
x = 55 |
*stopped,reason="exited-normally" |
(gdb) |
@end smallexample |
|
@noindent |
Program exited exceptionally: |
|
@smallexample |
(gdb) |
-exec-run |
^running |
(gdb) |
x = 55 |
*stopped,reason="exited",exit-code="01" |
(gdb) |
@end smallexample |
|
Another way the program can terminate is if it receives a signal such as |
@code{SIGINT}. In this case, @sc{gdb/mi} displays this: |
|
@smallexample |
(gdb) |
*stopped,reason="exited-signalled",signal-name="SIGINT", |
signal-meaning="Interrupt" |
@end smallexample |
|
|
@subheading The @code{-exec-abort} Command |
@findex -exec-abort |
|
@subsubheading Synopsis |
|
@example |
-exec-abort |
@end example |
|
Kill the inferior running program. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{kill}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-exec-arguments} Command |
@findex -exec-arguments |
|
@subsubheading Synopsis |
|
@example |
-exec-arguments @var{args} |
@end example |
|
Set the inferior program arguments, to be used in the next |
@samp{-exec-run}. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{set args}. |
|
@subsubheading Example |
|
@c FIXME! |
Don't have one around. |
|
|
@subheading The @code{-exec-continue} Command |
@findex -exec-continue |
|
@subsubheading Synopsis |
|
@example |
-exec-continue |
@end example |
|
Asynchronous command. Resumes the execution of the inferior program |
until a breakpoint is encountered, or until the inferior exits. |
|
@subsubheading GDB Command |
|
The corresponding GDB corresponding is @samp{continue}. |
|
@subsubheading Example |
|
@smallexample |
-exec-continue |
^running |
(gdb) |
@@Hello world |
*stopped,reason="breakpoint-hit",bkptno="2",frame=@{func="foo",args=@{@}, |
file="hello.c",line="13"@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-finish} Command |
@findex -exec-finish |
|
@subsubheading Synopsis |
|
@example |
-exec-finish |
@end example |
|
Asynchronous command. Resumes the execution of the inferior program |
until the current function is exited. Displays the results returned by |
the function. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{finish}. |
|
@subsubheading Example |
|
Function returning @code{void}. |
|
@smallexample |
-exec-finish |
^running |
(gdb) |
@@hello from foo |
*stopped,reason="function-finished",frame=@{func="main",args=@{@}, |
file="hello.c",line="7"@} |
(gdb) |
@end smallexample |
|
Function returning other than @code{void}. The name of the internal GDB |
variable storing the result is printed, together with the value itself. |
|
@smallexample |
-exec-finish |
^running |
(gdb) |
*stopped,reason="function-finished",frame=@{addr="0x000107b0",func="foo", |
args=@{@{name="a",value="1"@},@{name="b",value="9"@}@}, |
file="recursive2.c",line="14"@}, |
gdb-result-var="$1",return-value="0" |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-interrupt} Command |
@findex -exec-interrupt |
|
@subsubheading Synopsis |
|
@example |
-exec-interrupt |
@end example |
|
Asynchronous command. Interrupts the background execution of the target. |
Note how the token associated with the stop message is the one for the |
execution command that has been interrupted. The token for the interrupt |
itself only appears in the '^done' output. If the user is trying to |
interrupt a non-running program, an error message will be printed. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{interrupt}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
111-exec-continue |
111^running |
|
(gdb) |
222-exec-interrupt |
222^done |
(gdb) |
111*stopped,signal-name="SIGINT",signal-meaning="Interrupt", |
frame=@{addr="0x00010140",func="foo",args=@{@},file="try.c",line="13"@} |
(gdb) |
|
(gdb) |
-exec-interrupt |
^error,msg="mi_cmd_exec_interrupt: Inferior not executing." |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-next} Command |
@findex -exec-next |
|
@subsubheading Synopsis |
|
@example |
-exec-next |
@end example |
|
Asynchronous command. Resumes execution of the inferior program, stopping |
when the beginning of the next source line is reached. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{next}. |
|
@subsubheading Example |
|
@smallexample |
-exec-next |
^running |
(gdb) |
*stopped,reason="end-stepping-range",line="8",file="hello.c" |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-next-instruction} Command |
@findex -exec-next-instruction |
|
@subsubheading Synopsis |
|
@example |
-exec-next-instruction |
@end example |
|
Asynchronous command. Executes one machine instruction. If the |
instruction is a function call continues until the function returns. If |
the program stops at an instruction in the middle of a source line, the |
address will be printed as well. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{nexti}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-exec-next-instruction |
^running |
|
(gdb) |
*stopped,reason="end-stepping-range", |
addr="0x000100d4",line="5",file="hello.c" |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-return} Command |
@findex -exec-return |
|
@subsubheading Synopsis |
|
@example |
-exec-return |
@end example |
|
Makes current function return immediately. Doesn't execute the inferior. |
Displays the new current frame. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{return}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
200-break-insert callee4 |
200^done,bkpt=@{number="1",addr="0x00010734", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@} |
(gdb) |
000-exec-run |
000^running |
(gdb) |
000*stopped,reason="breakpoint-hit",bkptno="1", |
frame=@{func="callee4",args=@{@}, |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@} |
(gdb) |
205-break-delete |
205^done |
(gdb) |
111-exec-return |
111^done,frame=@{level="0 ",func="callee3", |
args=@{@{name="strarg", |
value="0x11940 \"A string argument.\""@}@}, |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-run} Command |
@findex -exec-run |
|
@subsubheading Synopsis |
|
@example |
-exec-run |
@end example |
|
Asynchronous command. Starts execution of the inferior from the |
beginning. The inferior executes until either a breakpoint is |
encountered or the program exits. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{run}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-break-insert main |
^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@} |
(gdb) |
-exec-run |
^running |
(gdb) |
*stopped,reason="breakpoint-hit",bkptno="1", |
frame=@{func="main",args=@{@},file="recursive2.c",line="4"@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-show-arguments} Command |
@findex -exec-show-arguments |
|
@subsubheading Synopsis |
|
@example |
-exec-show-arguments |
@end example |
|
Print the arguments of the program. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{show args}. |
|
@subsubheading Example |
N.A. |
|
@c @subheading -exec-signal |
|
@subheading The @code{-exec-step} Command |
@findex -exec-step |
|
@subsubheading Synopsis |
|
@example |
-exec-step |
@end example |
|
Asynchronous command. Resumes execution of the inferior program, stopping |
when the beginning of the next source line is reached, if the next |
source line is not a function call. If it is, stop at the first |
instruction of the called function. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{step}. |
|
@subsubheading Example |
|
Stepping into a function: |
|
@smallexample |
-exec-step |
^running |
(gdb) |
*stopped,reason="end-stepping-range", |
frame=@{func="foo",args=@{@{name="a",value="10"@}, |
@{name="b",value="0"@}@},file="recursive2.c",line="11"@} |
(gdb) |
@end smallexample |
|
Regular stepping: |
|
@smallexample |
-exec-step |
^running |
(gdb) |
*stopped,reason="end-stepping-range",line="14",file="recursive2.c" |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-step-instruction} Command |
@findex -exec-step-instruction |
|
@subsubheading Synopsis |
|
@example |
-exec-step-instruction |
@end example |
|
Asynchronous command. Resumes the inferior which executes one machine |
instruction. The output, once GDB has stopped, will vary depending on |
whether we have stopped in the middle of a source line or not. In the |
former case, the address at which the program stopped will be printed as |
well. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{stepi}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-exec-step-instruction |
^running |
|
(gdb) |
*stopped,reason="end-stepping-range", |
frame=@{func="foo",args=@{@},file="try.c",line="10"@} |
(gdb) |
-exec-step-instruction |
^running |
|
(gdb) |
*stopped,reason="end-stepping-range", |
frame=@{addr="0x000100f4",func="foo",args=@{@},file="try.c",line="10"@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-exec-until} Command |
@findex -exec-until |
|
@subsubheading Synopsis |
|
@example |
-exec-until [ @var{location} ] |
@end example |
|
Asynchronous command. Executes the inferior until the @var{location} |
specified in the argument is reached. If there is no argument, the inferior |
executes until a source line greater than the current one is reached. |
The reason for stopping in this case will be ``location-reached''. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{until}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-exec-until recursive2.c:6 |
^running |
(gdb) |
x = 55 |
*stopped,reason="location-reached",frame=@{func="main",args=@{@}, |
file="recursive2.c",line="6"@} |
(gdb) |
@end smallexample |
|
@ignore |
@subheading -file-clear |
Is this going away???? |
@end ignore |
|
|
@subheading The @code{-file-exec-and-symbols} Command |
@findex -file-exec-and-symbols |
|
@subsubheading Synopsis |
|
@example |
-file-exec-and-symbols @var{file} |
@end example |
|
Specify the executable file to be debugged. This file is the one from |
which the symbol table is also read. If no file is specified, the |
command clears the executable and symbol information. If breakpoints |
are set when using this command with no arguments, gdb will produce |
error messages. Otherwise, no output is produced, except a completion |
notification. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{file}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx |
^done |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-file-exec-file} Command |
@findex -file-exec-file |
|
@subsubheading Synopsis |
|
@example |
-file-exec-file @var{file} |
@end example |
|
Specify the executable file to be debugged. Unlike |
@samp{-file-exec-and-symbols}, the symbol table is @emph{not} read |
from this file. If used without argument, GDB clears the information |
about the executable file. No output is produced, except a completion |
notification. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{exec-file}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx |
^done |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-file-list-exec-sections} Command |
@findex -file-list-exec-sections |
|
@subsubheading Synopsis |
|
@example |
-file-list-exec-sections |
@end example |
|
List the sections of the current executable file. |
|
@subsubheading GDB Command |
|
The GDB command @samp{info file} shows, among the rest, the same |
information as this command. @code{gdbtk} has a corresponding command |
@samp{gdb_load_info}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-file-list-exec-source-files} Command |
@findex -file-list-exec-source-files |
|
@subsubheading Synopsis |
|
@example |
-file-list-exec-source-files |
@end example |
|
List the source files for the current executable. |
|
@subsubheading GDB Command |
|
There's no GDB command which directly corresponds to this one. |
@code{gdbtk} has an analogous command @samp{gdb_listfiles}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-file-list-shared-libraries} Command |
@findex -file-list-shared-libraries |
|
@subsubheading Synopsis |
|
@example |
-file-list-shared-libraries |
@end example |
|
List the shared libraries in the program. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{info shared}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-file-list-symbol-files} Command |
@findex -file-list-symbol-files |
|
@subsubheading Synopsis |
|
@example |
-file-list-symbol-files |
@end example |
|
List symbol files. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{info file} (part of it). |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-file-symbol-file} Command |
@findex -file-symbol-file |
|
@subsubheading Synopsis |
|
@example |
-file-symbol-file @var{file} |
@end example |
|
Read symbol table info from the specified @var{file} argument. When |
used without arguments, clears GDB's symbol table info. No output is |
produced, except for a completion notification. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{symbol-file}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx |
^done |
(gdb) |
@end smallexample |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Miscellaneous Commands |
@section Miscellaneous GDB commands in @sc{gdb/mi} |
|
@c @subheading -gdb-complete |
|
@subheading The @code{-gdb-exit} Command |
@findex -gdb-exit |
|
@subsubheading Synopsis |
|
@example |
-gdb-exit |
@end example |
|
Exit GDB immediately. |
|
@subsubheading GDB Command |
|
Approximately corresponds to @samp{quit}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-gdb-exit |
@end smallexample |
|
@subheading The @code{-gdb-set} Command |
@findex -gdb-set |
|
@subsubheading Synopsis |
|
@example |
-gdb-set |
@end example |
|
Set an internal GDB variable. |
@c IS THIS A DOLLAR VARIABLE? OR SOMETHING LIKE ANNOTATE ????? |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{set}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-gdb-set $foo=3 |
^done |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-gdb-show} Command |
@findex -gdb-show |
|
@subsubheading Synopsis |
|
@example |
-gdb-show |
@end example |
|
Show the current value of a GDB variable. |
|
@subsubheading GDB command |
|
The corresponding GDB command is @samp{show}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-gdb-show annotate |
^done,value="0" |
(gdb) |
@end smallexample |
|
@c @subheading -gdb-source |
|
|
@subheading The @code{-gdb-version} Command |
@findex -gdb-version |
|
@subsubheading Synopsis |
|
@example |
-gdb-version |
@end example |
|
Show version information for GDB. Used mostly in testing. |
|
@subsubheading GDB Command |
|
There's no equivalent GDB command. GDB by default shows this |
information when you start an interactive session. |
|
@subsubheading Example |
|
@c This example modifies the actual output from GDB to avoid overfull |
@c box in TeX. |
@smallexample |
(gdb) |
-gdb-version |
~GNU gdb 5.2.1 |
~Copyright 2000 Free Software Foundation, Inc. |
~GDB is free software, covered by the GNU General Public License, and |
~you are welcome to change it and/or distribute copies of it under |
~ certain conditions. |
~Type "show copying" to see the conditions. |
~There is absolutely no warranty for GDB. Type "show warranty" for |
~ details. |
~This GDB was configured as |
"--host=sparc-sun-solaris2.5.1 --target=ppc-eabi". |
^done |
(gdb) |
@end smallexample |
|
@ignore |
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Kod Commands |
@section @sc{gdb/mi} Kod Commands |
|
The Kod commands are not implemented. |
|
@c @subheading -kod-info |
|
@c @subheading -kod-list |
|
@c @subheading -kod-list-object-types |
|
@c @subheading -kod-show |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Memory Overlay Commands |
@section @sc{gdb/mi} Memory Overlay Commands |
|
The memory overlay commands are not implemented. |
|
@c @subheading -overlay-auto |
|
@c @subheading -overlay-list-mapping-state |
|
@c @subheading -overlay-list-overlays |
|
@c @subheading -overlay-map |
|
@c @subheading -overlay-off |
|
@c @subheading -overlay-on |
|
@c @subheading -overlay-unmap |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Signal Handling Commands |
@section @sc{gdb/mi} Signal Handling Commands |
|
Signal handling commands are not implemented. |
|
@c @subheading -signal-handle |
|
@c @subheading -signal-list-handle-actions |
|
@c @subheading -signal-list-signal-types |
@end ignore |
|
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Stack Manipulation |
@section Stack manipulation commands in @sc{gdb/mi} |
|
|
@subheading The @code{-stack-info-frame} Command |
@findex -stack-info-frame |
|
@subsubheading Synopsis |
|
@example |
-stack-info-frame |
@end example |
|
Get info on the current frame. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{info frame} or @samp{frame} |
(without arguments). |
|
@subsubheading Example |
N.A. |
|
@subheading The @code{-stack-info-depth} Command |
@findex -stack-info-depth |
|
@subsubheading Synopsis |
|
@example |
-stack-info-depth [ @var{max-depth} ] |
@end example |
|
Return the depth of the stack. If the integer argument @var{max-depth} |
is specified, do not count beyond @var{max-depth} frames. |
|
@subsubheading GDB Command |
|
There's no equivalent GDB command. |
|
@subsubheading Example |
|
For a stack with frame levels 0 through 11: |
|
@smallexample |
(gdb) |
-stack-info-depth |
^done,depth="12" |
(gdb) |
-stack-info-depth 4 |
^done,depth="4" |
(gdb) |
-stack-info-depth 12 |
^done,depth="12" |
(gdb) |
-stack-info-depth 11 |
^done,depth="11" |
(gdb) |
-stack-info-depth 13 |
^done,depth="12" |
(gdb) |
@end smallexample |
|
@subheading The @code{-stack-list-arguments} Command |
@findex -stack-list-arguments |
|
@subsubheading Synopsis |
|
@example |
-stack-list-arguments @var{show-values} |
[ @var{low-frame} @var{high-frame} ] |
@end example |
|
Display a list of the arguments for the frames between @var{low-frame} |
and @var{high-frame} (inclusive). If @var{low-frame} and |
@var{high-frame} are not provided, list the arguments for the whole call |
stack. |
|
The @var{show-values} argument must have a value of 0 or 1. A value of |
0 means that only the names of the arguments are listed, a value of 1 |
means that both names and values of the arguments are printed. |
|
@subsubheading GDB Command |
|
GDB does not have an equivalent command. @code{gdbtk} has a |
@samp{gdb_get_args} command which partially overlaps with the |
functionality of @samp{-stack-list-arguments}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-stack-list-frames |
^done, |
stack=@{ |
frame=@{level="0 ",addr="0x00010734",func="callee4", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}, |
frame=@{level="1 ",addr="0x0001076c",func="callee3", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"@}, |
frame=@{level="2 ",addr="0x0001078c",func="callee2", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"@}, |
frame=@{level="3 ",addr="0x000107b4",func="callee1", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"@}, |
frame=@{level="4 ",addr="0x000107e0",func="main", |
file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"@}@} |
(gdb) |
-stack-list-arguments 0 |
^done, |
stack-args=@{ |
frame=@{level="0",args=@{@}@}, |
frame=@{level="1",args=@{name="strarg"@}@}, |
frame=@{level="2",args=@{name="intarg",name="strarg"@}@}, |
frame=@{level="3",args=@{name="intarg",name="strarg",name="fltarg"@}@}, |
frame=@{level="4",args=@{@}@}@} |
(gdb) |
-stack-list-arguments 1 |
^done, |
stack-args=@{ |
frame=@{level="0",args=@{@}@}, |
frame=@{level="1", |
args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@}@}, |
frame=@{level="2",args=@{ |
@{name="intarg",value="2"@}, |
@{name="strarg",value="0x11940 \"A string argument.\""@}@}@}, |
@{frame=@{level="3",args=@{ |
@{name="intarg",value="2"@}, |
@{name="strarg",value="0x11940 \"A string argument.\""@}, |
@{name="fltarg",value="3.5"@}@}@}, |
frame=@{level="4",args=@{@}@}@} |
(gdb) |
-stack-list-arguments 0 2 2 |
^done,stack-args=@{frame=@{level="2",args=@{name="intarg",name="strarg"@}@}@} |
(gdb) |
-stack-list-arguments 1 2 2 |
^done,stack-args=@{frame=@{level="2", |
args=@{@{name="intarg",value="2"@}, |
@{name="strarg",value="0x11940 \"A string argument.\""@}@}@}@} |
(gdb) |
@end smallexample |
|
@c @subheading -stack-list-exception-handlers |
|
|
@subheading The @code{-stack-list-frames} Command |
@findex -stack-list-frames |
|
@subsubheading Synopsis |
|
@example |
-stack-list-frames [ @var{low-frame} @var{high-frame} ] |
@end example |
|
List the frames currently on the stack. For each frame it displays the |
following info: |
|
@table @samp |
@item @var{level} |
The frame number, 0 being the topmost frame, i.e. the innermost function. |
@item @var{addr} |
The @code{$pc} value for that frame. |
@item @var{func} |
Function name. |
@item @var{file} |
File name of the source file where the function lives. |
@item @var{line} |
Line number corresponding to the @code{$pc}. |
@end table |
|
If invoked without arguments, this command prints a backtrace for the |
whole stack. If given two integer arguments, it shows the frames whose |
levels are between the two arguments (inclusive). If the two arguments |
are equal, it shows the single frame at the corresponding level. |
|
@subsubheading GDB Command |
|
The corresponding GDB commands are @samp{backtrace} and @samp{where}. |
|
@subsubheading Example |
|
Full stack backtrace: |
|
@smallexample |
(gdb) |
-stack-list-frames |
^done,stack= |
@{frame=@{level="0 ",addr="0x0001076c",func="foo", |
file="recursive2.c",line="11"@}, |
frame=@{level="1 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="2 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="3 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="4 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="5 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="6 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="7 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="8 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="9 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="10",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="11",addr="0x00010738",func="main", |
file="recursive2.c",line="4"@}@} |
(gdb) |
@end smallexample |
|
Show frames between low_frame and high_frame: |
|
@smallexample |
(gdb) |
-stack-list-frames 3 5 |
^done,stack= |
@{frame=@{level="3 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="4 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}, |
frame=@{level="5 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}@} |
(gdb) |
@end smallexample |
|
Show a single frame: |
|
@smallexample |
(gdb) |
-stack-list-frames 3 3 |
^done,stack= |
@{frame=@{level="3 ",addr="0x000107a4",func="foo", |
file="recursive2.c",line="14"@}@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-stack-list-locals} Command |
@findex -stack-list-locals |
|
@subsubheading Synopsis |
|
@example |
-stack-list-locals @var{print-values} |
@end example |
|
Display the local variable names for the current frame. With an |
argument of 0 prints only the names of the variables, with argument of 1 |
prints also their values. |
|
@subsubheading GDB Command |
|
@samp{info locals} in GDB, @samp{gdb_get_locals} in @code{gdbtk}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-stack-list-locals 0 |
^done,locals=@{name="A",name="B",name="C"@} |
(gdb) |
-stack-list-locals 1 |
^done,locals=@{@{name="A",value="1"@},@{name="B",value="2"@}, |
@{name="C",value="3"@}@} |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-stack-select-frame} Command |
@findex -stack-select-frame |
|
@subsubheading Synopsis |
|
@example |
-stack-select-frame @var{framenum} |
@end example |
|
Change the current frame. Select a different frame @var{framenum} on |
the stack. |
|
@subsubheading GDB Command |
|
The corresponding GDB commands are @samp{frame}, @samp{up}, @samp{down}, |
@samp{select-frame}, @samp{up-silent}, and @samp{down-silent}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-stack-select-frame 2 |
^done |
(gdb) |
@end smallexample |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Symbol Query |
@section @sc{gdb/mi} Symbol Query Commands |
|
|
@subheading The @code{-symbol-info-address} Command |
@findex -symbol-info-address |
|
@subsubheading Synopsis |
|
@example |
-symbol-info-address @var{symbol} |
@end example |
|
Describe where @var{symbol} is stored. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{info address}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-info-file} Command |
@findex -symbol-info-file |
|
@subsubheading Synopsis |
|
@example |
-symbol-info-file |
@end example |
|
Show the file for the symbol. |
|
@subsubheading GDB Command |
|
There's no equivalent GDB command. @code{gdbtk} has |
@samp{gdb_filnd_file}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-info-function} Command |
@findex -symbol-info-function |
|
@subsubheading Synopsis |
|
@example |
-symbol-info-function |
@end example |
|
Show which function the symbol lives in. |
|
@subsubheading GDB Command |
|
@samp{gdb_get_function} in @code{gdbtk}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-info-line} Command |
@findex -symbol-info-line |
|
@subsubheading Synopsis |
|
@example |
-symbol-info-line |
@end example |
|
Show the core addresses of the code for a source line. |
|
@subsubheading GDB Command |
|
The corresponding GDB comamnd is @samp{info line}. @code{gdbtk} has the |
@samp{gdb_get_line} @samp{gdb_get_file} commands. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-info-symbol} Command |
@findex -symbol-info-symbol |
|
@subsubheading Synopsis |
|
@example |
-symbol-info-symbol @var{addr} |
@end example |
|
Describe what symbol is at location @var{addr}. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{info symbol}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-list-functions} Command |
@findex -symbol-list-functions |
|
@subsubheading Synopsis |
|
@example |
-symbol-list-functions |
@end example |
|
List the functions in the executable. |
|
@subsubheading GDB Command |
|
@samp{info functions} in GDB, @samp{gdb_listfunc} @samp{gdb_search} in |
@code{gdbtk}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-list-types} Command |
@findex -symbol-list-types |
|
@subsubheading Synopsis |
|
@example |
-symbol-list-types |
@end example |
|
List all the type names. |
|
@subsubheading GDB Command |
|
The corresponding commands are @samp{info types} in GDB, |
@samp{gdb_search} in @code{gdbtk}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-list-variables} Command |
@findex -symbol-list-variables |
|
@subsubheading Synopsis |
|
@example |
-symbol-list-variables |
@end example |
|
List all the global and static variable names. |
|
@subsubheading GDB Command |
|
@samp{info variables} in GDB, @samp{gdb_search} in @code{gdbtk}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-locate} Command |
@findex -symbol-locate |
|
@subsubheading Synopsis |
|
@example |
-symbol-locate |
@end example |
|
@subsubheading GDB Command |
|
@samp{gdb_loc} in @code{gdbtk}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-symbol-type} Command |
@findex -symbol-type |
|
@subsubheading Synopsis |
|
@example |
-symbol-type @var{variable} |
@end example |
|
Show type of @var{variable}. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{ptype}, @code{gdbtk} has |
@samp{gdb_obj_variable}. |
|
@subsubheading Example |
N.A. |
|
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Target Manipulation |
@section @sc{gdb/mi} Target Manipulation Commands |
|
|
@subheading The @code{-target-attach} Command |
@findex -target-attach |
|
@subsubheading Synopsis |
|
@example |
-target-attach @var{pid} | @var{file} |
@end example |
|
Attach to a process @var{pid} or a file @var{file} outside of GDB. |
|
@subsubheading GDB command |
|
The corresponding GDB command is @samp{attach}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-target-compare-sections} Command |
@findex -target-compare-sections |
|
@subsubheading Synopsis |
|
@example |
-target-compare-sections [ @var{section} ] |
@end example |
|
Compare data of section @var{section} on target to the exec file. |
Without the argument, all sections are compared. |
|
@subsubheading GDB Command |
|
The GDB equivalent is @samp{compare-sections}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-target-detach} Command |
@findex -target-detach |
|
@subsubheading Synopsis |
|
@example |
-target-detach |
@end example |
|
Disconnect from the remote target. There's no output. |
|
@subsubheading GDB command |
|
The corresponding GDB command is @samp{detach}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-target-detach |
^done |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-target-download} Command |
@findex -target-download |
|
@subsubheading Synopsis |
|
@example |
-target-download |
@end example |
|
Loads the executable onto the remote target. |
It prints out an update message every half second, which includes the fields: |
|
@table @samp |
@item section |
The name of the section. |
@item section-sent |
The size of what has been sent so far for that section. |
@item section-size |
The size of the section. |
@item total-sent |
The total size of what was sent so far (the current and the previous sections). |
@item total-size |
The size of the overall executable to download. |
@end table |
|
@noindent |
Each message is sent as status record (@pxref{GDB/MI Output Syntax, , |
@sc{gdb/mi} Output Syntax}). |
|
In addition, it prints the name and size of the sections, as they are |
downloaded. These messages include the following fields: |
|
@table @samp |
@item section |
The name of the section. |
@item section-size |
The size of the section. |
@item total-size |
The size of the overall executable to download. |
@end table |
|
@noindent |
At the end, a summary is printed. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{load}. |
|
@subsubheading Example |
|
Note: each status message appears on a single line. Here the messages |
have been broken down so that they can fit onto a page. |
|
@smallexample |
(gdb) |
-target-download |
+download,@{section=".text",section-size="6668",total-size="9880"@} |
+download,@{section=".text",section-sent="512",section-size="6668", |
total-sent="512",total-size="9880"@} |
+download,@{section=".text",section-sent="1024",section-size="6668", |
total-sent="1024",total-size="9880"@} |
+download,@{section=".text",section-sent="1536",section-size="6668", |
total-sent="1536",total-size="9880"@} |
+download,@{section=".text",section-sent="2048",section-size="6668", |
total-sent="2048",total-size="9880"@} |
+download,@{section=".text",section-sent="2560",section-size="6668", |
total-sent="2560",total-size="9880"@} |
+download,@{section=".text",section-sent="3072",section-size="6668", |
total-sent="3072",total-size="9880"@} |
+download,@{section=".text",section-sent="3584",section-size="6668", |
total-sent="3584",total-size="9880"@} |
+download,@{section=".text",section-sent="4096",section-size="6668", |
total-sent="4096",total-size="9880"@} |
+download,@{section=".text",section-sent="4608",section-size="6668", |
total-sent="4608",total-size="9880"@} |
+download,@{section=".text",section-sent="5120",section-size="6668", |
total-sent="5120",total-size="9880"@} |
+download,@{section=".text",section-sent="5632",section-size="6668", |
total-sent="5632",total-size="9880"@} |
+download,@{section=".text",section-sent="6144",section-size="6668", |
total-sent="6144",total-size="9880"@} |
+download,@{section=".text",section-sent="6656",section-size="6668", |
total-sent="6656",total-size="9880"@} |
+download,@{section=".init",section-size="28",total-size="9880"@} |
+download,@{section=".fini",section-size="28",total-size="9880"@} |
+download,@{section=".data",section-size="3156",total-size="9880"@} |
+download,@{section=".data",section-sent="512",section-size="3156", |
total-sent="7236",total-size="9880"@} |
+download,@{section=".data",section-sent="1024",section-size="3156", |
total-sent="7748",total-size="9880"@} |
+download,@{section=".data",section-sent="1536",section-size="3156", |
total-sent="8260",total-size="9880"@} |
+download,@{section=".data",section-sent="2048",section-size="3156", |
total-sent="8772",total-size="9880"@} |
+download,@{section=".data",section-sent="2560",section-size="3156", |
total-sent="9284",total-size="9880"@} |
+download,@{section=".data",section-sent="3072",section-size="3156", |
total-sent="9796",total-size="9880"@} |
^done,address="0x10004",load-size="9880",transfer-rate="6586", |
write-rate="429" |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-target-exec-status} Command |
@findex -target-exec-status |
|
@subsubheading Synopsis |
|
@example |
-target-exec-status |
@end example |
|
Provide information on the state of the target (whether it is running or |
not, for instance). |
|
@subsubheading GDB Command |
|
There's no equivalent GDB command. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-target-list-available-targets} Command |
@findex -target-list-available-targets |
|
@subsubheading Synopsis |
|
@example |
-target-list-available-targets |
@end example |
|
List the possible targets to connect to. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{help target}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-target-list-current-targets} Command |
@findex -target-list-current-targets |
|
@subsubheading Synopsis |
|
@example |
-target-list-current-targets |
@end example |
|
Describe the current target. |
|
@subsubheading GDB Command |
|
The corresponding information is printed by @samp{info file} (among |
other things). |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-target-list-parameters} Command |
@findex -target-list-parameters |
|
@subsubheading Synopsis |
|
@example |
-target-list-parameters |
@end example |
|
@c ???? |
|
@subsubheading GDB Command |
|
No equivalent. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-target-select} Command |
@findex -target-select |
|
@subsubheading Synopsis |
|
@example |
-target-select @var{type} @var{parameters ...} |
@end example |
|
Connect GDB to the remote target. This command takes two args: |
|
@table @samp |
@item @var{type} |
The type of target, for instance @samp{async}, @samp{remote}, etc. |
@item @var{parameters} |
Device names, host names and the like. @xref{Target Commands, , |
Commands for managing targets}, for more details. |
@end table |
|
The output is a connection notification, followed by the address at |
which the target program is, in the following form: |
|
@smallexample |
^connected,addr="@var{address}",func="@var{function name}", |
args=@{@var{arg list}@} |
@end smallexample |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{target}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-target-select async /dev/ttya |
^connected,addr="0xfe00a300",func="??",args=@{@} |
(gdb) |
@end smallexample |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Thread Commands |
@section @sc{gdb/mi} Thread Commands |
|
|
@subheading The @code{-thread-info} Command |
@findex -thread-info |
|
@subsubheading Synopsis |
|
@example |
-thread-info |
@end example |
|
@subsubheading GDB command |
|
No equivalent. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-thread-list-all-threads} Command |
@findex -thread-list-all-threads |
|
@subsubheading Synopsis |
|
@example |
-thread-list-all-threads |
@end example |
|
@subsubheading GDB Command |
|
The equivalent GDB command is @samp{info threads}. |
|
@subsubheading Example |
N.A. |
|
|
@subheading The @code{-thread-list-ids} Command |
@findex -thread-list-ids |
|
@subsubheading Synopsis |
|
@example |
-thread-list-ids |
@end example |
|
Produces a list of the currently known gdb thread ids. At the end of the |
list it also prints the total number of such threads. |
|
@subsubheading GDB Command |
|
Part of @samp{info threads} supplies the same information. |
|
@subsubheading Example |
|
No threads present, besides the main process. |
|
@smallexample |
(gdb) |
-thread-list-ids |
^done,thread-ids=@{@},number-of-threads="0" |
(gdb) |
@end smallexample |
|
|
Several threads. |
|
@smallexample |
(gdb) |
-thread-list-ids |
^done,thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@}, |
number-of-threads="3" |
(gdb) |
@end smallexample |
|
|
@subheading The @code{-thread-select} Command |
@findex -thread-select |
|
@subsubheading Synopsis |
|
@example |
-thread-select @var{threadnum} |
@end example |
|
Make @var{threadnum} the current thread. It prints the number of the new |
current thread, and the topmost frame for that thread. |
|
@subsubheading GDB Command |
|
The corresponding GDB command is @samp{thread}. |
|
@subsubheading Example |
|
@smallexample |
(gdb) |
-exec-next |
^running |
(gdb) |
*stopped,reason="end-stepping-range",thread-id="2",line="187", |
file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c" |
(gdb) |
-thread-list-ids |
^done, |
thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@}, |
number-of-threads="3" |
(gdb) |
-thread-select 3 |
^done,new-thread-id="3", |
frame=@{level="0 ",func="vprintf", |
args=@{@{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""@}, |
@{name="arg",value="0x2"@}@},file="vprintf.c",line="31"@} |
(gdb) |
@end smallexample |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Tracepoint Commands |
@section @sc{gdb/mi} Tracepoint Commands |
|
The tracepoint commands are not yet implemented. |
|
@c @subheading -trace-actions |
|
@c @subheading -trace-delete |
|
@c @subheading -trace-disable |
|
@c @subheading -trace-dump |
|
@c @subheading -trace-enable |
|
@c @subheading -trace-exists |
|
@c @subheading -trace-find |
|
@c @subheading -trace-frame-number |
|
@c @subheading -trace-info |
|
@c @subheading -trace-insert |
|
@c @subheading -trace-list |
|
@c @subheading -trace-pass-count |
|
@c @subheading -trace-save |
|
@c @subheading -trace-start |
|
@c @subheading -trace-stop |
|
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Variable Objects |
@section @sc{gdb/mi} Variable Objects |
|
|
@subheading Motivation for Variable Objects in @sc{gdb/mi} |
|
For the implementation of a variable debugger window (locals, watched |
expressions, etc.), we are proposing the adaptation of the existing code |
used by @code{Insight}. |
|
The two main reasons for that are: |
|
@enumerate 1 |
@item |
It has been proven in practice (it is already on its second generation). |
|
@item |
It will shorten development time (needless to say how important it is |
now). |
@end enumerate |
|
The original interface was designed to be used by Tcl code, so it was |
slightly changed so it could be used through flathead. This document |
describes the flathead operations that will be available and gives some |
hints about their use. |
|
@emph{Note}: In addition to the set of operations described here, we |
expect the @sc{gui} implementation of a variable window to require, at |
least, the following operations: |
|
@itemize @bullet |
@item -gdb-show output-radix |
@item -stack-list-arguments |
@item -stack-list-locals |
@item -stack-select-frame |
@end itemize |
|
@subheading Introduction to Variable Objects in @sc{gdb/mi} |
|
@cindex variable objects in @sc{gdb/mi} |
The basic idea behind variable objects is the creation of a named object |
to represent a variable, an expression, a memory location or even a CPU |
register. For each object created, a set of operations is available for |
examining or changing its properties. |
|
Furthermore, complex data types, such as C structures, are represented |
in a tree format. For instance, the @code{struct} type variable is the |
root and the children will represent the struct members. If a child |
is itself of a complex type, it will also have children of its own. |
Appropriate language differences are handled for C, C@t{++} and Java. |
|
When returning the actual values of the objects, this facility allows |
for the individual selection of the display format used in the result |
creation. It can be chosen among: binary, decimal, hexadecimal, octal |
and natural. Natural refers to a default format automatically |
chosen based on the variable type (like decimal for an @code{int}, hex |
for pointers, etc.). |
|
The following is the complete set of flathead operations defined to |
access this functionality: |
|
@multitable @columnfractions .3 .6 |
@item @strong{Operation} |
@tab @strong{Description} |
|
@item -var-create |
@tab create a variable object |
@item -var-delete |
@tab delete the variable object and its children |
@item -var-set-format |
@tab set the display format of this variable |
@item -var-show-format |
@tab show the display format of this variable |
@item -var-info-num-children |
@tab tells how many children this object has |
@item -var-list-children |
@tab return a list of the object's children |
@item -var-info-type |
@tab show the type of this variable object |
@item -var-info-expression |
@tab print what this variable object represents |
@item -var-show-attributes |
@tab is this variable editable? does it exist here? |
@item -var-evaluate-expression |
@tab get the value of this variable |
@item -var-assign |
@tab set the value of this variable |
@item -var-update |
@tab update the variable and its children |
@end multitable |
|
In the next subsection we describe each operation in detail and suggest |
how it can be used. |
|
@subheading Description And Use of Operations on Variable Objects |
|
@subheading The @code{-var-create} Command |
@findex -var-create |
|
@subsubheading Synopsis |
|
@example |
-var-create @{@var{name} | "-"@} |
@{@var{frame-addr} | "*"@} @var{expression} |
@end example |
|
This operation creates a variable object, which allows the monitoring of |
a variable, the result of an expression, a memory cell or a CPU |
register. |
|
The @var{name} parameter is the string by which the object can be |
referenced. It must be unique. If @samp{-} is specified, the varobj |
system will generate a string "varNNNNNN'' automatically. It will be |
unique provided that one does not specify @var{name} on that format. |
The command fails if a duplicate name is found. |
|
The frame under which the expression should be evaluated can be |
specified by @var{frame-addr}. A @samp{*} indicates that the current |
frame should be used. |
|
@var{expression} is any expression valid on the current language set (must not |
begin with a @samp{*}), or one of the following: |
|
@itemize @bullet |
@item |
@samp{*@var{addr}}, where @var{addr} is the address of a memory cell |
|
@item |
@samp{*@var{addr}-@var{addr}} -- a memory address range (TBD) |
|
@item |
@samp{$@var{regname}} -- a CPU register name |
@end itemize |
|
@subsubheading Result |
|
This operation returns the name, number of children and the type of the |
object created. Type is returned as a string as the ones generated by |
the GDB CLI: |
|
@example |
name="@var{name}",numchild="N",type="@var{type}" |
@end example |
|
|
@subheading The @code{-var-delete} Command |
@findex -var-delete |
|
@subsubheading Synopsis |
|
@example |
-var-delete @var{name} |
@end example |
|
Deletes a previously created variable object and all of its children. |
|
Returns an error if the object @var{name} is not found. |
|
|
@subheading The @code{-var-set-format} Command |
@findex -var-set-format |
|
@subsubheading Synopsis |
|
@example |
-var-set-format @var{name} @var{format-spec} |
@end example |
|
Sets the output format for the value of the object @var{name} to be |
@var{format-spec}. |
|
The syntax for the @var{format-spec} is as follows: |
|
@example |
@var{format-spec} @expansion{} |
@{binary | decimal | hexadecimal | octal | natural@} |
@end example |
|
|
@subheading The @code{-var-show-format} Command |
@findex -var-show-format |
|
@subsubheading Synopsis |
|
@example |
-var-show-format @var{name} |
@end example |
|
Returns the format used to display the value of the object @var{name}. |
|
@example |
format @expansion{} |
@var{format-spec} |
@end example |
|
|
@subheading The @code{-var-info-num-children} Command |
@findex -var-info-num-children |
|
@subsubheading Synopsis |
|
@example |
-var-info-num-children @var{name} |
@end example |
|
Returns the number of children of a variable object @var{name}: |
|
@example |
numchild=@var{n} |
@end example |
|
|
@subheading The @code{-var-list-children} Command |
@findex -var-list-children |
|
@subsubheading Synopsis |
|
@example |
-var-list-children @var{name} |
@end example |
|
Returns a list of the children of the specified variable object: |
|
@example |
numchild=@var{n},children=@{@{name=@var{name}, |
numchild=@var{n},type=@var{type}@},(repeats N times)@} |
@end example |
|
|
@subheading The @code{-var-info-type} Command |
@findex -var-info-type |
|
@subsubheading Synopsis |
|
@example |
-var-info-type @var{name} |
@end example |
|
Returns the type of the specified variable @var{name}. The type is |
returned as a string in the same format as it is output by the GDB CLI: |
|
@example |
type=@var{typename} |
@end example |
|
|
@subheading The @code{-var-info-expression} Command |
@findex -var-info-expression |
|
@subsubheading Synopsis |
|
@example |
-var-info-expression @var{name} |
@end example |
|
Returns what is represented by the variable object @var{name}: |
|
@example |
lang=@var{lang-spec},exp=@var{expression} |
@end example |
|
@noindent |
where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}. |
|
@subheading The @code{-var-show-attributes} Command |
@findex -var-show-attributes |
|
@subsubheading Synopsis |
|
@example |
-var-show-attributes @var{name} |
@end example |
|
List attributes of the specified variable object @var{name}: |
|
@example |
status=@var{attr} [ ( ,@var{attr} )* ] |
@end example |
|
@noindent |
where @var{attr} is @code{@{ @{ editable | noneditable @} | TBD @}}. |
|
@subheading The @code{-var-evaluate-expression} Command |
@findex -var-evaluate-expression |
|
@subsubheading Synopsis |
|
@example |
-var-evaluate-expression @var{name} |
@end example |
|
Evaluates the expression that is represented by the specified variable |
object and returns its value as a string in the current format specified |
for the object: |
|
@example |
value=@var{value} |
@end example |
|
@subheading The @code{-var-assign} Command |
@findex -var-assign |
|
@subsubheading Synopsis |
|
@example |
-var-assign @var{name} @var{expression} |
@end example |
|
Assigns the value of @var{expression} to the variable object specified |
by @var{name}. The object must be ``editable''. |
|
@subheading The @code{-var-update} Command |
@findex -var-update |
|
@subsubheading Synopsis |
|
@example |
-var-update @{@var{name} | "*"@} |
@end example |
|
Update the value of the variable object @var{name} by evaluating its |
expression after fetching all the new values from memory or registers. |
A @samp{*} causes all existing variable objects to be updated. |
|
@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
@node GDB/MI Draft Changes to Output Syntax |
@section @sc{gdb/mi} Draft Changes to Output Syntax |
|
@cindex draft changes to output syntax of @sc{gdb/mi} |
@cindex @sc{gdb/mi}, draft changes to output syntax |
|
One problem identified in the existing @sc{gdb/mi} output syntax was the |
difficulty in differentiating between a tuple such as: |
|
@example |
@{number="1",type="breakpoint",disp="keep",enabled="y"@} |
@end example |
|
where each value has a unique label, and a list such as: |
|
@example |
@{"1","2","4"@} |
@{bp="1",bp="2",bp="4"@} |
@end example |
|
where values are un-labeled or the label is duplicated. |
|
What follows is a draft revision to the output specification that |
addresses this problem. |
|
The output from @sc{gdb/mi} consists of zero or more out-of-band records |
optionally followed by a single result record, the result record being |
for the most recent command input. The sequence is terminated by |
``(gdb)''. |
|
Asynchronous @sc{gdb/mi} output is similar. |
|
Each output record directly associated with an input command is prefixed |
by the input commands @code{@var{token}}. |
|
@table @code |
@item @var{output} @expansion{} |
@{ @var{out-of-band-record} @} @code{[} @var{result-record} @code{]} "(gdb)" @var{nl} |
|
@item @var{result-record} @expansion{} |
@code{[} @var{token} @code{]} "^" @var{result-class} @{ "," @var{result} @} @var{nl} |
|
@item @var{out-of-band-record} @expansion{} |
@var{async-record} @code{|} @var{stream-record} |
|
@item @var{async-record} @expansion{} |
@var{exec-async-output} @code{|} @var{status-async-output} @code{|} @var{notify-async-output} |
|
@item @var{exec-async-output} @expansion{} |
@code{[} @var{token} @code{]} "*" @var{async-output} |
|
@item @var{status-async-output} @expansion{} |
@code{[} @var{token} @code{]} "+" @var{async-output} |
|
@item @var{notify-async-output} @expansion{} |
@code{[} @var{token} @code{]} "=" @var{async-output} |
|
@item @var{async-output} @expansion{} |
@var{async-class} @{ "," @var{result} @} @var{nl} |
|
@item @var{result-class} @expansion{} |
"done" @code{|} "running" @code{|} "connected" @code{|} "error" @code{|} "exit" |
|
@item @var{async-class} @expansion{} |
"stopped" @code{|} @emph{others depending on need as still in development} |
|
@item @var{result} @expansion{} |
@var{string} "=" @var{value} |
|
@item @var{value} @expansion{} |
@var{c-string} @code{|} @var{tupple} @code{|} @var{list} |
|
@item @var{tupple} @expansion{} |
"@{@}" @code{|} "@{" @var{result} @{ "," @var{result} @} "@}" |
|
@item @var{list} @expansion{} |
"@code{[]}" @code{|} "@code{[}" @var{value} @{ "," @var{value} @} "@code{]}" |
|
@item @var{string} @expansion{} |
@emph{[-A-Za-z\.0-9_]*} |
|
@item @var{c-string} @expansion{} |
@emph{See the input specification} |
|
@item @var{stream-record} @expansion{} |
@var{console-stream-output} @code{|} @var{target-stream-output} @code{|} @var{log-stream-output} |
|
@item @var{console-stream-output} @expansion{} |
"~" @var{c-string} |
|
@item @var{target-stream-output} @expansion{} |
"@@" @var{c-string} |
|
@item @var{log-stream-output} @expansion{} |
"&" @var{c-string} |
|
@item @var{nl} @expansion{} |
CR @code{|} CR-LF |
|
@item @var{token} @expansion{} |
"any sequence of digits" |
|
@end table |
|
In addition, the following are still being developed. |
|
@table @code |
|
@item @var{query} |
This action is currently undefined. |
|
@end table |
|
Notes: |
|
@itemize @bullet |
|
@item |
All output sequences end in a single line containing a period. |
|
@item |
The @code{@var{token}} is from the corresponding request. If an execution |
command is interrupted by the -exec-interrupt command, the token |
associated with the `*stopped' message is the one of the original |
execution command, not the one of the interrupt-command. |
|
@item |
@var{status-async-output} contains on-going status information about the progress |
of a slow operation. It can be discarded. All status output is prefixed by |
the prefix `+'. |
|
@item |
@var{exec-async-output} contains asynchronous state change on the target |
(stopped, started, disappeared). All async output is prefixed by |
the prefix `*'. |
|
@item |
@var{notify-async-output} contains supplementary information that the client should |
handle (new breakpoint information). All notify output is prefixed by |
the prefix `='. |
|
@item |
@var{console-stream-output} is output that should be displayed as is, in the |
console. It is the textual response to a CLI command. All the console |
output is prefixed by the prefix ``~''. |
|
@item |
@var{target-stream-output} is the output produced by the target program. |
All the target output is prefixed by the prefix ``@@''. |
|
@item |
@var{log-stream-output} is output text coming from GDB's internals, for |
instance messages that should be displayed as part of an error log. All |
the log output is prefixed by the prefix ``&''. |
|
@end itemize |
|
@c Local variables: |
@c change-log-default-name: "ChangeLog-mi" |
@c End: |
/mi-parse.c
0,0 → 1,243
/* MI Command Set - MI parser. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "mi-cmds.h" |
#include "mi-parse.h" |
|
#include <ctype.h> |
#include <string.h> |
|
#undef XMALLOC |
#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) |
|
static void |
mi_parse_argv (char *args, struct mi_parse *parse) |
{ |
char *chp = args; |
int argc = 0; |
char **argv = xmalloc ((argc + 1) * sizeof (char *)); |
argv[argc] = NULL; |
while (1) |
{ |
char *arg; |
/* skip leading white space */ |
while (isspace (*chp)) |
chp++; |
/* Three possibilities: EOF, quoted string, or other text. */ |
switch (*chp) |
{ |
case '\0': |
parse->argv = argv; |
parse->argc = argc; |
return; |
case '"': |
{ |
/* A quoted string. */ |
int len; |
char *start = chp + 1; |
/* Determine the buffer size. */ |
chp = start; |
len = 0; |
while (*chp != '\0' && *chp != '"') |
{ |
if (*chp == '\\') |
{ |
chp++; |
if (parse_escape (&chp) <= 0) |
{ |
/* Do not allow split lines or "\000" */ |
freeargv (argv); |
return; |
} |
} |
else |
chp++; |
len++; |
} |
/* Insist on a closing quote. */ |
if (*chp != '"') |
{ |
freeargv (argv); |
return; |
} |
/* Insist on trailing white space. */ |
if (chp[1] != '\0' && !isspace (chp[1])) |
{ |
freeargv (argv); |
return; |
} |
/* create the buffer. */ |
arg = xmalloc ((len + 1) * sizeof (char)); |
/* And copy the characters in. */ |
chp = start; |
len = 0; |
while (*chp != '\0' && *chp != '"') |
{ |
if (*chp == '\\') |
{ |
chp++; |
arg[len] = parse_escape (&chp); |
} |
else |
arg[len] = *chp++; |
len++; |
} |
arg[len] = '\0'; |
chp++; /* that closing quote. */ |
break; |
} |
default: |
{ |
/* An unquoted string. Accumulate all non blank |
characters into a buffer. */ |
int len; |
char *start = chp; |
while (*chp != '\0' && !isspace (*chp)) |
{ |
chp++; |
} |
len = chp - start; |
arg = xmalloc ((len + 1) * sizeof (char)); |
strncpy (arg, start, len); |
arg[len] = '\0'; |
break; |
} |
} |
/* Append arg to argv. */ |
argv = xrealloc (argv, (argc + 2) * sizeof (char *)); |
argv[argc++] = arg; |
argv[argc] = NULL; |
} |
} |
|
|
void |
mi_parse_free (struct mi_parse *parse) |
{ |
if (parse == NULL) |
return; |
if (parse->command != NULL) |
free (parse->command); |
if (parse->token != NULL) |
free (parse->token); |
if (parse->args != NULL) |
free (parse->args); |
if (parse->argv != NULL) |
freeargv (parse->argv); |
free (parse); |
} |
|
|
struct mi_parse * |
mi_parse (char *cmd) |
{ |
char *chp; |
struct mi_parse *parse = XMALLOC (struct mi_parse); |
memset (parse, 0, sizeof (*parse)); |
|
/* Before starting, skip leading white space. */ |
while (isspace (*cmd)) |
cmd++; |
|
/* Find/skip any token and then extract it. */ |
for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++) |
; |
parse->token = xmalloc ((chp - cmd + 1) * sizeof (char *)); |
memcpy (parse->token, cmd, (chp - cmd)); |
parse->token[chp - cmd] = '\0'; |
|
/* This wasn't a real MI command. Return it as a CLI_COMMAND. */ |
if (*chp != '-') |
{ |
while (isspace (*chp)) |
chp++; |
parse->command = xstrdup (chp); |
parse->op = CLI_COMMAND; |
return parse; |
} |
|
/* Extract the command. */ |
{ |
char *tmp = chp + 1; /* discard ``-'' */ |
for (; *chp && !isspace (*chp); chp++) |
; |
parse->command = xmalloc ((chp - tmp + 1) * sizeof (char *)); |
memcpy (parse->command, tmp, chp - tmp); |
parse->command[chp - tmp] = '\0'; |
} |
|
/* Find the command in the MI table. */ |
parse->cmd = mi_lookup (parse->command); |
if (parse->cmd == NULL) |
{ |
/* FIXME: This should be a function call. */ |
fprintf_unfiltered |
(raw_stdout, |
"%s^error,msg=\"Undefined MI command: %s\"\n", |
parse->token, parse->command); |
mi_parse_free (parse); |
return NULL; |
} |
|
/* Skip white space following the command. */ |
while (isspace (*chp)) |
chp++; |
|
/* For new argv commands, attempt to return the parsed argument |
list. */ |
if (parse->cmd->argv_func != NULL) |
{ |
mi_parse_argv (chp, parse); |
if (parse->argv == NULL) |
{ |
/* FIXME: This should be a function call. */ |
fprintf_unfiltered |
(raw_stdout, |
"%s^error,msg=\"Problem parsing arguments: %s %s\"\n", |
parse->token, parse->command, chp); |
mi_parse_free (parse); |
return NULL; |
} |
} |
|
/* FIXME: DELETE THIS */ |
/* For CLI and old ARGS commands, also return the remainder of the |
command line as a single string. */ |
if (parse->cmd->args_func != NULL |
|| parse->cmd->cli != NULL) |
{ |
parse->args = xstrdup (chp); |
} |
|
/* Fully parsed. */ |
parse->op = MI_COMMAND; |
return parse; |
} |
|
void |
_initialize_mi_parse () |
{ |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-out.h
0,0 → 1,39
/* MI Command Set - MI output generating routines for GDB. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#ifndef MI_OUT_H |
#define MI_OUT_H 1 |
|
#if __STDC__ |
struct ui_out; |
struct ui_file; |
#endif |
|
extern struct ui_out *mi_out_new (void); |
extern void mi_out_put (struct ui_out *uiout, struct ui_file *stream); |
extern void mi_out_rewind (struct ui_out *uiout); |
extern void mi_out_buffered (struct ui_out *uiout, char *string); |
|
#endif /* MI_OUT_H */ |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-parse.h
0,0 → 1,59
/* MI Command Set - MI Command Parser. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#ifndef MI_PARSE_H |
#define MI_PARSE_H |
|
/* MI parser */ |
|
enum mi_command_type |
{ |
MI_COMMAND, CLI_COMMAND |
}; |
|
struct mi_parse |
{ |
enum mi_command_type op; |
char *command; |
char *token; |
const struct mi_cmd *cmd; |
char *args; |
char **argv; |
int argc; |
}; |
|
/* Attempts to parse CMD returning a ``struct mi_command''. If CMD is |
invalid, an error mesage is reported (MI format) and NULL is |
returned. For a CLI_COMMAND, COMMAND, TOKEN and OP are initialized. |
For an MI_COMMAND COMMAND, TOKEN, ARGS and OP are |
initialized. Un-initialized fields are zero. */ |
|
extern struct mi_parse *mi_parse (char *cmd); |
|
/* Free a command returned by mi_parse_command. */ |
|
extern void mi_parse_free (struct mi_parse *cmd); |
|
#endif |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-main.c
0,0 → 1,1522
/* MI Command Set. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
/* Work in progress */ |
|
#include "defs.h" |
#include "target.h" |
#include "inferior.h" |
#include "gdb_string.h" |
#include "top.h" |
#include "gdbthread.h" |
#include "mi-cmds.h" |
#include "mi-parse.h" |
#include "mi-getopt.h" |
#include "mi-console.h" |
#include "ui-out.h" |
#include "mi-out.h" |
#include "event-loop.h" |
#include "event-top.h" |
#include "gdbcore.h" /* for write_memory() */ |
#include "value.h" /* for write_register_bytes() */ |
#include <ctype.h> |
#include <sys/time.h> |
|
/* Convenience macro for allocting typesafe memory. */ |
|
#undef XMALLOC |
#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) |
|
enum |
{ |
FROM_TTY = 0 |
}; |
|
|
int mi_debug_p; |
struct ui_file *raw_stdout; |
|
/* The token of the last asynchronous command */ |
static char *last_async_command; |
static char *previous_async_command; |
static char *mi_error_message; |
static char *old_regs; |
|
extern void _initialize_mi_main (void); |
static char *mi_input (char *); |
static void mi_execute_command (char *cmd, int from_tty); |
static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse); |
|
static void mi_execute_cli_command (const char *cli, char *args); |
static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty); |
static void mi_execute_command_wrapper (char *cmd); |
|
void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg); |
static void free_and_reset (char **arg); |
|
static int register_changed_p (int regnum); |
static int get_register (int regnum, int format); |
static void mi_load_progress (const char *section_name, |
unsigned long sent_so_far, |
unsigned long total_section, |
unsigned long total_sent, |
unsigned long grand_total); |
|
#ifdef UI_OUT |
/* FIXME: these should go in some .h file, but infcmd.c doesn't have a |
corresponding .h file. These wrappers will be obsolete anyway, once |
we pull the plug on the sanitization. */ |
extern void interrupt_target_command_wrapper (char *, int); |
extern void return_command_wrapper (char *, int); |
#endif |
|
/* Command implementations. FIXME: Is this libgdb? No. This is the MI |
layer that calls libgdb. Any operation used in the below should be |
formalized. */ |
|
enum mi_cmd_result |
mi_cmd_gdb_exit (char *command, char **argv, int argc) |
{ |
/* We have to print everything right here because we never return */ |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("^exit\n", raw_stdout); |
mi_out_put (uiout, raw_stdout); |
/* FIXME: The function called is not yet a formal libgdb function */ |
quit_force (NULL, FROM_TTY); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_exec_run (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("run", args, from_tty); |
} |
|
enum mi_cmd_result |
mi_cmd_exec_next (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("next", args, from_tty); |
} |
|
enum mi_cmd_result |
mi_cmd_exec_next_instruction (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("nexti", args, from_tty); |
} |
|
enum mi_cmd_result |
mi_cmd_exec_step (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("step", args, from_tty); |
} |
|
enum mi_cmd_result |
mi_cmd_exec_step_instruction (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("stepi", args, from_tty); |
} |
|
enum mi_cmd_result |
mi_cmd_exec_finish (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("finish", args, from_tty); |
} |
|
enum mi_cmd_result |
mi_cmd_exec_until (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("until", args, from_tty); |
} |
|
enum mi_cmd_result |
mi_cmd_exec_return (char *args, int from_tty) |
{ |
#ifdef UI_OUT |
/* This command doesn't really execute the target, it just pops the |
specified number of frames. */ |
if (*args) |
/* Call return_command with from_tty argument equal to 0 so as to |
avoid being queried. */ |
return_command_wrapper (args, 0); |
else |
/* Call return_command with from_tty argument equal to 0 so as to |
avoid being queried. */ |
return_command_wrapper (NULL, 0); |
|
/* Because we have called return_command with from_tty = 0, we need |
to print the frame here. */ |
show_and_print_stack_frame (selected_frame, |
selected_frame_level, |
LOC_AND_ADDRESS); |
#endif |
|
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_exec_continue (char *args, int from_tty) |
{ |
/* FIXME: Should call a libgdb function, not a cli wrapper */ |
return mi_execute_async_cli_command ("continue", args, from_tty); |
} |
|
/* Interrupt the execution of the target. Note how we must play around |
with the token varialbes, in order to display the current token in |
the result of the interrupt command, and the previous execution |
token when the target finally stops. See comments in |
mi_cmd_execute. */ |
enum mi_cmd_result |
mi_cmd_exec_interrupt (char *args, int from_tty) |
{ |
#ifdef UI_OUT |
if (!target_executing) |
{ |
asprintf (&mi_error_message, "mi_cmd_exec_interrupt: Inferior not executing."); |
return MI_CMD_ERROR; |
} |
interrupt_target_command_wrapper (args, from_tty); |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("^done", raw_stdout); |
free (last_async_command); |
if (previous_async_command) |
last_async_command = xstrdup (previous_async_command); |
free (previous_async_command); |
previous_async_command = NULL; |
mi_out_put (uiout, raw_stdout); |
mi_out_rewind (uiout); |
fputs_unfiltered ("\n", raw_stdout); |
#endif |
return MI_CMD_QUIET; |
} |
|
enum mi_cmd_result |
mi_cmd_thread_select (char *command, char **argv, int argc) |
{ |
enum gdb_rc rc; |
|
if (argc != 1) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_thread_select: USAGE: threadnum."); |
return MI_CMD_ERROR; |
} |
else |
rc = gdb_thread_select (argv[0]); |
|
if (rc == GDB_RC_FAIL) |
return MI_CMD_CAUGHT_ERROR; |
else |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_thread_list_ids (char *command, char **argv, int argc) |
{ |
enum gdb_rc rc = MI_CMD_DONE; |
|
if (argc != 0) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_thread_list_ids: No arguments required."); |
return MI_CMD_ERROR; |
} |
else |
#ifdef UI_OUT |
rc = gdb_list_thread_ids (); |
#endif |
|
if (rc == GDB_RC_FAIL) |
return MI_CMD_CAUGHT_ERROR; |
else |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_data_list_register_names (char *command, char **argv, int argc) |
{ |
int regnum, numregs; |
int i; |
|
/* Note that the test for a valid register must include checking the |
REGISTER_NAME because NUM_REGS may be allocated for the union of |
the register sets within a family of related processors. In this |
case, some entries of REGISTER_NAME will change depending upon |
the particular processor being debugged. */ |
|
numregs = ARCH_NUM_REGS; |
|
ui_out_list_begin (uiout, "register-names"); |
|
if (argc == 0) /* No args, just do all the regs */ |
{ |
for (regnum = 0; |
regnum < numregs; |
regnum++) |
{ |
if (REGISTER_NAME (regnum) == NULL |
|| *(REGISTER_NAME (regnum)) == '\0') |
continue; |
|
ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum)); |
} |
} |
|
/* Else, list of register #s, just do listed regs */ |
for (i = 0; i < argc; i++) |
{ |
regnum = atoi (argv[i]); |
|
if (regnum >= 0 |
&& regnum < numregs |
&& REGISTER_NAME (regnum) != NULL |
&& *REGISTER_NAME (regnum) != '\000') |
ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum)); |
else |
{ |
asprintf (&mi_error_message, "bad register number"); |
return MI_CMD_ERROR; |
} |
} |
ui_out_list_end (uiout); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) |
{ |
int regnum, numregs, changed; |
int i; |
|
/* Note that the test for a valid register must include checking the |
REGISTER_NAME because NUM_REGS may be allocated for the union of |
the register sets within a family of related processors. In this |
case, some entries of REGISTER_NAME will change depending upon |
the particular processor being debugged. */ |
|
numregs = ARCH_NUM_REGS; |
|
ui_out_list_begin (uiout, "changed-registers"); |
|
if (argc == 0) /* No args, just do all the regs */ |
{ |
for (regnum = 0; |
regnum < numregs; |
regnum++) |
{ |
if (REGISTER_NAME (regnum) == NULL |
|| *(REGISTER_NAME (regnum)) == '\0') |
continue; |
changed = register_changed_p (regnum); |
if (changed < 0) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_list_changed_registers: Unable to read register contents."); |
return MI_CMD_ERROR; |
} |
else if (changed) |
ui_out_field_int (uiout, NULL, regnum); |
} |
} |
|
/* Else, list of register #s, just do listed regs */ |
for (i = 0; i < argc; i++) |
{ |
regnum = atoi (argv[i]); |
|
if (regnum >= 0 |
&& regnum < numregs |
&& REGISTER_NAME (regnum) != NULL |
&& *REGISTER_NAME (regnum) != '\000') |
{ |
changed = register_changed_p (regnum); |
if (changed < 0) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_list_register_change: Unable to read register contents."); |
return MI_CMD_ERROR; |
} |
else if (changed) |
ui_out_field_int (uiout, NULL, regnum); |
} |
else |
{ |
asprintf (&mi_error_message, "bad register number"); |
return MI_CMD_ERROR; |
} |
} |
ui_out_list_end (uiout); |
return MI_CMD_DONE; |
} |
|
static int |
register_changed_p (int regnum) |
{ |
char raw_buffer[MAX_REGISTER_RAW_SIZE]; |
|
if (read_relative_register_raw_bytes (regnum, raw_buffer)) |
return -1; |
|
if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, |
REGISTER_RAW_SIZE (regnum)) == 0) |
return 0; |
|
/* Found a changed register. Return 1. */ |
|
memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, |
REGISTER_RAW_SIZE (regnum)); |
|
return 1; |
} |
|
/* Return a list of register number and value pairs. The valid |
arguments expected are: a letter indicating the format in which to |
display the registers contents. This can be one of: x (hexadecimal), d |
(decimal), N (natural), t (binary), o (octal), r (raw). After the |
format argumetn there can be a sequence of numbers, indicating which |
registers to fetch the content of. If the format is the only argument, |
a list of all the registers with their values is returned. */ |
enum mi_cmd_result |
mi_cmd_data_list_register_values (char *command, char **argv, int argc) |
{ |
int regnum, numregs, format, result; |
int i; |
|
/* Note that the test for a valid register must include checking the |
REGISTER_NAME because NUM_REGS may be allocated for the union of |
the register sets within a family of related processors. In this |
case, some entries of REGISTER_NAME will change depending upon |
the particular processor being debugged. */ |
|
numregs = ARCH_NUM_REGS; |
|
if (argc == 0) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]"); |
return MI_CMD_ERROR; |
} |
|
format = (int) argv[0][0]; |
|
if (!target_has_registers) |
{ |
asprintf (&mi_error_message, "mi_cmd_data_list_register_values: No registers."); |
return MI_CMD_ERROR; |
} |
|
ui_out_list_begin (uiout, "register-values"); |
|
if (argc == 1) /* No args, beside the format: do all the regs */ |
{ |
for (regnum = 0; |
regnum < numregs; |
regnum++) |
{ |
if (REGISTER_NAME (regnum) == NULL |
|| *(REGISTER_NAME (regnum)) == '\0') |
continue; |
ui_out_list_begin (uiout, NULL); |
ui_out_field_int (uiout, "number", regnum); |
result = get_register (regnum, format); |
if (result == -1) |
return MI_CMD_ERROR; |
ui_out_list_end (uiout); |
} |
} |
|
/* Else, list of register #s, just do listed regs */ |
for (i = 1; i < argc; i++) |
{ |
regnum = atoi (argv[i]); |
|
if (regnum >= 0 |
&& regnum < numregs |
&& REGISTER_NAME (regnum) != NULL |
&& *REGISTER_NAME (regnum) != '\000') |
{ |
ui_out_list_begin (uiout, NULL); |
ui_out_field_int (uiout, "number", regnum); |
result = get_register (regnum, format); |
if (result == -1) |
return MI_CMD_ERROR; |
ui_out_list_end (uiout); |
} |
else |
{ |
asprintf (&mi_error_message, "bad register number"); |
return MI_CMD_ERROR; |
} |
} |
ui_out_list_end (uiout); |
return MI_CMD_DONE; |
} |
|
/* Output one register's contents in the desired format. */ |
static int |
get_register (int regnum, int format) |
{ |
char raw_buffer[MAX_REGISTER_RAW_SIZE]; |
char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; |
int optim; |
static struct ui_stream *stb = NULL; |
|
stb = ui_out_stream_new (uiout); |
|
if (format == 'N') |
format = 0; |
|
/* read_relative_register_raw_bytes returns a virtual frame pointer |
(FRAME_FP (selected_frame)) if regnum == FP_REGNUM instead |
of the real contents of the register. To get around this, |
use get_saved_register instead. */ |
get_saved_register (raw_buffer, &optim, (CORE_ADDR *) NULL, selected_frame, |
regnum, (enum lval_type *) NULL); |
if (optim) |
{ |
asprintf (&mi_error_message, "Optimized out"); |
return -1; |
} |
|
/* Convert raw data to virtual format if necessary. */ |
|
if (REGISTER_CONVERTIBLE (regnum)) |
{ |
REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), |
raw_buffer, virtual_buffer); |
} |
else |
memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum)); |
|
if (format == 'r') |
{ |
int j; |
char *ptr, buf[1024]; |
|
strcpy (buf, "0x"); |
ptr = buf + 2; |
for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++) |
{ |
register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j |
: REGISTER_RAW_SIZE (regnum) - 1 - j; |
sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]); |
ptr += 2; |
} |
ui_out_field_string (uiout, "value", buf); |
/*fputs_filtered (buf, gdb_stdout); */ |
} |
else |
{ |
val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, 0, |
stb->stream, format, 1, 0, Val_pretty_default); |
ui_out_field_stream (uiout, "value", stb); |
ui_out_stream_delete (stb); |
} |
return 1; |
} |
|
/* Write given values into registers. The registers and values are |
given as pairs. The corresponding MI command is |
-data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/ |
enum mi_cmd_result |
mi_cmd_data_write_register_values (char *command, char **argv, int argc) |
{ |
int regnum; |
int i; |
int numregs; |
char *buffer; |
LONGEST value; |
char format; |
|
/* Note that the test for a valid register must include checking the |
REGISTER_NAME because NUM_REGS may be allocated for the union of |
the register sets within a family of related processors. In this |
case, some entries of REGISTER_NAME will change depending upon |
the particular processor being debugged. */ |
|
numregs = ARCH_NUM_REGS; |
|
if (argc == 0) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]"); |
return MI_CMD_ERROR; |
} |
|
format = (int) argv[0][0]; |
|
if (!target_has_registers) |
{ |
asprintf (&mi_error_message, "mi_cmd_data_write_register_values: No registers."); |
return MI_CMD_ERROR; |
} |
|
if (!(argc - 1)) |
{ |
asprintf (&mi_error_message, "mi_cmd_data_write_register_values: No regs and values specified."); |
return MI_CMD_ERROR; |
} |
|
if ((argc - 1) % 2) |
{ |
asprintf (&mi_error_message, "mi_cmd_data_write_register_values: Regs and vals are not in pairs."); |
return MI_CMD_ERROR; |
} |
|
for (i = 1; i < argc; i = i + 2) |
{ |
regnum = atoi (argv[i]); |
|
if (regnum >= 0 |
&& regnum < numregs |
&& REGISTER_NAME (regnum) != NULL |
&& *REGISTER_NAME (regnum) != '\000') |
{ |
/* Get the value as a number */ |
value = parse_and_eval_address (argv[i + 1]); |
/* Get the value into an array */ |
buffer = (unsigned char *) xmalloc (REGISTER_SIZE); |
store_signed_integer (buffer, REGISTER_SIZE, value); |
/* Write it down */ |
write_register_bytes (REGISTER_BYTE (regnum), buffer, REGISTER_RAW_SIZE (regnum)); |
/* write_register_bytes (REGISTER_BYTE (regnum), buffer, REGISTER_SIZE); */ |
} |
else |
{ |
asprintf (&mi_error_message, "bad register number"); |
return MI_CMD_ERROR; |
} |
} |
return MI_CMD_DONE; |
} |
|
#if 0 |
/*This is commented out because we decided it was not useful. I leave |
it, just in case. ezannoni:1999-12-08 */ |
|
/* Assign a value to a variable. The expression argument must be in |
the form A=2 or "A = 2" (I.e. if there are spaces it needs to be |
quoted. */ |
enum mi_cmd_result |
mi_cmd_data_assign (char *command, char **argv, int argc) |
{ |
struct expression *expr; |
struct cleanup *old_chain; |
|
if (argc != 1) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_assign: Usage: -data-assign expression"); |
return MI_CMD_ERROR; |
} |
|
/* NOTE what follows is a clone of set_command(). FIXME: ezannoni |
01-12-1999: Need to decide what to do with this for libgdb purposes. */ |
|
expr = parse_expression (argv[0]); |
old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr); |
evaluate_expression (expr); |
do_cleanups (old_chain); |
return MI_CMD_DONE; |
} |
#endif |
|
/* Evaluate the value of the argument. The argument is an |
expression. If the expression contains spaces it needs to be |
included in double quotes. */ |
enum mi_cmd_result |
mi_cmd_data_evaluate_expression (char *command, char **argv, int argc) |
{ |
struct expression *expr; |
struct cleanup *old_chain = NULL; |
value_ptr val; |
struct ui_stream *stb = NULL; |
|
stb = ui_out_stream_new (uiout); |
|
if (argc != 1) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_evaluate_expression: Usage: -data-evaluate-expression expression"); |
return MI_CMD_ERROR; |
} |
|
expr = parse_expression (argv[0]); |
|
old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr); |
|
val = evaluate_expression (expr); |
|
/* Print the result of the expression evaluation. */ |
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), |
VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), |
stb->stream, 0, 0, 0, 0); |
|
ui_out_field_stream (uiout, "value", stb); |
ui_out_stream_delete (stb); |
|
do_cleanups (old_chain); |
|
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_target_download (char *args, int from_tty) |
{ |
char *run; |
struct cleanup *old_cleanups = NULL; |
|
asprintf (&run, "load %s", args); |
if (run == 0) |
internal_error ("mi_cmd_target_download: no memory"); |
old_cleanups = make_cleanup (free, run); |
execute_command (run, from_tty); |
|
do_cleanups (old_cleanups); |
return MI_CMD_DONE; |
} |
|
/* Connect to the remote target. */ |
enum mi_cmd_result |
mi_cmd_target_select (char *args, int from_tty) |
{ |
char *run; |
struct cleanup *old_cleanups = NULL; |
|
asprintf (&run, "target %s", args); |
if (run == 0) |
internal_error ("mi_cmd_target_select: no memory"); |
old_cleanups = make_cleanup (free, run); |
|
/* target-select is always synchronous. once the call has returned |
we know that we are connected. */ |
/* NOTE: At present all targets that are connected are also |
(implicitly) talking to a halted target. In the future this may |
change. */ |
execute_command (run, from_tty); |
|
do_cleanups (old_cleanups); |
|
/* Issue the completion message here. */ |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("^connected", raw_stdout); |
mi_out_put (uiout, raw_stdout); |
mi_out_rewind (uiout); |
fputs_unfiltered ("\n", raw_stdout); |
do_exec_cleanups (ALL_CLEANUPS); |
return MI_CMD_QUIET; |
} |
|
/* DATA-MEMORY-READ: |
|
ADDR: start address of data to be dumped. |
WORD-FORMAT: a char indicating format for the ``word''. See |
the ``x'' command. |
WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes |
NR_ROW: Number of rows. |
NR_COL: The number of colums (words per row). |
ASCHAR: (OPTIONAL) Append an ascii character dump to each row. Use |
ASCHAR for unprintable characters. |
|
Reads SIZE*NR_ROW*NR_COL bytes starting at ADDR from memory and |
displayes them. Returns: |
|
{addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...} |
|
Returns: |
The number of bytes read is SIZE*ROW*COL. */ |
|
enum mi_cmd_result |
mi_cmd_data_read_memory (char *command, char **argv, int argc) |
{ |
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); |
CORE_ADDR addr; |
long total_bytes; |
long nr_cols; |
long nr_rows; |
char word_format; |
struct type *word_type; |
long word_size; |
char word_asize; |
char aschar; |
char *mbuf; |
int nr_bytes; |
long offset = 0; |
int optind = 0; |
char *optarg; |
enum opt |
{ |
OFFSET_OPT |
}; |
static struct mi_opt opts[] = |
{ |
{"o", OFFSET_OPT, 1}, |
0 |
}; |
|
while (1) |
{ |
int opt = mi_getopt ("mi_cmd_data_read_memory", argc, argv, opts, |
&optind, &optarg); |
if (opt < 0) |
break; |
switch ((enum opt) opt) |
{ |
case OFFSET_OPT: |
offset = atol (optarg); |
break; |
} |
} |
argv += optind; |
argc -= optind; |
|
if (argc < 5 || argc > 6) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR]."); |
return MI_CMD_ERROR; |
} |
|
/* Extract all the arguments. */ |
|
/* Start address of the memory dump. */ |
addr = parse_and_eval_address (argv[0]) + offset; |
/* The format character to use when displaying a memory word. See |
the ``x'' command. */ |
word_format = argv[1][0]; |
/* The size of the memory word. */ |
word_size = atol (argv[2]); |
switch (word_size) |
{ |
case 1: |
word_type = builtin_type_int8; |
word_asize = 'b'; |
break; |
case 2: |
word_type = builtin_type_int16; |
word_asize = 'h'; |
break; |
case 4: |
word_type = builtin_type_int32; |
word_asize = 'w'; |
break; |
case 8: |
word_type = builtin_type_int64; |
word_asize = 'g'; |
break; |
default: |
word_type = builtin_type_int8; |
word_asize = 'b'; |
} |
/* The number of rows */ |
nr_rows = atol (argv[3]); |
if (nr_rows <= 0) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_read_memory: invalid number of rows."); |
return MI_CMD_ERROR; |
} |
/* number of bytes per row. */ |
nr_cols = atol (argv[4]); |
if (nr_cols <= 0) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_read_memory: invalid number of columns."); |
} |
/* The un-printable character when printing ascii. */ |
if (argc == 6) |
aschar = *argv[5]; |
else |
aschar = 0; |
|
/* create a buffer and read it in. */ |
total_bytes = word_size * nr_rows * nr_cols; |
mbuf = calloc (total_bytes, 1); |
make_cleanup (free, mbuf); |
if (mbuf == NULL) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_read_memory: out of memory."); |
return MI_CMD_ERROR; |
} |
nr_bytes = 0; |
while (nr_bytes < total_bytes) |
{ |
int error; |
long num = target_read_memory_partial (addr + nr_bytes, mbuf + nr_bytes, |
total_bytes - nr_bytes, |
&error); |
if (num <= 0) |
break; |
nr_bytes += num; |
} |
|
/* output the header information. */ |
ui_out_field_core_addr (uiout, "addr", addr); |
ui_out_field_int (uiout, "nr-bytes", nr_bytes); |
ui_out_field_int (uiout, "total-bytes", total_bytes); |
ui_out_field_core_addr (uiout, "next-row", addr + word_size * nr_cols); |
ui_out_field_core_addr (uiout, "prev-row", addr - word_size * nr_cols); |
ui_out_field_core_addr (uiout, "next-page", addr + total_bytes); |
ui_out_field_core_addr (uiout, "prev-page", addr - total_bytes); |
|
/* Build the result as a two dimentional table. */ |
{ |
struct ui_stream *stream = ui_out_stream_new (uiout); |
int row; |
int row_byte; |
ui_out_list_begin (uiout, "memory"); |
for (row = 0, row_byte = 0; |
row < nr_rows; |
row++, row_byte += nr_cols * word_size) |
{ |
int col; |
int col_byte; |
ui_out_list_begin (uiout, NULL); |
ui_out_field_core_addr (uiout, "addr", addr + row_byte); |
/* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */ |
ui_out_list_begin (uiout, "data"); |
for (col = 0, col_byte = row_byte; |
col < nr_cols; |
col++, col_byte += word_size) |
{ |
if (col_byte + word_size > nr_bytes) |
{ |
ui_out_field_string (uiout, NULL, "N/A"); |
} |
else |
{ |
ui_file_rewind (stream->stream); |
print_scalar_formatted (mbuf + col_byte, word_type, word_format, |
word_asize, stream->stream); |
ui_out_field_stream (uiout, NULL, stream); |
} |
} |
ui_out_list_end (uiout); |
if (aschar) |
{ |
int byte; |
ui_file_rewind (stream->stream); |
for (byte = row_byte; byte < row_byte + word_size * nr_cols; byte++) |
{ |
if (byte >= nr_bytes) |
{ |
fputc_unfiltered ('X', stream->stream); |
} |
else if (mbuf[byte] < 32 || mbuf[byte] > 126) |
{ |
fputc_unfiltered (aschar, stream->stream); |
} |
else |
fputc_unfiltered (mbuf[byte], stream->stream); |
} |
ui_out_field_stream (uiout, "ascii", stream); |
} |
ui_out_list_end (uiout); |
} |
ui_out_stream_delete (stream); |
ui_out_list_end (uiout); |
} |
do_cleanups (cleanups); |
return MI_CMD_DONE; |
} |
|
/* DATA-MEMORY-WRITE: |
|
COLUMN_OFFSET: optional argument. Must be preceeded by '-o'. The |
offset from the beginning of the memory grid row where the cell to |
be written is. |
ADDR: start address of the row in the memory grid where the memory |
cell is, if OFFSET_COLUMN is specified. Otherwise, the address of |
the location to write to. |
FORMAT: a char indicating format for the ``word''. See |
the ``x'' command. |
WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes |
VALUE: value to be written into the memory address. |
|
Writes VALUE into ADDR + (COLUMN_OFFSET * WORD_SIZE). |
|
Prints nothing. */ |
enum mi_cmd_result |
mi_cmd_data_write_memory (char *command, char **argv, int argc) |
{ |
CORE_ADDR addr; |
char word_format; |
long word_size; |
/* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big |
enough when using a compiler other than GCC. */ |
LONGEST value; |
unsigned char *buffer; |
long offset = 0; |
int optind = 0; |
char *optarg; |
enum opt |
{ |
OFFSET_OPT |
}; |
static struct mi_opt opts[] = |
{ |
{"o", OFFSET_OPT, 1}, |
0 |
}; |
|
while (1) |
{ |
int opt = mi_getopt ("mi_cmd_data_write_memory", argc, argv, opts, |
&optind, &optarg); |
if (opt < 0) |
break; |
switch ((enum opt) opt) |
{ |
case OFFSET_OPT: |
offset = atol (optarg); |
break; |
} |
} |
argv += optind; |
argc -= optind; |
|
if (argc != 4) |
{ |
asprintf (&mi_error_message, |
"mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE."); |
return MI_CMD_ERROR; |
} |
|
/* Extract all the arguments. */ |
/* Start address of the memory dump. */ |
addr = parse_and_eval_address (argv[0]); |
/* The format character to use when displaying a memory word. See |
the ``x'' command. */ |
word_format = argv[1][0]; |
/* The size of the memory word. */ |
word_size = atol (argv[2]); |
|
/* Calculate the real address of the write destination. */ |
addr += (offset * word_size); |
|
/* Get the value as a number */ |
value = parse_and_eval_address (argv[3]); |
/* Get the value into an array */ |
buffer = (unsigned char *) xmalloc (word_size); |
store_signed_integer (buffer, word_size, value); |
/* Write it down to memory */ |
write_memory (addr, buffer, word_size); |
|
return MI_CMD_DONE; |
} |
|
/* Execute a command within a safe environment. Return >0 for |
ok. Return <0 for supress prompt. Return 0 to have the error |
extracted from error_last_message(). */ |
|
static int |
captured_mi_execute_command (void *data) |
{ |
struct mi_parse *context = data; |
enum mi_cmd_result rc; |
|
switch (context->op) |
{ |
|
case MI_COMMAND: |
/* A MI command was read from the input stream */ |
if (mi_debug_p) |
/* FIXME: gdb_???? */ |
fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n", |
context->token, context->command, context->args); |
/* FIXME: cagney/1999-09-25: Rather than this convoluted |
condition expression, each function should return an |
indication of what action is required and then switch on |
that. */ |
rc = mi_cmd_execute (context); |
if (!target_can_async_p () || !target_executing) |
{ |
/* print the result if there were no errors */ |
if (rc == MI_CMD_DONE) |
{ |
fputs_unfiltered (context->token, raw_stdout); |
fputs_unfiltered ("^done", raw_stdout); |
mi_out_put (uiout, raw_stdout); |
mi_out_rewind (uiout); |
fputs_unfiltered ("\n", raw_stdout); |
} |
else if (rc == MI_CMD_ERROR) |
{ |
if (mi_error_message) |
{ |
fputs_unfiltered (context->token, raw_stdout); |
fputs_unfiltered ("^error,msg=\"", raw_stdout); |
fputstr_unfiltered (mi_error_message, '"', raw_stdout); |
free (mi_error_message); |
fputs_unfiltered ("\"\n", raw_stdout); |
} |
mi_out_rewind (uiout); |
} |
else if (rc == MI_CMD_CAUGHT_ERROR) |
{ |
mi_out_rewind (uiout); |
return 0; |
} |
else |
mi_out_rewind (uiout); |
} |
else if (sync_execution) |
/* Don't print the prompt. We are executing the target in |
synchronous mode. */ |
return -1; |
break; |
|
case CLI_COMMAND: |
/* A CLI command was read from the input stream */ |
/* This will be removed as soon as we have a complete set of |
mi commands */ |
/* echo the command on the console. */ |
fprintf_unfiltered (gdb_stdlog, "%s\n", context->command); |
/* FIXME: If the command string has something that looks like |
a format spec (e.g. %s) we will get a core dump */ |
mi_execute_cli_command ("%s", context->command); |
/* print the result */ |
/* FIXME: Check for errors here. */ |
fputs_unfiltered (context->token, raw_stdout); |
fputs_unfiltered ("^done", raw_stdout); |
mi_out_put (uiout, raw_stdout); |
mi_out_rewind (uiout); |
fputs_unfiltered ("\n", raw_stdout); |
break; |
|
} |
return 1; |
} |
|
|
void |
mi_execute_command (char *cmd, int from_tty) |
{ |
struct mi_parse *command; |
|
/* This is to handle EOF (^D). We just quit gdb. */ |
/* FIXME: we should call some API function here. */ |
if (cmd == 0) |
quit_force (NULL, from_tty); |
|
command = mi_parse (cmd); |
|
if (command != NULL) |
{ |
/* FIXME: cagney/1999-11-04: Can this use of catch_errors either |
be pushed even further down or even eliminated? */ |
int rc = catch_errors (captured_mi_execute_command, command, "", |
RETURN_MASK_ALL); |
if (rc < 0) |
{ |
/* The command is executing synchronously. Bail out early |
suppressing the finished prompt. */ |
mi_parse_free (command); |
return; |
} |
if (rc == 0) |
{ |
char *msg = error_last_message (); |
struct cleanup *cleanup = make_cleanup (free, msg); |
/* The command execution failed and error() was called |
somewhere */ |
fputs_unfiltered (command->token, raw_stdout); |
fputs_unfiltered ("^error,msg=\"", raw_stdout); |
fputstr_unfiltered (msg, '"', raw_stdout); |
fputs_unfiltered ("\"\n", raw_stdout); |
} |
mi_parse_free (command); |
} |
|
gdb_flush (raw_stdout); |
fputs_unfiltered ("(gdb) \n", raw_stdout); |
/* print any buffered hook code */ |
/* ..... */ |
} |
|
static enum mi_cmd_result |
mi_cmd_execute (struct mi_parse *parse) |
{ |
if (parse->cmd->argv_func != NULL |
|| parse->cmd->args_func != NULL) |
{ |
/* FIXME: We need to save the token because the command executed |
may be asynchronous and need to print the token again. |
In the future we can pass the token down to the func |
and get rid of the last_async_command */ |
/* The problem here is to keep the token around when we launch |
the target, and we want to interrupt it later on. The |
interrupt command will have its own token, but when the |
target stops, we must display the token corresponding to the |
last execution command given. So we have another string where |
we copy the token (previous_async_command), if this was |
indeed the token of an execution command, and when we stop we |
print that one. This is possible because the interrupt |
command, when over, will copy that token back into the |
default token string (last_async_command). */ |
|
if (target_executing) |
{ |
if (!previous_async_command) |
previous_async_command = xstrdup (last_async_command); |
if (strcmp (parse->command, "exec-interrupt")) |
{ |
fputs_unfiltered (parse->token, raw_stdout); |
fputs_unfiltered ("^error,msg=\"", raw_stdout); |
fputs_unfiltered ("Cannot execute command ", raw_stdout); |
fputstr_unfiltered (parse->command, '"', raw_stdout); |
fputs_unfiltered (" while target running", raw_stdout); |
fputs_unfiltered ("\"\n", raw_stdout); |
return MI_CMD_ERROR; |
} |
} |
last_async_command = xstrdup (parse->token); |
make_exec_cleanup ((make_cleanup_func) free_and_reset, &last_async_command); |
/* FIXME: DELETE THIS! */ |
if (parse->cmd->args_func != NULL) |
return parse->cmd->args_func (parse->args, 0 /*from_tty */ ); |
return parse->cmd->argv_func (parse->command, parse->argv, parse->argc); |
} |
else if (parse->cmd->cli != 0) |
{ |
/* FIXME: DELETE THIS. */ |
/* The operation is still implemented by a cli command */ |
/* Must be a synchronous one */ |
mi_execute_cli_command (parse->cmd->cli, parse->args); |
return MI_CMD_DONE; |
} |
else |
{ |
/* FIXME: DELETE THIS. */ |
fputs_unfiltered (parse->token, raw_stdout); |
fputs_unfiltered ("^error,msg=\"", raw_stdout); |
fputs_unfiltered ("Undefined mi command: ", raw_stdout); |
fputstr_unfiltered (parse->command, '"', raw_stdout); |
fputs_unfiltered (" (missing implementation)", raw_stdout); |
fputs_unfiltered ("\"\n", raw_stdout); |
return MI_CMD_ERROR; |
} |
} |
|
void |
free_and_reset (char **arg) |
{ |
free (*arg); |
*arg = NULL; |
} |
|
static void |
mi_execute_command_wrapper (char *cmd) |
{ |
mi_execute_command (cmd, stdin == instream); |
} |
|
/* FIXME: This is just a hack so we can get some extra commands going. |
We don't want to channel things through the CLI, but call libgdb directly */ |
/* Use only for synchronous commands */ |
|
void |
mi_execute_cli_command (const char *cli, char *args) |
{ |
if (cli != 0) |
{ |
struct cleanup *old_cleanups; |
char *run; |
asprintf (&run, cli, args); |
if (mi_debug_p) |
/* FIXME: gdb_???? */ |
fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n", |
cli, run); |
if (run == 0) |
abort (); |
old_cleanups = make_cleanup (free, run); |
execute_command ( /*ui */ run, 0 /*from_tty */ ); |
do_cleanups (old_cleanups); |
return; |
} |
} |
|
enum mi_cmd_result |
mi_execute_async_cli_command (char *mi, char *args, int from_tty) |
{ |
struct cleanup *old_cleanups; |
char *run; |
char *async_args; |
|
if (target_can_async_p ()) |
{ |
async_args = (char *) xmalloc (strlen (args) + 2); |
make_exec_cleanup (free, async_args); |
strcpy (async_args, args); |
strcat (async_args, "&"); |
asprintf (&run, "%s %s", mi, async_args); |
if (run == 0) |
internal_error ("mi_execute_async_cli_command: no memory"); |
make_exec_cleanup (free, run); |
add_continuation (mi_exec_async_cli_cmd_continuation, NULL); |
} |
else |
{ |
asprintf (&run, "%s %s", mi, args); |
if (run == 0) |
internal_error ("mi_execute_async_cli_command: no memory"); |
old_cleanups = make_cleanup (free, run); |
} |
|
if (!target_can_async_p ()) |
{ |
/* NOTE: For synchronous targets asynchronous behavour is faked by |
printing out the GDB prompt before we even try to execute the |
command. */ |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("^running\n", raw_stdout); |
fputs_unfiltered ("(gdb) \n", raw_stdout); |
} |
else |
{ |
/* FIXME: cagney/1999-11-29: Printing this message before |
calling execute_command is wrong. It should only be printed |
once gdb has confirmed that it really has managed to send a |
run command to the target. */ |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("^running\n", raw_stdout); |
} |
|
execute_command ( /*ui */ run, 0 /*from_tty */ ); |
|
if (!target_can_async_p ()) |
{ |
/* Do this before doing any printing. It would appear that some |
print code leaves garbage around in the buffer. */ |
do_cleanups (old_cleanups); |
/* If the target was doing the operation synchronously we fake |
the stopped message. */ |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("*stopped", raw_stdout); |
mi_out_put (uiout, raw_stdout); |
mi_out_rewind (uiout); |
fputs_unfiltered ("\n", raw_stdout); |
return MI_CMD_QUIET; |
} |
return MI_CMD_DONE; |
} |
|
void |
mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg) |
{ |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("*stopped", raw_stdout); |
mi_out_put (uiout, raw_stdout); |
fputs_unfiltered ("\n", raw_stdout); |
fputs_unfiltered ("(gdb) \n", raw_stdout); |
do_exec_cleanups (ALL_CLEANUPS); |
} |
|
static char * |
mi_input (char *buf) |
{ |
return gdb_readline (NULL); |
} |
|
static void |
mi_load_progress (const char *section_name, |
unsigned long sent_so_far, |
unsigned long total_section, |
unsigned long total_sent, |
unsigned long grand_total) |
{ |
struct timeval time_now, delta, update_threshold; |
static struct timeval last_update; |
static char *previous_sect_name = NULL; |
int new_section; |
|
if (!interpreter_p || strcmp (interpreter_p, "mi") != 0) |
return; |
|
update_threshold.tv_sec = 0; |
update_threshold.tv_usec = 500000; |
gettimeofday (&time_now, NULL); |
|
delta.tv_usec = time_now.tv_usec - last_update.tv_usec; |
delta.tv_sec = time_now.tv_sec - last_update.tv_sec; |
|
if (delta.tv_usec < 0) |
{ |
delta.tv_sec -= 1; |
delta.tv_usec += 1000000; |
} |
|
new_section = (previous_sect_name ? |
strcmp (previous_sect_name, section_name) : 1); |
if (new_section) |
{ |
free (previous_sect_name); |
previous_sect_name = xstrdup (section_name); |
|
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("+download", raw_stdout); |
ui_out_list_begin (uiout, NULL); |
ui_out_field_string (uiout, "section", section_name); |
ui_out_field_int (uiout, "section-size", total_section); |
ui_out_field_int (uiout, "total-size", grand_total); |
ui_out_list_end (uiout); |
mi_out_put (uiout, raw_stdout); |
fputs_unfiltered ("\n", raw_stdout); |
gdb_flush (raw_stdout); |
} |
|
if (delta.tv_sec >= update_threshold.tv_sec && |
delta.tv_usec >= update_threshold.tv_usec) |
{ |
last_update.tv_sec = time_now.tv_sec; |
last_update.tv_usec = time_now.tv_usec; |
if (last_async_command) |
fputs_unfiltered (last_async_command, raw_stdout); |
fputs_unfiltered ("+download", raw_stdout); |
ui_out_list_begin (uiout, NULL); |
ui_out_field_string (uiout, "section", section_name); |
ui_out_field_int (uiout, "section-sent", sent_so_far); |
ui_out_field_int (uiout, "section-size", total_section); |
ui_out_field_int (uiout, "total-sent", total_sent); |
ui_out_field_int (uiout, "total-size", grand_total); |
ui_out_list_end (uiout); |
mi_out_put (uiout, raw_stdout); |
fputs_unfiltered ("\n", raw_stdout); |
gdb_flush (raw_stdout); |
} |
} |
|
static void |
mi_command_loop () |
{ |
/* HACK: Force stdout/stderr to point at the console. This avoids |
any potential side effects caused by legacy code that is still |
using the TUI / fputs_unfiltered_hook */ |
raw_stdout = stdio_fileopen (stdout); |
/* Route normal output through the MIx */ |
gdb_stdout = mi_console_file_new (raw_stdout, "~"); |
/* Route error and log output through the MI */ |
gdb_stderr = mi_console_file_new (raw_stdout, "&"); |
gdb_stdlog = gdb_stderr; |
/* Route target output through the MI. */ |
gdb_stdtarg = mi_console_file_new (raw_stdout, "@"); |
|
/* HACK: Poke the ui_out table directly. Should we be creating a |
mi_out object wired up to the above gdb_stdout / gdb_stderr? */ |
uiout = mi_out_new (); |
|
/* HACK: Override any other interpreter hooks. We need to create a |
real event table and pass in that. */ |
init_ui_hook = 0; |
/* command_loop_hook = 0; */ |
print_frame_info_listing_hook = 0; |
query_hook = 0; |
warning_hook = 0; |
create_breakpoint_hook = 0; |
delete_breakpoint_hook = 0; |
modify_breakpoint_hook = 0; |
interactive_hook = 0; |
registers_changed_hook = 0; |
readline_begin_hook = 0; |
readline_hook = 0; |
readline_end_hook = 0; |
register_changed_hook = 0; |
memory_changed_hook = 0; |
context_hook = 0; |
target_wait_hook = 0; |
call_command_hook = 0; |
error_hook = 0; |
error_begin_hook = 0; |
show_load_progress = mi_load_progress; |
|
/* Turn off 8 bit strings in quoted output. Any character with the |
high bit set is printed using C's octal format. */ |
sevenbit_strings = 1; |
|
/* Tell the world that we're alive */ |
fputs_unfiltered ("(gdb) \n", raw_stdout); |
|
if (!event_loop_p) |
simplified_command_loop (mi_input, mi_execute_command); |
else |
start_event_loop (); |
} |
|
static void |
setup_architecture_data () |
{ |
/* don't trust REGISTER_BYTES to be zero. */ |
old_regs = xmalloc (REGISTER_BYTES + 1); |
memset (old_regs, 0, REGISTER_BYTES + 1); |
} |
|
static void |
mi_init_ui (arg0) |
char *arg0; |
{ |
/* Eventually this will contain code that takes control of the |
console. */ |
} |
|
void |
_initialize_mi_main () |
{ |
/* If we're _the_ interpreter, take control. */ |
if (interpreter_p |
&& strcmp (interpreter_p, "mi") == 0) |
{ |
init_ui_hook = mi_init_ui; |
command_loop_hook = mi_command_loop; |
setup_architecture_data (); |
register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL); |
register_gdbarch_swap (NULL, 0, setup_architecture_data); |
if (event_loop_p) |
{ |
/* These overwrite some of the initialization done in |
_intialize_event_loop. */ |
call_readline = gdb_readline2; |
input_handler = mi_execute_command_wrapper; |
add_file_handler (input_fd, stdin_event_handler, 0); |
async_command_editing_p = 0; |
} |
} |
/* FIXME: Should we notify main that we are here as a possible |
interpreter? */ |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-cmd-break.c
0,0 → 1,253
/* MI Command Set - breakpoint and watchpoint commands. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "mi-cmds.h" |
#include "ui-out.h" |
#include "mi-out.h" |
#include "breakpoint.h" |
#include "gdb_string.h" |
#include "mi-getopt.h" |
#include "gdb-events.h" |
|
/* Convenience macro for allocting typesafe memory. */ |
|
#undef XMALLOC |
#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) |
|
enum |
{ |
FROM_TTY = 0 |
}; |
|
/* Output a single breakpoint. */ |
|
static void |
breakpoint_notify (int b) |
{ |
gdb_breakpoint_query (b); |
} |
|
|
struct gdb_events breakpoint_hooks = |
{ |
breakpoint_notify, |
breakpoint_notify, |
breakpoint_notify, |
}; |
|
|
enum bp_type |
{ |
REG_BP, |
HW_BP, |
REGEXP_BP |
}; |
|
/* Insert a breakpoint. The type of breakpoint is specified by the |
first argument: -break-insert <location> --> insert a regular |
breakpoint. -break-insert -t <location> --> insert a temporary |
breakpoint. -break-insert -h <location> --> insert an hardware |
breakpoint. -break-insert -t -h <location> --> insert a temporary |
hw bp. |
-break-insert -r <regexp> --> insert a bp at functions matching |
<regexp> */ |
|
enum mi_cmd_result |
mi_cmd_break_insert (char *command, char **argv, int argc) |
{ |
char *address = NULL; |
enum bp_type type = REG_BP; |
int temp_p = 0; |
int thread = -1; |
int ignore_count = 0; |
char *condition = NULL; |
enum gdb_rc rc; |
struct gdb_events *old_hooks; |
enum opt |
{ |
HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT, |
IGNORE_COUNT_OPT, THREAD_OPT |
}; |
static struct mi_opt opts[] = |
{ |
{"h", HARDWARE_OPT, 0}, |
{"t", TEMP_OPT, 0}, |
{"c", CONDITION_OPT, 1}, |
{"i", IGNORE_COUNT_OPT, 1}, |
{"p", THREAD_OPT, 1}, |
0 |
}; |
|
/* Parse arguments. It could be -r or -h or -t, <location> or ``--'' |
to denote the end of the option list. */ |
int optind = 0; |
char *optarg; |
while (1) |
{ |
int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg); |
if (opt < 0) |
break; |
switch ((enum opt) opt) |
{ |
case TEMP_OPT: |
temp_p = 1; |
break; |
case HARDWARE_OPT: |
type = HW_BP; |
break; |
#if 0 |
case REGEXP_OPT: |
type = REGEXP_BP; |
break; |
#endif |
case CONDITION_OPT: |
condition = optarg; |
break; |
case IGNORE_COUNT_OPT: |
ignore_count = atol (optarg); |
break; |
case THREAD_OPT: |
thread = atol (optarg); |
break; |
} |
} |
|
if (optind >= argc) |
error ("mi_cmd_break_insert: Missing <location>"); |
if (optind < argc - 1) |
error ("mi_cmd_break_insert: Garbage following <location>"); |
address = argv[optind]; |
|
/* Now we have what we need, let's insert the breakpoint! */ |
old_hooks = set_gdb_event_hooks (&breakpoint_hooks); |
switch (type) |
{ |
case REG_BP: |
rc = gdb_breakpoint (address, condition, |
0 /*hardwareflag */ , temp_p, |
thread, ignore_count); |
break; |
case HW_BP: |
rc = gdb_breakpoint (address, condition, |
1 /*hardwareflag */ , temp_p, |
thread, ignore_count); |
break; |
#if 0 |
case REGEXP_BP: |
if (temp_p) |
error ("mi_cmd_break_insert: Unsupported tempoary regexp breakpoint"); |
else |
rbreak_command_wrapper (address, FROM_TTY); |
return MI_CMD_DONE; |
break; |
#endif |
default: |
internal_error ("mi_cmd_break_insert: Bad switch."); |
} |
set_gdb_event_hooks (old_hooks); |
|
if (rc == GDB_RC_FAIL) |
return MI_CMD_CAUGHT_ERROR; |
else |
return MI_CMD_DONE; |
} |
|
enum wp_type |
{ |
REG_WP, |
READ_WP, |
ACCESS_WP |
}; |
|
/* Insert a watchpoint. The type of watchpoint is specified by the |
first argument: |
-break-watch <expr> --> insert a regular wp. |
-break-watch -r <expr> --> insert a read watchpoint. |
-break-watch -a <expr> --> insert an access wp. */ |
|
enum mi_cmd_result |
mi_cmd_break_watch (char *command, char **argv, int argc) |
{ |
char *expr = NULL; |
enum wp_type type = REG_WP; |
enum opt |
{ |
READ_OPT, ACCESS_OPT |
}; |
static struct mi_opt opts[] = |
{ |
{"r", READ_OPT, 0}, |
{"a", ACCESS_OPT, 0}, |
0 |
}; |
|
/* Parse arguments. */ |
int optind = 0; |
char *optarg; |
while (1) |
{ |
int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg); |
if (opt < 0) |
break; |
switch ((enum opt) opt) |
{ |
case READ_OPT: |
type = READ_WP; |
break; |
case ACCESS_OPT: |
type = ACCESS_WP; |
break; |
} |
} |
if (optind >= argc) |
error ("mi_cmd_break_watch: Missing <expression>"); |
if (optind < argc - 1) |
error ("mi_cmd_break_watch: Garbage following <expression>"); |
expr = argv[optind]; |
|
/* Now we have what we need, let's insert the watchpoint! */ |
switch (type) |
{ |
case REG_WP: |
#ifdef UI_OUT |
watch_command_wrapper (expr, FROM_TTY); |
#endif |
break; |
case READ_WP: |
#ifdef UI_OUT |
rwatch_command_wrapper (expr, FROM_TTY); |
#endif |
break; |
case ACCESS_WP: |
#ifdef UI_OUT |
awatch_command_wrapper (expr, FROM_TTY); |
#endif |
break; |
default: |
error ("mi_cmd_break_watch: Unknown watchpoint type."); |
} |
return MI_CMD_DONE; |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-cmds.c
0,0 → 1,264
/* MI Command Set. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "top.h" |
#include "mi-cmds.h" |
#include <string.h> |
|
extern void _initialize_mi_cmds (void); |
struct mi_cmd; |
static struct mi_cmd **lookup_table (const char *command); |
static void build_table (struct mi_cmd *commands); |
|
|
struct mi_cmd mi_cmds[] = |
{ |
{"break-after", "ignore %s", 0}, |
{"break-catch", 0, 0}, |
{"break-commands", 0, 0}, |
{"break-condition", "cond %s", 0}, |
{"break-delete", "delete breakpoint %s", 0}, |
{"break-disable", "disable breakpoint %s", 0}, |
{"break-enable", "enable breakpoint %s", 0}, |
{"break-info", "info break %s", 0}, |
{"break-insert", 0, 0, mi_cmd_break_insert}, |
{"break-list", "info break", 0}, |
{"break-watch", 0, 0, mi_cmd_break_watch}, |
{"data-disassemble", 0, 0, mi_cmd_disassemble}, |
{"data-evaluate-expression", 0, 0, mi_cmd_data_evaluate_expression}, |
{"data-list-changed-registers", 0, 0, mi_cmd_data_list_changed_registers}, |
{"data-list-register-names", 0, 0, mi_cmd_data_list_register_names}, |
{"data-list-register-values", 0, 0, mi_cmd_data_list_register_values}, |
{"data-read-memory", 0, 0, mi_cmd_data_read_memory}, |
{"data-write-memory", 0, 0, mi_cmd_data_write_memory}, |
{"data-write-register-values", 0, 0, mi_cmd_data_write_register_values}, |
{"display-delete", 0, 0}, |
{"display-disable", 0, 0}, |
{"display-enable", 0, 0}, |
{"display-insert", 0, 0}, |
{"display-list", 0, 0}, |
{"environment-cd", "cd %s", 0}, |
{"environment-directory", "dir %s", 0}, |
{"environment-path", "path %s", 0}, |
{"environment-pwd", "pwd", 0}, |
{"exec-abort", 0, 0}, |
{"exec-arguments", "set args %s", 0}, |
{"exec-continue", 0, mi_cmd_exec_continue}, |
{"exec-finish", 0, mi_cmd_exec_finish}, |
{"exec-interrupt", 0, mi_cmd_exec_interrupt}, |
{"exec-next", 0, mi_cmd_exec_next}, |
{"exec-next-instruction", 0, mi_cmd_exec_next_instruction}, |
{"exec-return", 0, mi_cmd_exec_return}, |
{"exec-run", 0, mi_cmd_exec_run}, |
{"exec-show-arguments", 0, 0}, |
{"exec-signal", 0, 0}, |
{"exec-step", 0, mi_cmd_exec_step}, |
{"exec-step-instruction", 0, mi_cmd_exec_step_instruction}, |
{"exec-until", 0, mi_cmd_exec_until}, |
{"file-clear", 0, 0}, |
{"file-exec-and-symbols", "file %s", 0}, |
{"file-exec-file", "exec-file %s", 0}, |
{"file-list-exec-sections", 0, 0}, |
{"file-list-exec-source-files", 0, 0}, |
{"file-list-shared-libraries", 0, 0}, |
{"file-list-symbol-files", 0, 0}, |
{"file-symbol-file", "symbol-file %s", 0}, |
{"gdb-complete", 0, 0}, |
{"gdb-exit", 0, 0, mi_cmd_gdb_exit}, |
{"gdb-set", "set %s", 0}, |
{"gdb-show", "show %s", 0}, |
{"gdb-source", 0, 0}, |
{"gdb-version", "show version", 0}, |
{"kod-info", 0, 0}, |
{"kod-list", 0, 0}, |
{"kod-list-object-types", 0, 0}, |
{"kod-show", 0, 0}, |
{"overlay-auto", 0, 0}, |
{"overlay-list-mapping-state", 0, 0}, |
{"overlay-list-overlays", 0, 0}, |
{"overlay-map", 0, 0}, |
{"overlay-off", 0, 0}, |
{"overlay-on", 0, 0}, |
{"overlay-unmap", 0, 0}, |
{"signal-handle", 0, 0}, |
{"signal-list-handle-actions", 0, 0}, |
{"signal-list-signal-types", 0, 0}, |
{"stack-info-depth", 0, 0, mi_cmd_stack_info_depth}, |
{"stack-info-frame", 0, 0}, |
{"stack-list-arguments", 0, 0, mi_cmd_stack_list_args}, |
{"stack-list-exception-handlers", 0, 0}, |
{"stack-list-frames", 0, 0, mi_cmd_stack_list_frames}, |
{"stack-list-locals", 0, 0, mi_cmd_stack_list_locals}, |
{"stack-select-frame", 0, 0, mi_cmd_stack_select_frame}, |
{"symbol-info-address", 0, 0}, |
{"symbol-info-file", 0, 0}, |
{"symbol-info-function", 0, 0}, |
{"symbol-info-line", 0, 0}, |
{"symbol-info-symbol", 0, 0}, |
{"symbol-list-functions", 0, 0}, |
{"symbol-list-types", 0, 0}, |
{"symbol-list-variables", 0, 0}, |
{"symbol-locate", 0, 0}, |
{"symbol-type", 0, 0}, |
{"target-attach", 0, 0}, |
{"target-compare-sections", 0, 0}, |
{"target-detach", "detach", 0}, |
{"target-download", 0, mi_cmd_target_download}, |
{"target-exec-status", 0, 0}, |
{"target-list-available-targets", 0, 0}, |
{"target-list-current-targets", 0, 0}, |
{"target-list-parameters", 0, 0}, |
{"target-select", 0, mi_cmd_target_select}, |
{"thread-info", 0, 0}, |
{"thread-list-all-threads", 0, 0}, |
{"thread-list-ids", 0, 0, mi_cmd_thread_list_ids}, |
{"thread-select", 0, 0, mi_cmd_thread_select}, |
{"trace-actions", 0, 0}, |
{"trace-delete", 0, 0}, |
{"trace-disable", 0, 0}, |
{"trace-dump", 0, 0}, |
{"trace-enable", 0, 0}, |
{"trace-exists", 0, 0}, |
{"trace-find", 0, 0}, |
{"trace-frame-number", 0, 0}, |
{"trace-info", 0, 0}, |
{"trace-insert", 0, 0}, |
{"trace-list", 0, 0}, |
{"trace-pass-count", 0, 0}, |
{"trace-save", 0, 0}, |
{"trace-start", 0, 0}, |
{"trace-stop", 0, 0}, |
{"var-assign", 0, 0, mi_cmd_var_assign}, |
{"var-create", 0, 0, mi_cmd_var_create}, |
{"var-delete", 0, 0, mi_cmd_var_delete}, |
{"var-evaluate-expression", 0, 0, mi_cmd_var_evaluate_expression}, |
{"var-info-expression", 0, 0, mi_cmd_var_info_expression}, |
{"var-info-num-children", 0, 0, mi_cmd_var_info_num_children}, |
{"var-info-type", 0, 0, mi_cmd_var_info_type}, |
{"var-list-children", 0, 0, mi_cmd_var_list_children}, |
{"var-set-format", 0, 0, mi_cmd_var_set_format}, |
{"var-show-attributes", 0, 0, mi_cmd_var_show_attributes}, |
{"var-show-format", 0, 0, mi_cmd_var_show_format}, |
{"var-update", 0, 0, mi_cmd_var_update}, |
{0,} |
}; |
|
/* Pointer to the mi command table (built at run time) */ |
|
static struct mi_cmd **mi_table; |
|
/* A prime large enough to accomodate the entire command table */ |
enum |
{ |
MI_TABLE_SIZE = 227 |
}; |
|
/* Exported function used to obtain info from the table */ |
struct mi_cmd * |
mi_lookup (const char *command) |
{ |
return *lookup_table (command); |
} |
|
/* stat collecting */ |
struct mi_cmd_stats |
{ |
int hit; |
int miss; |
int rehash; |
}; |
struct mi_cmd_stats stats; |
|
/* our lookup function */ |
static struct mi_cmd ** |
lookup_table (const char *command) |
{ |
const char *chp; |
unsigned int index = 0; |
/* compute our hash */ |
for (chp = command; *chp; chp++) |
{ |
/* some what arbitrary */ |
index = ((index << 6) + (unsigned int) *chp) % MI_TABLE_SIZE; |
} |
/* look it up */ |
while (1) |
{ |
struct mi_cmd **entry = &mi_table[index]; |
if ((*entry) == 0) |
{ |
/* not found, return pointer to next free. */ |
stats.miss++; |
return entry; |
} |
if (strcmp (command, (*entry)->name) == 0) |
{ |
stats.hit++; |
return entry; /* found */ |
} |
index = (index + 1) % MI_TABLE_SIZE; |
stats.rehash++; |
} |
} |
|
static void |
build_table (struct mi_cmd *commands) |
{ |
int nr_rehash = 0; |
int nr_entries = 0; |
struct mi_cmd *command; |
int sizeof_table = sizeof (struct mi_cmd **) * MI_TABLE_SIZE; |
|
mi_table = xmalloc (sizeof_table); |
memset (mi_table, 0, sizeof_table); |
for (command = commands; command->name != 0; command++) |
{ |
struct mi_cmd **entry = lookup_table (command->name); |
if (*entry) |
internal_error ("command `%s' appears to be duplicated", |
command->name); |
*entry = command; |
if (0) |
{ |
fprintf_unfiltered (gdb_stdlog, "%-30s %2d\n", |
command->name, stats.rehash - nr_rehash); |
} |
nr_entries++; |
nr_rehash = stats.rehash; |
} |
if (0) |
{ |
fprintf_filtered (gdb_stdlog, "Average %3.1f\n", |
(double) nr_rehash / (double) nr_entries); |
} |
} |
|
void |
_initialize_mi_cmds () |
{ |
build_table (mi_cmds); |
memset (&stats, 0, sizeof (stats)); |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |
/mi-cmd-var.c
0,0 → 1,507
/* MI Command Set - varobj commands. |
Copyright (C) 2000, Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
|
This file is part of GDB. |
|
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 2 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, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, |
Boston, MA 02111-1307, USA. */ |
|
#include "defs.h" |
#include "mi-cmds.h" |
#include "ui-out.h" |
#include "mi-out.h" |
#include "varobj.h" |
#include "value.h" |
#include <ctype.h> |
|
/* Convenience macro for allocting typesafe memory. */ |
|
#undef XMALLOC |
#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) |
|
extern int varobjdebug; /* defined in varobj.c */ |
|
static int varobj_update_one (struct varobj *var); |
|
/* VAROBJ operations */ |
|
enum mi_cmd_result |
mi_cmd_var_create (char *command, char **argv, int argc) |
{ |
CORE_ADDR frameaddr = 0; |
struct varobj *var; |
char *name; |
char *frame; |
char *expr; |
char *type; |
struct cleanup *old_cleanups; |
enum varobj_type var_type; |
|
if (argc != 3) |
{ |
/* asprintf (&mi_error_message, |
"mi_cmd_var_create: Usage: ."); |
return MI_CMD_ERROR; */ |
error ("mi_cmd_var_create: Usage: NAME FRAME EXPRESSION."); |
} |
|
name = xstrdup (argv[0]); |
/* Add cleanup for name. Must be free_current_contents as |
name can be reallocated */ |
old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents, |
&name); |
|
frame = xstrdup (argv[1]); |
old_cleanups = make_cleanup (free, frame); |
|
expr = xstrdup (argv[2]); |
|
if (strcmp (name, "-") == 0) |
{ |
free (name); |
name = varobj_gen_name (); |
} |
else if (!isalpha (*name)) |
error ("mi_cmd_var_create: name of object must begin with a letter"); |
|
if (strcmp (frame, "*") == 0) |
var_type = USE_CURRENT_FRAME; |
else if (strcmp (frame, "@") == 0) |
var_type = USE_SELECTED_FRAME; |
else |
{ |
var_type = USE_SPECIFIED_FRAME; |
frameaddr = parse_and_eval_address (frame); |
} |
|
if (varobjdebug) |
fprintf_unfiltered (gdb_stdlog, |
"Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n", |
name, frame, paddr (frameaddr), expr); |
|
var = varobj_create (name, expr, frameaddr, var_type); |
|
if (var == NULL) |
error ("mi_cmd_var_create: unable to create variable object"); |
|
ui_out_field_string (uiout, "name", name); |
ui_out_field_int (uiout, "numchild", varobj_get_num_children (var)); |
type = varobj_get_type (var); |
if (type == NULL) |
ui_out_field_string (uiout, "type", ""); |
else |
{ |
ui_out_field_string (uiout, "type", type); |
free (type); |
} |
|
do_cleanups (old_cleanups); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_delete (char *command, char **argv, int argc) |
{ |
char *name; |
char *expr; |
struct varobj *var; |
int numdel; |
int children_only_p = 0; |
struct cleanup *old_cleanups; |
|
if (argc < 1 || argc > 2) |
error ("mi_cmd_var_delete: Usage: [-c] EXPRESSION."); |
|
name = xstrdup (argv[0]); |
/* Add cleanup for name. Must be free_current_contents as |
name can be reallocated */ |
old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents, |
&name); |
|
/* If we have one single argument it cannot be '-c' or any string |
starting with '-'. */ |
if (argc == 1) |
{ |
if (strcmp (name, "-c") == 0) |
error ("mi_cmd_var_delete: Missing required argument after '-c': variable object name"); |
if (*name == '-') |
error ("mi_cmd_var_delete: Illegal variable object name"); |
} |
|
/* If we have 2 arguments they must be '-c' followed by a string |
which would be the variable name. */ |
if (argc == 2) |
{ |
expr = xstrdup (argv[1]); |
if (strcmp (name, "-c") != 0) |
error ("mi_cmd_var_delete: Invalid option."); |
children_only_p = 1; |
free (name); |
name = xstrdup (expr); |
free (expr); |
} |
|
/* If we didn't error out, now NAME contains the name of the |
variable. */ |
|
var = varobj_get_handle (name); |
|
if (var == NULL) |
error ("mi_cmd_var_delete: Variable object not found."); |
|
numdel = varobj_delete (var, NULL, children_only_p); |
|
ui_out_field_int (uiout, "ndeleted", numdel); |
|
do_cleanups (old_cleanups); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_set_format (char *command, char **argv, int argc) |
{ |
enum varobj_display_formats format; |
int len; |
struct varobj *var; |
char *formspec; |
|
if (argc != 2) |
error ("mi_cmd_var_set_format: Usage: NAME FORMAT."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
|
if (var == NULL) |
error ("mi_cmd_var_set_format: Variable object not found"); |
|
formspec = xstrdup (argv[1]); |
if (formspec == NULL) |
error ("mi_cmd_var_set_format: Must specify the format as: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""); |
|
len = strlen (formspec); |
|
if (STREQN (formspec, "natural", len)) |
format = FORMAT_NATURAL; |
else if (STREQN (formspec, "binary", len)) |
format = FORMAT_BINARY; |
else if (STREQN (formspec, "decimal", len)) |
format = FORMAT_DECIMAL; |
else if (STREQN (formspec, "hexadecimal", len)) |
format = FORMAT_HEXADECIMAL; |
else if (STREQN (formspec, "octal", len)) |
format = FORMAT_OCTAL; |
else |
error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""); |
|
/* Set the format of VAR to given format */ |
varobj_set_display_format (var, format); |
|
/* Report the new current format */ |
ui_out_field_string (uiout, "format", varobj_format_string[(int) format]); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_show_format (char *command, char **argv, int argc) |
{ |
enum varobj_display_formats format; |
struct varobj *var; |
|
if (argc != 1) |
error ("mi_cmd_var_show_format: Usage: NAME."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_show_format: Variable object not found"); |
|
format = varobj_get_display_format (var); |
|
/* Report the current format */ |
ui_out_field_string (uiout, "format", varobj_format_string[(int) format]); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_info_num_children (char *command, char **argv, int argc) |
{ |
struct varobj *var; |
|
if (argc != 1) |
error ("mi_cmd_var_info_num_children: Usage: NAME."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_info_num_children: Variable object not found"); |
|
ui_out_field_int (uiout, "numchild", varobj_get_num_children (var)); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_list_children (char *command, char **argv, int argc) |
{ |
struct varobj *var; |
struct varobj **childlist; |
struct varobj **cc; |
int numchild; |
char *type; |
|
if (argc != 1) |
error ("mi_cmd_var_list_children: Usage: NAME."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_list_children: Variable object not found"); |
|
numchild = varobj_list_children (var, &childlist); |
ui_out_field_int (uiout, "numchild", numchild); |
|
if (numchild <= 0) |
return MI_CMD_DONE; |
|
ui_out_list_begin (uiout, "children"); |
cc = childlist; |
while (*cc != NULL) |
{ |
ui_out_list_begin (uiout, "child"); |
ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); |
ui_out_field_string (uiout, "exp", varobj_get_expression (*cc)); |
ui_out_field_int (uiout, "numchild", varobj_get_num_children (*cc)); |
type = varobj_get_type (*cc); |
/* C++ pseudo-variables (public, private, protected) do not have a type */ |
if (type) |
ui_out_field_string (uiout, "type", varobj_get_type (*cc)); |
ui_out_list_end (uiout); |
cc++; |
} |
ui_out_list_end (uiout); |
free (childlist); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_info_type (char *command, char **argv, int argc) |
{ |
struct varobj *var; |
|
if (argc != 1) |
error ("mi_cmd_var_info_type: Usage: NAME."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_info_type: Variable object not found"); |
|
ui_out_field_string (uiout, "type", varobj_get_type (var)); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_info_expression (char *command, char **argv, int argc) |
{ |
enum varobj_languages lang; |
struct varobj *var; |
|
if (argc != 1) |
error ("mi_cmd_var_info_expression: Usage: NAME."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_info_expression: Variable object not found"); |
|
lang = varobj_get_language (var); |
|
ui_out_field_string (uiout, "lang", varobj_language_string[(int) lang]); |
ui_out_field_string (uiout, "exp", varobj_get_expression (var)); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_show_attributes (char *command, char **argv, int argc) |
{ |
int attr; |
char *attstr; |
struct varobj *var; |
|
if (argc != 1) |
error ("mi_cmd_var_show_attributes: Usage: NAME."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_show_attributes: Variable object not found"); |
|
attr = varobj_get_attributes (var); |
/* FIXME: define masks for attributes */ |
if (attr & 0x00000001) |
attstr = "editable"; |
else |
attstr = "noneditable"; |
|
ui_out_field_string (uiout, "attr", attstr); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_evaluate_expression (char *command, char **argv, int argc) |
{ |
struct varobj *var; |
|
if (argc != 1) |
error ("mi_cmd_var_evaluate_expression: Usage: NAME."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_evaluate_expression: Variable object not found"); |
|
ui_out_field_string (uiout, "value", varobj_get_value (var)); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_assign (char *command, char **argv, int argc) |
{ |
struct varobj *var; |
char *expression; |
|
if (argc != 2) |
error ("mi_cmd_var_assign: Usage: NAME EXPRESSION."); |
|
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (argv[0]); |
if (var == NULL) |
error ("mi_cmd_var_assign: Variable object not found"); |
|
/* FIXME: define masks for attributes */ |
if (!(varobj_get_attributes (var) & 0x00000001)) |
error ("mi_cmd_var_assign: Variable object is not editable"); |
|
expression = xstrdup (argv[1]); |
|
if (!varobj_set_value (var, expression)) |
error ("mi_cmd_var_assign: Could not assign expression to varible object"); |
|
ui_out_field_string (uiout, "value", varobj_get_value (var)); |
return MI_CMD_DONE; |
} |
|
enum mi_cmd_result |
mi_cmd_var_update (char *command, char **argv, int argc) |
{ |
struct varobj *var; |
struct varobj **rootlist; |
struct varobj **cr; |
char *name; |
int nv; |
|
if (argc != 1) |
error ("mi_cmd_var_update: Usage: NAME."); |
|
name = argv[0]; |
|
/* Check if the parameter is a "*" which means that we want |
to update all variables */ |
|
if ((*name == '*') && (*(name + 1) == '\0')) |
{ |
nv = varobj_list (&rootlist); |
ui_out_list_begin (uiout, "changelist"); |
if (nv <= 0) |
{ |
ui_out_list_end (uiout); |
return MI_CMD_DONE; |
} |
cr = rootlist; |
while (*cr != NULL) |
{ |
varobj_update_one (*cr); |
cr++; |
} |
free (rootlist); |
ui_out_list_end (uiout); |
} |
else |
{ |
/* Get varobj handle, if a valid var obj name was specified */ |
var = varobj_get_handle (name); |
if (var == NULL) |
error ("mi_cmd_var_update: Variable object not found"); |
|
ui_out_list_begin (uiout, "changelist"); |
varobj_update_one (var); |
ui_out_list_end (uiout); |
} |
return MI_CMD_DONE; |
} |
|
/* Helper for mi_cmd_var_update() Returns 0 if the update for |
the variable fails (usually because the variable is out of |
scope), and 1 if it succeeds. */ |
|
static int |
varobj_update_one (struct varobj *var) |
{ |
struct varobj **changelist; |
struct varobj **cc; |
int nc; |
|
nc = varobj_update (var, &changelist); |
|
/* nc == 0 means that nothing has changed. |
nc == -1 means that an error occured in updating the variable. |
nc == -2 means the variable has changed type. */ |
|
if (nc == 0) |
return 1; |
else if (nc == -1) |
{ |
ui_out_field_string (uiout, "name", varobj_get_objname(var)); |
ui_out_field_string (uiout, "in_scope", "false"); |
return -1; |
} |
else if (nc == -2) |
{ |
ui_out_field_string (uiout, "name", varobj_get_objname (var)); |
ui_out_field_string (uiout, "in_scope", "true"); |
ui_out_field_string (uiout, "new_type", varobj_get_type(var)); |
ui_out_field_int (uiout, "new_num_children", |
varobj_get_num_children(var)); |
} |
else |
{ |
|
cc = changelist; |
while (*cc != NULL) |
{ |
ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); |
ui_out_field_string (uiout, "in_scope", "true"); |
ui_out_field_string (uiout, "type_changed", "false"); |
cc++; |
} |
free (changelist); |
return 1; |
} |
return 1; |
} |
|
/* Local variables: */ |
/* change-log-default-name: "ChangeLog-mi" */ |
/* End: */ |