Add mi/ and testsuite/gdb.mi/ subdirectories.

Add --enable-gdbmi option to configury.
Add mi rules to Makefile.in
Add mi conditional output to event-top.c infrun.c main.c top.c.
Add -i=mi option.
This commit is contained in:
Andrew Cagney 2000-02-23 00:25:43 +00:00
parent e6c6b6fe2d
commit fb40c20903
59 changed files with 16199 additions and 318 deletions

View File

@ -1,3 +1,36 @@
Mon Feb 21 13:57:27 2000 Andrew Cagney <cagney@b1.cygnus.com>
* configure.in (CONFIG_INITS): Fix typo, was CONFIG_INIT.
(ENABLE_CFLAGS): Move initialization to start of file.
(enable-gdbmi): Add new configure option --enable-gdbmi. When
selected and an ${srcdir}/mi directory is present enable MI
interface.
* configure: Regenerate.
* Makefile.in (SUBDIR_MI_OBS, SUBDIR_MI_SRCS, SUBDIR_MI_DEPS,
SUBDIR_MI_INITS, SUBDIR_MI_LDFLAGS, SUBDIR_MI_CFLAGS): New macros.
(CONFIG_OBS, CONFIG_SRCS, CONFIG_DEPS, CONFIG_INITS,
CONFIG_LDFLAGS): New macros. Initialized by autoconf via
@CONFIG...@.
(INTERNAL_LDFLAGS, CDEPS, LINTFILES, DEPFILES, SOURCES,
INIT_FILES): Use $(CONFIG_...) instead of @CONFIG...@.
* mi: New directory. MI interface to GDB.
* defs.h (interpreter_p): Declare when UI_OUT.
* top.c (gdb_init): When interpreter_p, check that the interpreter
was recognized by one of the linked in interpreters.
* main.c (interpreter_p): Define.
(captured_main): When UI_OUT, check for ``-i <interpreter>'' option.
* event-top.c (display_gdb_prompt): When interpreter_p, assume
interpreter displays prompt.
* breakpoint.c (print_it_typical, watchpoint_check,
print_one_breakpoint, mention): When MI include additional
target status information.
* infrun.c (print_stop_reason, normal_stop): Ditto.
2000-02-22 Jim Blandy <jimb@redhat.com>
* gdbarch.sh: Make the `default' field really default to zero, as

View File

@ -141,6 +141,27 @@ TUI_DIR=tui
TUI_SRC = $(srcdir)/$(TUI_DIR)
TUI_CFLAGS= -I$(TUI_SRC)
#
# MI sub directory definitons
#
SUBDIR_MI_OBS = \
mi-out.o mi-console.o \
mi-cmds.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
mi-cmd-disas.o \
mi-main.o mi-parse.o mi-getopt.o
SUBDIR_MI_SRCS = \
mi/mi-out.c mi/mi-console.c \
mi/mi-cmds.c \
mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \
mi/mi-cmd-disas.c \
mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c
SUBDIR_MI_DEPS =
SUBDIR_MI_INITS = \
mi/mi-cmds.c mi/mi-parse.c mi/mi-main.c
SUBDIR_MI_LDFLAGS=
SUBDIR_MI_CFLAGS= \
-DUI_OUT=1
# Opcodes currently live in one of two places. Either they are in the
# opcode library, typically ../opcodes, or they are in a header file
# in INCLUDE_DIR.
@ -200,6 +221,11 @@ LIBGUI = @LIBGUI@
GUI_CFLAGS_X = @GUI_CFLAGS_X@
IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X)
CONFIG_OBS= @CONFIG_OBS@
CONFIG_SRCS= @CONFIG_SRCS@
CONFIG_DEPS= @CONFIG_DEPS@
CONFIG_INITS= @CONFIG_INITS@
CONFIG_LDFLAGS = @CONFIG_LDFLAGS@
ENABLE_CFLAGS= @ENABLE_CFLAGS@
# -I. for config files.
@ -240,7 +266,7 @@ INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS)
# Profiling options need to go here to work.
# I think it's perfectly reasonable for a user to set -pg in CFLAGS
# and have it work; that's why CFLAGS is here.
INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS) @CONFIG_LDFLAGS@ @HLDFLAGS@
INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS) $(CONFIG_LDFLAGS) @HLDFLAGS@
HLDENV = @HLDENV@
# We are using our own version of REGEX now to be consistent across
@ -265,7 +291,7 @@ CLIBS = $(SIM) $(BFD) $(READLINE) $(OPCODES) $(INTL) $(LIBIBERTY) \
$(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
$(MMALLOC) $(LIBIBERTY) $(WIN32LIBS)
CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
$(OPCODES) $(MMALLOC) $(INTL_DEPS) $(LIBIBERTY) @CONFIG_DEPS@
$(OPCODES) $(MMALLOC) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS)
ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
@ -449,7 +475,7 @@ SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
tui/tui-file.h tui/tui-file.c \
ui-file.h ui-file.c
LINTFILES = $(SFILES) $(YYFILES) @CONFIG_SRCS@ init.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
# "system" headers. Using these in dependencies is a rather personal
# choice. (-rich, summer 1993)
@ -551,9 +577,9 @@ POSSLIBS = gnu-regex.c gnu-regex.h
# Makefile.in
DEPFILES = $(TDEPFILES) $(XDEPFILES) $(SER_HARDWIRE) $(NATDEPFILES) \
$(REMOTE_OBS) $(SIM_OBS) @CONFIG_OBS@
$(REMOTE_OBS) $(SIM_OBS) $(CONFIG_OBS)
SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) @CONFIG_SRCS@
SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) $(CONFIG_SRCS)
# Don't include YYFILES (*.tab.c) because we already include *.y in SFILES,
# and it's more useful to see it in the .y file.
TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_NO_SRCDIR) $(ALLDEPFILES) \
@ -693,7 +719,7 @@ uninstall: force
# tui-file.c.
#
INIT_FILES = $(OBS) $(TSOBS) $(SUBDIR_INIT_FILES) @CONFIG_INITS@
INIT_FILES = $(OBS) $(TSOBS) $(CONFIG_INITS)
init.c: $(INIT_FILES)
@echo Making init.c
@rm -f init.c-tmp init.l-tmp
@ -1859,4 +1885,43 @@ varobj.o: varobj.c $(defs_h) $(frame_h) $(value_h) \
$(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $<
wrapper.o: wrapper.c $(defs_h) $(frame_h) $(value_h) wrapper.h
#
# MI dependencies
#
# Need to explicitly specify the compile rule as make will do nothing
# or try to compile the object file into the mi directory.
mi_cmds_h = $(srcdir)/mi/mi-cmds.h
mi_out_h = $(srcdir)/mi/mi-out.h
mi_parse_h = $(srcdir)/mi/mi-parse.h
mi_getopt_h = $(srcdir)/mi/mi-getopt.h
mi_console_h = $(srcdir)/mi/mi-console.h
mi-cmds.o: $(srcdir)/mi/mi-cmds.c $(defs_h) $(top_h) $(mi_cmds_h) $(ui_out_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmds.c
mi-cmd-var.o: $(srcdir)/mi/mi-cmd-var.c $(defs_h) $(top_h) $(mi_cmds_h) \
$(ui_out_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-var.c
mi-cmd-stack.o: $(srcdir)/mi/mi-cmd-stack.c $(defs_h) $(top_h) $(mi_cmds_h) \
$(ui_out_h) $(frame_h) $(value_h) $(target_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-stack.c
mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c $(defs_h) $(mi_cmds_h) \
$(ui_out_h) $(mi_getopt_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-break.c
mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(defs_h) $(mi_cmds_h) \
$(ui_out_h) $(value_h) $(target_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-disas.c
mi-main.o: $(srcdir)/mi/mi-main.c $(defs_h) $(top_h) $(mi_cmds_h) $(ui_out_h) \
$(mi_console_h) $(mi_getopt_h) $(event_loop_h) $(event_top_h) \
$(mi_getopt_h)
$(CC) -c $(INTERNAL_WARN_CFLAGS) $(srcdir)/mi/mi-main.c
mi-out.o: $(srcdir)/mi/mi-out.c $(defs_h) $(mi_out_h) $(ui_out_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-out.c
mi-console.o: $(srcdir)/mi/mi-console.c $(mi_out_h) $(defs_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-console.c
mi-parse.o: $(srcdir)/mi/mi-parse.c $(defs_h) $(mi_parse_h) $(mi_cmds_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-parse.c
mi-getopt.o: $(srcdir)/mi/mi-getopt.c $(mi_getopt_h) $(defs_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-getopt.c
### end of the gdb Makefile.in.

View File

@ -1909,6 +1909,8 @@ print_it_typical (bs)
#ifdef UI_OUT
annotate_breakpoint (bs->breakpoint_at->number);
ui_out_text (uiout, "\nBreakpoint ");
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "breakpoint-hit");
ui_out_field_int (uiout, "bkptno", bs->breakpoint_at->number);
ui_out_text (uiout, ", ");
return PRINT_SRC_AND_LOC;
@ -2052,6 +2054,8 @@ print_it_typical (bs)
{
annotate_watchpoint (bs->breakpoint_at->number);
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "watchpoint-trigger");
mention (bs->breakpoint_at);
ui_out_list_begin (uiout, "value");
ui_out_text (uiout, "\nOld value = ");
@ -2080,6 +2084,8 @@ print_it_typical (bs)
case bp_read_watchpoint:
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "read-watchpoint-trigger");
mention (bs->breakpoint_at);
ui_out_list_begin (uiout, "value");
ui_out_text (uiout, "\nValue = ");
@ -2102,6 +2108,8 @@ print_it_typical (bs)
if (bs->old_val != NULL)
{
annotate_watchpoint (bs->breakpoint_at->number);
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
mention (bs->breakpoint_at);
ui_out_list_begin (uiout, "value");
ui_out_text (uiout, "\nOld value = ");
@ -2114,6 +2122,8 @@ print_it_typical (bs)
else
{
mention (bs->breakpoint_at);
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_list_begin (uiout, "value");
ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
ui_out_text (uiout, "\nValue = ");
}
@ -2148,10 +2158,18 @@ print_it_typical (bs)
here. */
case bp_finish:
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "function-finished");
#endif
return PRINT_UNKNOWN;
break;
case bp_until:
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "location-reached");
#endif
return PRINT_UNKNOWN;
break;
@ -2360,6 +2378,8 @@ watchpoint_check (p)
will be deleted already. So we have no choice but print the
information here. */
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "watchpoint-scope");
ui_out_text (uiout, "\nWatchpoint ");
ui_out_field_int (uiout, "wpnum", bs->breakpoint_at->number);
ui_out_text (uiout, " deleted because the program has left the block in\n\
@ -3446,6 +3466,13 @@ print_one_breakpoint (struct breakpoint *b,
#endif
}
#ifdef UI_OUT
/* Output the count also if it is zero, but only if this is
mi. FIXME: Should have a better test for this. */
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
if (show_breakpoint_hit_counts && b->hit_count == 0)
ui_out_field_int (uiout, "times", b->hit_count);
#endif
if (b->ignore_count)
{
@ -4446,10 +4473,24 @@ mention (b)
break;
#endif
case bp_breakpoint:
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
{
say_where = 0;
break;
}
#endif
printf_filtered ("Breakpoint %d", b->number);
say_where = 1;
break;
case bp_hardware_breakpoint:
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
{
say_where = 0;
break;
}
#endif
printf_filtered ("Hardware assisted breakpoint %d", b->number);
say_where = 1;
break;
@ -4505,6 +4546,10 @@ mention (b)
}
#ifdef UI_OUT
do_cleanups (old_chain);
#endif
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
return;
#endif
printf_filtered ("\n");
}

657
gdb/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,8 @@ dnl List of object files added by configure.
CONFIG_OBS=
CONFIG_DEPS=
CONFIG_SRCS=
CONFIG_INIT=
CONFIG_INITS=
ENABLE_CFLAGS=
configdirs="doc testsuite"
@ -363,7 +364,30 @@ if test ${build} = ${host} -a ${host} = ${target} ; then
fi
dnl Handle optional features that can be enabled.
ENABLE_CFLAGS=
dnl Handle MI sub-directory configury.
AC_ARG_ENABLE(gdbmi,
[ --enable-gdbmi Enable GDB-MI interface],
[
case "${enable_gdbmi}" in
yes | no) ;;
"") enable_gdbmi=yes ;;
*)
AC_MSG_ERROR(Bad value for --enable-gdbmi: ${enableval})
;;
esac
])
case ${enable_gdbmi} in
"yes" )
if test -d "${srcdir}/mi" ; then
CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_MI_OBS)"
CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_MI_DEPS)"
CONFIG_SRCS="${CONFIG_SRS} \$(SUBDIR_MI_SRCS)"
CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_MI_INITS)"
ENABLE_CFLAGS="${ENABLE_CFLAGS} \${SUBDIR_MI_CFLAGS)"
fi
;;
esac
AC_ARG_ENABLE(tui,
[ --enable-tui Enable full-screen terminal user interface],
@ -406,7 +430,9 @@ fi
AC_ARG_ENABLE(build-warnings,
[ --enable-build-warnings Enable build-time compiler warnings if gcc is used],
[build_warnings="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations"
[
# not yet: -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith"
case "${enableval}" in
yes) ;;
no) build_warnings="-w";;

View File

@ -1122,6 +1122,16 @@ extern int watchdog;
/* Hooks for alternate command interfaces. */
#ifdef UI_OUT
/* The name of the interpreter if specified on the command line. */
extern char *interpreter_p;
#endif
/* If a given interpreter matches INTERPRETER_P then it should update
command_loop_hook and init_ui_hook with the per-interpreter
implementation. */
/* FIXME: command_loop_hook and init_ui_hook should be moved here. */
struct target_waitstatus;
struct cmd_list_element;

View File

@ -246,6 +246,13 @@ display_gdb_prompt (char *new_prompt)
int prompt_length = 0;
char *gdb_prompt = get_prompt ();
#ifdef UI_OUT
/* When an alternative interpreter has been installed, do not
display the comand prompt. */
if (interpreter_p)
return;
#endif
if (target_executing && sync_execution)
{
/* This is to trick readline into not trying to display the

View File

@ -3223,6 +3223,13 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
case END_STEPPING_RANGE:
/* We are done with a step/next/si/ni command. */
/* For now print nothing. */
#ifdef UI_OUT
/* Print a message only if not in the middle of doing a "step n"
operation for n > 1 */
if (!step_multi || !stop_step)
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "end-stepping-range");
#endif
break;
case BREAKPOINT_HIT:
/* We found a breakpoint. */
@ -3232,6 +3239,8 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
/* The inferior was terminated by a signal. */
#ifdef UI_OUT
annotate_signalled ();
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "exited-signalled");
ui_out_text (uiout, "\nProgram terminated with signal ");
annotate_signal_name ();
ui_out_field_string (uiout, "signal-name", target_signal_to_name (stop_info));
@ -3264,12 +3273,16 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
annotate_exited (stop_info);
if (stop_info)
{
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "exited");
ui_out_text (uiout, "\nProgram exited with code ");
ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) stop_info);
ui_out_text (uiout, ".\n");
}
else
{
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_string (uiout, "reason", "exited-normally");
ui_out_text (uiout, "\nProgram exited normally.\n");
}
#else
@ -3445,7 +3458,17 @@ The same program may be running in another process.\n");
default:
internal_error ("Unknown value.");
}
#ifdef UI_OUT
/* For mi, have the same behavior every time we stop:
print everything but the source line. */
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
source_flag = LOC_AND_ADDRESS;
#endif
#ifdef UI_OUT
if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
ui_out_field_int (uiout, "thread-id", pid_to_thread_id (inferior_pid));
#endif
/* The behavior of this routine with respect to the source
flag is:
SRC_LINE: Print only source line

View File

@ -53,6 +53,11 @@ int display_space;
processes UI events asynchronously. */
int event_loop_p = 1;
#ifdef UI_OUT
/* Has an interpreter been specified and if so, which. */
char *interpreter_p;
#endif
/* Whether this is the command line version or not */
int tui_version = 0;
@ -260,9 +265,11 @@ captured_main (void *data)
{"enable-external-editor", no_argument, 0, 'y'},
{"editor-command", required_argument, 0, 'w'},
#endif
#ifdef UI_OUT
{"ui", required_argument, 0, 'i'},
{"interpreter", required_argument, 0, 'i'},
{"i", required_argument, 0, 'i'},
#endif
{"directory", required_argument, 0, 'd'},
{"d", required_argument, 0, 'd'},
{"cd", required_argument, 0, 11},
@ -373,6 +380,11 @@ captured_main (void *data)
break;
}
#endif /* GDBTK */
#ifdef UI_OUT
case 'i':
interpreter_p = optarg;
break;
#endif
case 'd':
dirarg[ndir++] = optarg;
if (ndir >= dirsize)

1346
gdb/mi/ChangeLog-mi Normal file

File diff suppressed because it is too large Load Diff

2513
gdb/mi/gdbmi.texinfo Normal file

File diff suppressed because it is too large Load Diff

253
gdb/mi/mi-cmd-break.c Normal file
View File

@ -0,0 +1,253 @@
/* MI Command Set - breakpoint and watchpoint commands.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

499
gdb/mi/mi-cmd-disas.c Normal file
View File

@ -0,0 +1,499 @@
/* MI Command Set - disassemble commands.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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, 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, 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);
print_address_numeric (pc, 1, stb->stream);
ui_out_field_stream (uiout, "address", stb);
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);
print_address_numeric (pc, 1, stb->stream);
ui_out_field_stream (uiout, "address", stb);
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: */

317
gdb/mi/mi-cmd-stack.c Normal file
View File

@ -0,0 +1,317 @@
/* MI Command Set - stack commands.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

474
gdb/mi/mi-cmd-var.c Normal file
View File

@ -0,0 +1,474 @@
/* MI Command Set - varobj commands.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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 void 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;
struct varobj *var;
char *name;
char *frame;
char *expr;
char *type;
struct cleanup *old_cleanups;
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)
frameaddr = -1;
else
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);
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() */
static void
varobj_update_one (struct varobj *var)
{
struct varobj **changelist;
struct varobj **cc;
int nc;
nc = varobj_update (var, &changelist);
if (nc <= 0)
return;
cc = changelist;
while (*cc != NULL)
{
ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
cc++;
}
free (changelist);
}
/* Local variables: */
/* change-log-default-name: "ChangeLog-mi" */
/* End: */

263
gdb/mi/mi-cmds.c Normal file
View File

@ -0,0 +1,263 @@
/* MI Command Set.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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},
{"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: */

128
gdb/mi/mi-cmds.h Normal file
View File

@ -0,0 +1,128 @@
/* MI Command Set.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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_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: */

118
gdb/mi/mi-console.c Normal file
View File

@ -0,0 +1,118 @@
/* MI Console code.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

31
gdb/mi/mi-console.h Normal file
View File

@ -0,0 +1,31 @@
/* MI Command Set - MI Console.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

80
gdb/mi/mi-getopt.c Normal file
View File

@ -0,0 +1,80 @@
/* MI Command Set - MI Option Parser.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

64
gdb/mi/mi-getopt.h Normal file
View File

@ -0,0 +1,64 @@
/* MI Option Parser.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

1446
gdb/mi/mi-main.c Normal file

File diff suppressed because it is too large Load Diff

401
gdb/mi/mi-out.c Normal file
View File

@ -0,0 +1,401 @@
/* MI Command Set - output generating routines.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

39
gdb/mi/mi-out.h Normal file
View File

@ -0,0 +1,39 @@
/* MI Command Set - MI output generating routines for GDB.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

243
gdb/mi/mi-parse.c Normal file
View File

@ -0,0 +1,243 @@
/* MI Command Set - MI parser.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

59
gdb/mi/mi-parse.h Normal file
View File

@ -0,0 +1,59 @@
/* MI Command Set - MI Command Parser.
Copyright (C) 2000, Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
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: */

View File

@ -1,3 +1,10 @@
Mon Feb 21 13:05:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
* configure.in (configdirs): Add sub directory gdb.mi.
* configure: Re-generate.
* gdb.mi: New directory.
2000-02-16 Jim Blandy <jimb@redhat.com>
* gdb.base/break.exp ("breakpoint line number"): Make sure the

View File

@ -654,6 +654,7 @@ configdirs="gdb.asm \
gdb.c++ \
gdb.disasm \
gdb.chill \
gdb.mi \
gdb.threads \
gdb.trace"

View File

@ -18,6 +18,7 @@ configdirs="gdb.asm \
gdb.c++ \
gdb.disasm \
gdb.chill \
gdb.mi \
gdb.threads \
gdb.trace"

View File

@ -0,0 +1,390 @@
2000-02-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-support.exp (mi_gdb_start): Update to recognize start up
message with 'UI_OUT' instead of 'HEADLESS'.
2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-regs.exp (test_running_the_program): Add global var 'hex'.
* mi-stack.exp, mi-stepi.exp, mi-until.exp, mi-watch.exp,
mi-var-display.exp, mi-var-cmd.exp, mi-var-child.exp,
mi-var-block.exp: Update all stopped messages.
2000-01-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-console.exp, mi-disassemble.exp, mi-eval.exp,
mi-read-memory.exp, mi-regs.exp, mi-return.exp, mi-simplerun.exp:
Update stopped messages, update copyright.
* mi-disassemble.exp: Update error messages output.
* mi-support.exp (proc mi_step): Make gdb do a 'step' command, not
a 'next'. Update stopped message.
(proc mi_next): Update stop message.
(proc mi_run_to_main): Update stopped message.
Update copyright.
2000-01-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-simplerun.exp: Remove stack frames tests from here, to:
* mi-stack.exp: New file, tests for stack commands.
* mi-support.exp (mi_run_to_main, mi_next, mi_step) : Update to
include thread-id in stopped message.
* mi-regs.exp: Update break-insert output.
* (mi-console.exp, mi-disassemble.exp, mi-eval.exp,
mi-read-memory.exp, mi-regs.exp, mi-return.exp, mi-simplerun.exp,
mi-stepi.exp, mi-until.exp, mi-var-block.exp, mi-var-child.exp,
mi-var-cmd.exp, mi-var-display.exp, mi-watch.exp): Update stopped
message to include thread-id.
Wed Dec 29 22:06:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-watch.exp, mi-var-display.exp, mi-var-cmd.exp,
mi-var-child.exp, mi-var-block.exp, mi-until.exp, mi-stepi.exp,
mi-simplerun.exp, mi-return.exp, mi-support.exp, mi-eval.exp,
mi-console.exp, mi-disassemble.exp, mi-break.exp: Update to
reflect extended output from -break-insert command.
* mi-break.exp (test_rbreak_creation_and_listing): XFAIL regexp
tests. -r flag broken by above.
Sun Dec 19 19:28:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
* cpp_variable.cc, cpp_variable.h, c_variable.c: Delete.
Fri Dec 17 20:59:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-read-memory.exp: Test of ``-o <offset>'' now works.
1999-12-16 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-var-cmd.exp: Fix 2 tests outputs.
* mi-var-child.exp: Add many more tests.
* mi-var-display.exp: Add many more tests.
* var-cmd.c: Change type of incr_a parameter to char.
1999-12-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-var-block.exp: Set up xfails fro known problems.
* mi-var-display.exp: Set up printing of values of 'e' and 'anone'
as xfails.
* mi-var-child.exp: Fix typos.
1999-12-15 Andrew Cagney <cagney@b1.cygnus.com>
* mi-var-child.exp: Space was missing before ``[10]''.
Wed Dec 15 19:23:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-read-memory.exp: Add test for ``-o <offset>''. Update checks
and match next-row et.al.
1999-12-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-var-display.exp : New file. Tests for format and type, with
unions, structs and enums.
* mi-var-cmd.exp: Add some var-assign tests.
1999-12-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-var-cmd.exp, mi-var-block.exp, mi-var-child.exp: New files
some tests for -var* commands.
* var-cmd.c: New source file for var-* commands tests.
* gdb.mi/Makefile.in (PROGS): Add var-cmd.
Mon Dec 13 18:06:09 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-break.exp: Fix quoting. Changed "srcfile.c":6 to
"\"srcfile.c\":6".
* mi-simplerun.exp: Fix quoting.
Sat Dec 11 21:33:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-simplerun.exp (exec-finish): Fix return value was zero,
should have been three.
* mi-disassemble.exp: Reduce number of wild card matches in
* patterns. Remove all numeric constants.
1999-12-09 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-eval.exp: New file. Some initial tests for
-data-evaluate-expression.
1999-12-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
* c_variable.c, cpp_variable.cc, cpp_variable.h: New files. Used
for testing "var" operations.
* Makefile.in: Add reference to the above files.
1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-regs.exp: Fix test for format 'N' for
data-list-register-values.
1999-12-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-disassemble.exp: Update expected output. Break test of
disassembly in mixed mode into 2 functions.
* mi-regs.exp: Initial register tests. Works only on sparc right
now.
1999-12-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-stepi.exp: New file. Tests exec-step-instruction and
exec-next-instruction.
* mi-until.exp: New file. Tests exec-until.
* until.c: New file.
* mi-return.exp: New file. Tests exec-return.
Thu Dec 2 09:38:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-hack-cli.exp: New test. Check the hacked up access to the
CLI.
Wed Dec 1 16:47:40 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-basics.exp: Delete calls to mi_delete_breakpoints,
mi_gdb_reinitialize_dir and mi_gdb_load. This test is checking
that these can work.
* mi-support.exp (mi_step, mi_next, mi_run_to_main): New
procedures.
* mi-read-memory.exp, mi-read-memory.c: New files. Test
data-read-memory command.
Tue Nov 30 23:54:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-support.exp: Don't start SID until after GDB has been started
and verified.
Tue Nov 30 22:21:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-support.exp (mi_uncatched_gdb_exit): When SID, call sid_exit.
(mi_gdb_start): When SID, call sid_start.
(mi_gdb_start): Add MIFLAGS to spawn-GDB command. Check for
HEADLESS gdb. Return non-zero when GDB fails to start.
(mi_gdb_load): When SID or SIM, download program.
(mi_run_cmd): Don't do download here. Assume target supports the
00-exec-run command.
(skip_mi_tests, setup_gdbmi, unset_gdbmi): Delete. Merged into
mi_gdb_start.
* mi-basics.exp, mi-break.exp, mi-console.exp, mi-disassemble.exp,
mi-simplerun.exp, mi-watch.exp: Update. Check status from
mi_gdb_start indicating that GDB started correctly.
Tue Nov 30 15:22:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-support.exp (setup_gdbmi, unset_gdbmi): New
procedures. Setup/unset dejagnu for mi tests.
* mi-basics.exp, mi-console.exp, mi-simplerun.exp, mi-break.exp,
mi-disassemble.exp, mi-watch.exp: Update.
1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-simplerun.exp (test_running_the_program): Remove XFAIL. The
output is fixed now.
(test_program_termination): Update output pattern.
Tue Nov 30 00:19:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-console.c, mi-console.exp: New files. Test console output.
Mon Nov 29 17:59:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-support.exp (mi_run_command): Check for exec-run command
failure due to MI not having an active target.
(mi_run_command): Check for and handle a builtin simulator target.
(mi_run_command): Don't check/handle for ``The program has been
started already'', not a valid MI response.
* mi-simplerun.exp (test_running_the_program): Update all patterns
to match async output.
(test_running_the_program): Mark ``step to callee4'' as XFAIL. MI
output contains {,reason="end-stepping-range"}+.
* mi-simplerun.exp: Limit the timeout for ``step to callee4'' to
30 seconds.
Mon Nov 29 17:30:00 1999 Andrew Cagney <cagney@b1.cygnus.com>
* mi-support.exp (skip_mi_tests): Print UNTESTED when MI interface
isn't available. Start/stop instead of assuming GDB is running.
(MIFLAGS): Define.
* mi-simplerun.exp, mi-disassemble.exp, mi-break.exp,
mi-basics.exp, mi-watch.exp: Update.
1999-11-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* mi-simplerun.exp: Move break-insert {-t, -r} from here.
* mi-break.exp: To here. New file.
* mi-watch.exp: New file. Tests for watchpoints.
Wed Nov 24 17:42:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
* gdb.mi/ChangeLog-mi: MI entries moved to here.
Wed Nov 24 17:31:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
* gdb.mi/mi-basics.exp, gdb.mi/mi-disassemble.exp,
gdb.mi/mi-simplerun.exp: Print warning message when test isn't
run.
1999-11-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* gdb.mi/mi-simplerun.exp: Update output of break-list to account for
"times" field.
1999-11-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* gdb.mi/mi-simplerun.exp: Add tests for temporary breakpoints
and bp based on regular expressions.
* gdb.mi/mi-disassemble.exp: Fix typo.
1999-11-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* gdb.mi/mi-disassemble.exp: Update output of execution commands
to reflect new 'reason' field.
* gdb.mi/mi-simplerun.exp: Ditto.
1999-10-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* gdb.mi/mi-simplerun.exp: Add more stack-list-frames tests.
* gdb.mi/mi-disassemble.exp: Update 'run to main' output.
* gdb.mi/mi-simplerun.exp: Update execution commands
output. Update backtrace output.
1999-10-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* gdb.mi/mi-disassemble.exp: Add new tests for the new
disassembly command parameter, number of lines.
Mon Oct 11 13:57:21 1999 Andrew Cagney <cagney@amy.cygnus.com>
* lib/mi-support.exp: Break complicated gdb_expect containing
exp_continue into a while within an expect. Don't attempt a start
more than three times. Check return value from gdb_load.
1999-10-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
* gdb.mi/mi-disassemble.exp: New file.
Wed Oct 6 12:05:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
* lib/mi-support.exp (mi_run_cmd): Give up after two restart
attempts.
1999-09290 Fernando Nasser <fnasser@totem.to.cygnus.com>
* gdb.mi/mi-basics.exp: Update to current syntax and output formats.
* gdb.mi/mi-simplerun.exp: Ditto.
* lib/mi-support.exp (mi_delete_breakpoints): Ditto.
1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
* gdb.mi/basics.c (main): Fix return code. Add a print "Hello,
World".
* gdb.mi/mi-basics.exp: Fix message texts and numbering.
* gdb.mi/mi-simplerun.exp: Ditto. Also, add new tests and improve
some patterns.
1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
* lib/mi-support.exp (mi_gdb_reinitialize_dir): Remove query as an
acceptable response to the environment-dir command.
1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
* lib/mi-support.exp (mi_delete_breakpoints): Remove references to
gdb-cli.
(mi_run_cmd): Ditto.
1999-06-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
* lib/mi-support.exp (skip_mi_tests): Use gdb-version to check for
headless output format.
1999-06-24 Fernando Nasser <fnasser@totem.to.cygnus.com>
* gdb.mi/mi-simplerun.exp (test_controlled_execution): Add global
spec for hex.
1999-06-24 Fernando Nasser <fnasser@totem.to.cygnus.com>
* lib/mi-support.exp (mi_run_cmd): Fix pattern and add a timeout
clause.
1999-06-24 Fernando Nasser <fnasser@totem.to.cygnus.com>
* lib/mi-support.exp: Use mi_gdb_prompt instead of a modified
gdb_prompt. Remove uneeded loading of libgloss.
(mi_gdb_exit): Remove prompt argument.
(mi_uncatched_gdb_exit): Ditto.
(mi_run_cmd): New proc. MI version of gdb_run.
(skip_mi_tests): New proc. Check if gdb is capable of producing
headless formatted output.
* gdb.mi/mi-basics.exp: Use mi_gdb_prompt instead of a modified
gdb_prompt. Eliminate parameter to mi_gdb_exit (as a result of
the above). Test for skip_mi_tests before running.
Note: The above changes are interelated (need each other).
* gdb.mi/mi-simplerun.exp: Same changes as for mi-basics.exe
above.
(test_breakpoint_creation_and_listing): Remove insertion of
breakpoint at callee1 (and renumber tokens). Add tests for
break-list, break-disable and break-info.
(test_running_the_program): Use mi_run_cmd so it can run on remote
targets.
(test_controlled_execution): Fix broken test.
(test_program_termination): Test implemented.
* gdb.mi/basic.c (main): Small change to allow for testing of both
exec-next and exec-step operations.
1999-06-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
* lib/mi-support.exp (mi_gdb_test): New proc. MI version of gdb_test.
* gdb.mi/mi-basics.exp: Use the above instead of gdb_test.
* gdb.mi/mi-simplerun.exp: Ditto.
1999-06-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
* gdb.mi/mi-simplerun.exp: New file. Tests simple debugging tasks.
* gdb.mi/mi-basics.exp: Remove tests moved to above new file.
* lib/mi-support.exp: New file. Support procedures for mi tests.
1999-06-08 Fernando Nasser <fnasser@totem.to.cygnus.com>
* gdb.mi/mi-basics.exp: Skip all tests if the MI interpreter is
not active.
1999-06-03 Fernando Nasser <fnasser@totem.to.cygnus.com>
* gdb.mi: New directory.
* configure.in: Configure it.
* configure: Regenerate.
* gdb.mi/{Makefile.in,configure.in,configure}: New files.
* gdb.mi/{mi-basics.exp,basics.c,testcmds}: New files.
Local Variables:
mode: indented-text
left-margin: 8
fill-column: 74
version-control: never
End:

View File

@ -0,0 +1,20 @@
VPATH = @srcdir@
srcdir = @srcdir@
PROGS = basics c_variable cpp_variable var-cmd
MISCELLANEOUS = testcmds
all:
@echo "Nothing to be done for all..."
#### host, target, and site specific Makefile frags come in here.
clean mostlyclean:
-rm -f *.ci *.o $(OBJS) $(PROGS) $(MISCELLANEOUS) *~ core
distclean maintainer-clean realclean: clean
-rm -f Makefile config.status config.log
Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
$(SHELL) ./config.status --recheck

View File

@ -0,0 +1,41 @@
/*
* This simple program that passes different types of arguments
* on function calls. Useful to test printing frames, stepping, etc.
*/
callee4 (void)
{
int A=1;
int B=2;
int C;
C = A + B;
}
callee3 (char *strarg)
{
callee4 ();
}
callee2 (int intarg, char *strarg)
{
callee3 (strarg);
}
callee1 (int intarg, char *strarg, double fltarg)
{
callee2 (intarg, strarg);
}
main ()
{
callee1 (2, "A string argument.", 3.5);
callee1 (2, "A string argument.", 3.5);
printf ("Hello, World!");
return 0;
}

902
gdb/testsuite/gdb.mi/configure vendored Executable file
View File

@ -0,0 +1,902 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.13
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
# Defaults:
ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
# Initialize some variables set by options.
# The variables have the same names as the options, with
# dashes changed to underlines.
build=NONE
cache_file=./config.cache
exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document.
ac_max_here_lines=12
ac_prev=
for ac_option
do
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
ac_prev=
continue
fi
case "$ac_option" in
-*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) ac_optarg= ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
case "$ac_option" in
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
bindir="$ac_optarg" ;;
-build | --build | --buil | --bui | --bu)
ac_prev=build ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
build="$ac_optarg" ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
cache_file="$ac_optarg" ;;
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
datadir="$ac_optarg" ;;
-disable-* | --disable-*)
ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
eval "enable_${ac_feature}=no" ;;
-enable-* | --enable-*)
ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
case "$ac_option" in
*=*) ;;
*) ac_optarg=yes ;;
esac
eval "enable_${ac_feature}='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
ac_prev=exec_prefix ;;
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
exec_prefix="$ac_optarg" ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
-help | --help | --hel | --he)
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat << EOF
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
--cache-file=FILE cache test results in FILE
--help print this message
--no-create do not create output files
--quiet, --silent do not print \`checking...' messages
--version print the version of autoconf that created configure
Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[same as prefix]
--bindir=DIR user executables in DIR [EPREFIX/bin]
--sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
--libexecdir=DIR program executables in DIR [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data in DIR
[PREFIX/share]
--sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data in DIR
[PREFIX/com]
--localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
--libdir=DIR object code libraries in DIR [EPREFIX/lib]
--includedir=DIR C header files in DIR [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
--infodir=DIR info documentation in DIR [PREFIX/info]
--mandir=DIR man documentation in DIR [PREFIX/man]
--srcdir=DIR find the sources in DIR [configure dir or ..]
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM
run sed PROGRAM on installed program names
EOF
cat << EOF
Host type:
--build=BUILD configure for building on BUILD [BUILD=HOST]
--host=HOST configure for HOST [guessed]
--target=TARGET configure for TARGET [TARGET=HOST]
Features and packages:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--x-includes=DIR X include files are in DIR
--x-libraries=DIR X library files are in DIR
EOF
if test -n "$ac_help"; then
echo "--enable and --with options recognized:$ac_help"
fi
exit 0 ;;
-host | --host | --hos | --ho)
ac_prev=host ;;
-host=* | --host=* | --hos=* | --ho=*)
host="$ac_optarg" ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
includedir="$ac_optarg" ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
infodir="$ac_optarg" ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
libdir="$ac_optarg" ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
libexecdir="$ac_optarg" ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
| --locals | --local | --loca | --loc | --lo)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
localstatedir="$ac_optarg" ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
mandir="$ac_optarg" ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
-oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
| --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
| --oldin | --oldi | --old | --ol | --o)
ac_prev=oldincludedir ;;
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
oldincludedir="$ac_optarg" ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
prefix="$ac_optarg" ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
program_prefix="$ac_optarg" ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
program_suffix="$ac_optarg" ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
| --program-transform-n | --program-transform- \
| --program-transform | --program-transfor \
| --program-transfo | --program-transf \
| --program-trans | --program-tran \
| --progr-tra | --program-tr | --program-t)
ac_prev=program_transform_name ;;
-program-transform-name=* | --program-transform-name=* \
| --program-transform-nam=* | --program-transform-na=* \
| --program-transform-n=* | --program-transform-=* \
| --program-transform=* | --program-transfor=* \
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name="$ac_optarg" ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
sbindir="$ac_optarg" ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
| --sharedst | --shareds | --shared | --share | --shar \
| --sha | --sh)
ac_prev=sharedstatedir ;;
-sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
sharedstatedir="$ac_optarg" ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
site="$ac_optarg" ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir="$ac_optarg" ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
sysconfdir="$ac_optarg" ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
target="$ac_optarg" ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
echo "configure generated by autoconf version 2.13"
exit 0 ;;
-with-* | --with-*)
ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
case "$ac_option" in
*=*) ;;
*) ac_optarg=yes ;;
esac
eval "with_${ac_package}='$ac_optarg'" ;;
-without-* | --without-*)
ac_package=`echo $ac_option|sed -e 's/-*without-//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
eval "with_${ac_package}=no" ;;
--x)
# Obsolete; use --with-x.
with_x=yes ;;
-x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
| --x-incl | --x-inc | --x-in | --x-i)
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
x_includes="$ac_optarg" ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries="$ac_optarg" ;;
-*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
;;
*)
if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
echo "configure: warning: $ac_option: invalid host type" 1>&2
fi
if test "x$nonopt" != xNONE; then
{ echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
fi
nonopt="$ac_option"
;;
esac
done
if test -n "$ac_prev"; then
{ echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
fi
trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
# File descriptor usage:
# 0 standard input
# 1 file creation
# 2 errors and warnings
# 3 some systems may open it to /dev/tty
# 4 used on the Kubota Titan
# 6 checking for... messages and results
# 5 compiler messages saved in config.log
if test "$silent" = yes; then
exec 6>/dev/null
else
exec 6>&1
fi
exec 5>./config.log
echo "\
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
" 1>&5
# Strip out --no-create and --no-recursion so they do not pile up.
# Also quote any args containing shell metacharacters.
ac_configure_args=
for ac_arg
do
case "$ac_arg" in
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c) ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
ac_configure_args="$ac_configure_args '$ac_arg'" ;;
*) ac_configure_args="$ac_configure_args $ac_arg" ;;
esac
done
# NLS nuisances.
# Only set these to C if already set. These must not be set unconditionally
# because not all systems understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo > confdefs.h
# A filename unique to this package, relative to the directory that
# configure is in, which we can look for to find out if srcdir is correct.
ac_unique_file=mi-basics.exp
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
ac_prog=$0
ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
{ echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
else
{ echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
fi
fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
if test "x$prefix" != xNONE; then
CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
else
CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
fi
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
echo "loading site script $ac_site_file"
. "$ac_site_file"
fi
done
if test -r "$cache_file"; then
echo "loading cache $cache_file"
. $cache_file
else
echo "creating cache $cache_file"
> $cache_file
fi
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
ac_exeext=
ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
ac_n= ac_c='
' ac_t=' '
else
ac_n=-n ac_c= ac_t=
fi
else
ac_n= ac_c='\c' ac_t=
fi
CC=${CC-cc}
ac_aux_dir=
for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
if test -f $ac_dir/install-sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install-sh -c"
break
elif test -f $ac_dir/install.sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install.sh -c"
break
fi
done
if test -z "$ac_aux_dir"; then
{ echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
fi
ac_config_guess=$ac_aux_dir/config.guess
ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# Do some error checking and defaulting for the host and target type.
# The inputs are:
# configure --host=HOST --target=TARGET --build=BUILD NONOPT
#
# The rules are:
# 1. You are not allowed to specify --host, --target, and nonopt at the
# same time.
# 2. Host defaults to nonopt.
# 3. If nonopt is not specified, then host defaults to the current host,
# as determined by config.guess.
# 4. Target and build default to nonopt.
# 5. If nonopt is not specified, then target and build default to host.
# The aliases save the names the user supplied, while $host etc.
# will get canonicalized.
case $host---$target---$nonopt in
NONE---*---* | *---NONE---* | *---*---NONE) ;;
*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
esac
# Make sure we can run config.sub.
if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
echo "configure:575: checking host system type" >&5
host_alias=$host
case "$host_alias" in
NONE)
case $nonopt in
NONE)
if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
fi ;;
*) host_alias=$nonopt ;;
esac ;;
esac
host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6
echo $ac_n "checking target system type""... $ac_c" 1>&6
echo "configure:596: checking target system type" >&5
target_alias=$target
case "$target_alias" in
NONE)
case $nonopt in
NONE) target_alias=$host_alias ;;
*) target_alias=$nonopt ;;
esac ;;
esac
target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
echo "configure:614: checking build system type" >&5
build_alias=$build
case "$build_alias" in
NONE)
case $nonopt in
NONE) build_alias=$host_alias ;;
*) build_alias=$nonopt ;;
esac ;;
esac
build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$build" 1>&6
test "$host_alias" != "$target_alias" &&
test "$program_prefix$program_suffix$program_transform_name" = \
NONENONEs,x,x, &&
program_prefix=${target_alias}-
trap '' 1 2 15
cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs. It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already. You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#
EOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote substitution
# turns \\\\ into \\, and sed turns \\ into \).
sed -n \
-e "s/'/'\\\\''/g" \
-e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
;;
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
;;
esac >> confcache
if cmp -s $cache_file confcache; then
:
else
if test -w $cache_file; then
echo "updating cache $cache_file"
cat confcache > $cache_file
else
echo "not updating unwritable cache $cache_file"
fi
fi
rm -f confcache
trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
# Any assignment to VPATH causes Sun make to only execute
# the first set of double-colon rules, so remove it if not needed.
# If there is a colon in the path, we need to keep it.
if test "x$srcdir" = x.; then
ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
fi
trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
cat > conftest.defs <<\EOF
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
s%\[%\\&%g
s%\]%\\&%g
s%\$%$$%g
EOF
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
rm -f conftest.defs
# Without the "./", some shells look in PATH for config.status.
: ${CONFIG_STATUS=./config.status}
echo creating $CONFIG_STATUS
rm -f $CONFIG_STATUS
cat > $CONFIG_STATUS <<EOF
#! /bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
#
# $0 $ac_configure_args
#
# Compiler output produced by configure, useful for debugging
# configure, is in ./config.log if it exists.
ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
do
case "\$ac_option" in
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
*) echo "\$ac_cs_usage"; exit 1 ;;
esac
done
ac_given_srcdir=$srcdir
trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
# Protect against being on the right side of a sed subst in config.status.
sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
s%@bindir@%$bindir%g
s%@sbindir@%$sbindir%g
s%@libexecdir@%$libexecdir%g
s%@datadir@%$datadir%g
s%@sysconfdir@%$sysconfdir%g
s%@sharedstatedir@%$sharedstatedir%g
s%@localstatedir@%$localstatedir%g
s%@libdir@%$libdir%g
s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@CC@%$CC%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
s%@host_vendor@%$host_vendor%g
s%@host_os@%$host_os%g
s%@target@%$target%g
s%@target_alias@%$target_alias%g
s%@target_cpu@%$target_cpu%g
s%@target_vendor@%$target_vendor%g
s%@target_os@%$target_os%g
s%@build@%$build%g
s%@build_alias@%$build_alias%g
s%@build_cpu@%$build_cpu%g
s%@build_vendor@%$build_vendor%g
s%@build_os@%$build_os%g
CEOF
EOF
cat >> $CONFIG_STATUS <<\EOF
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=""
while $ac_more_lines; do
if test $ac_beg -gt 1; then
sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
else
sed "${ac_end}q" conftest.subs > conftest.s$ac_file
fi
if test ! -s conftest.s$ac_file; then
ac_more_lines=false
rm -f conftest.s$ac_file
else
if test -z "$ac_sed_cmds"; then
ac_sed_cmds="sed -f conftest.s$ac_file"
else
ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
fi
ac_file=`expr $ac_file + 1`
ac_beg=$ac_end
ac_end=`expr $ac_end + $ac_max_sed_cmds`
fi
done
if test -z "$ac_sed_cmds"; then
ac_sed_cmds=cat
fi
EOF
cat >> $CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
*:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
# Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
# The file is in a subdirectory.
test ! -d "$ac_dir" && mkdir "$ac_dir"
ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
# A "../" for each directory in $ac_dir_suffix.
ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
else
ac_dir_suffix= ac_dots=
fi
case "$ac_given_srcdir" in
.) srcdir=.
if test -z "$ac_dots"; then top_srcdir=.
else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
/*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
*) # Relative path.
srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
top_srcdir="$ac_dots$ac_given_srcdir" ;;
esac
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
case "$ac_file" in
*Makefile*) ac_comsub="1i\\
# $configure_input" ;;
*) ac_comsub= ;;
esac
ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
rm -f conftest.s*
EOF
cat >> $CONFIG_STATUS <<EOF
EOF
cat >> $CONFIG_STATUS <<\EOF
exit 0
EOF
chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1

View File

@ -0,0 +1,15 @@
dnl Process this file file with autoconf to produce a configure script.
dnl This file is a shell script fragment that supplies the information
dnl necessary to tailor a template configure script into the configure
dnl script appropriate for this directory. For more information, check
dnl any existing configure script.
AC_PREREQ(2.5)
AC_INIT(mi-basics.exp)
CC=${CC-cc}
AC_SUBST(CC)
AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
AC_CANONICAL_SYSTEM
AC_OUTPUT(Makefile)

View File

@ -0,0 +1,177 @@
# Copyright (C) 1999 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# test basic Machine interface (MI) operations
#
# Verify that, using the MI, we can load a program and do
# other basic things that are used by all test files through mi_gdb_exit,
# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
# mi_gdb_load, so we can safely use those.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but the command syntax and correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
# In this file we want to test if the operations needed by the following
# procedures work, so it makes no sense using them here.
# mi_delete_breakpoints
# mi_gdb_reinitialize_dir $srcdir/$subdir
# mi_gdb_load ${binfile}
# Test if the MI interpreter has been configured
proc test_mi_interpreter_selection {} {
global mi_gdb_prompt
global gdb_prompt
# All this test expects is to get the prompt back
# with no syntax error message
send_gdb "-gdb-version\n"
gdb_expect {
-re "GNU gdb .*\r\n$mi_gdb_prompt$" \
{ pass "acceptance of MI operations"
return 1}
-re ".*\r\n$mi_gdb_prompt$" \
{ fail "acceptance of MI operations"
note "Skipping all other MI tests." }
-re "Undefined command.*$gdb_prompt $" \
{ fail "acceptance of MI operations"
note "Skipping all other MI tests." }
-re ".*$gdb_prompt $" \
{ fail "acceptance of MI operations"
note "Skipping all other MI tests." }
timeout { fail "acceptance of MI operations (timeout)"
note "Skipping all other MI tests." }
}
return 0
}
proc test_exec_and_symbol_mi_operatons {} {
global mi_gdb_prompt
global binfile
# Load symbols and specify executable on a single operation
# Tests:
# -file-exec-and-symbols
# Can't use mi_gdb_test as if this doesn't work,
# we must give up on the whole test file
send_gdb "-file-exec-and-symbols ${binfile}\n"
gdb_expect {
-re "\[\r\n\]*\\\^done\r\n$mi_gdb_prompt$" \
{ pass "file-exec-and-symbols operation" }
timeout { fail "file-exec-and-symbols operation (timeout)"
note "Skipping all other MI tests."
return 0}
}
# The following is not used by mi-support.exp, but we test here so
# we get done with loading a program basics.
# Do it again, but now load symbols and specify executable with
# two separate operations
# Tests:
# -file-clear
# -file-exec-file
# -file-symbol-file
# FIXME: file-clear is not implemented yet.
mi_gdb_test "-file-clear" \
"\\\^done" \
"file-clear operation"
mi_gdb_test "-file-exec-file ${binfile}" \
"\\\^done" \
"file-exec-file operation"
mi_gdb_test "-file-symbol-file ${binfile}" \
"\\\^done" \
"file-symbol-file operation"
# FIXME: if we cannot load we have to skip all other tests.
}
proc test_breakpoints_deletion {} {
global mi_gdb_prompt
global srcfile
# Clear all breakpoints and list to confirm
# Tests:
# -break-delete (all)
# -break-list
# The all parameter is actually no parameter.
mi_gdb_test "200-break-delete" \
"\\\^done" \
"break-delete (all) operation"
mi_gdb_test "201-break-list" \
".*\\\^done,BreakpointTable=\\\{\\\}" \
"all breakpoints removed"
}
proc test_dir_specification {} {
global mi_gdb_prompt
global srcdir
global subdir
# Clear the search directories, then specify one to be searched
# Tests:
# -environment-directory
# -environment-directory arg
#exp_internal 1
mi_gdb_test "202-environment-directory" \
"\\\^done" \
"environment-directory operation"
mi_gdb_test "203-environment-directory ${srcdir}/${subdir}" \
"\\\^done" \
"environment-directory arg operation"
#exp_internal 0
}
if [test_mi_interpreter_selection] {
test_exec_and_symbol_mi_operatons
test_breakpoints_deletion
test_dir_specification
}
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,141 @@
# Copyright (C) 1999 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can run a simple program and perform basic
# debugging activities like: insert breakpoints, run the program,
# step, next, continue until it ends and, last but not least, quit.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_tbreak_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert some breakpoints and list them
# Also, disable some so they do not interfere with other tests
# Tests:
# -break-insert -t main
# -break-insert -t basics.c:callee2
# -break-insert -t basics.c:15
# -break-insert -t srcfile:6
# -break-list
mi_gdb_test "222-break-insert -t main" \
"222\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
"break-insert -t operation"
mi_gdb_test "333-break-insert -t basics.c:callee2" \
"333\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
"insert temp breakpoint at basics.c:callee2"
mi_gdb_test "444-break-insert -t basics.c:15" \
"444\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
"insert temp breakpoint at basics.c:15 (callee3)"
# Getting the quoting right is tricky. That is "\"<file>\":6"
mi_gdb_test "555-break-insert -t \"\\\"${srcfile}\\\":6\"" \
"555\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
"insert temp breakpoint at \"<fullfilename>\":6 (callee4)"
mi_gdb_test "666-break-list" \
"666\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
"list of breakpoints"
mi_gdb_test "777-break-delete" \
"777\\^done" \
"delete temp breakpoints"
}
proc test_rbreak_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert some breakpoints and list them
# Also, disable some so they do not interfere with other tests
# Tests:
# -break-insert -r main
# -break-insert -r callee2
# -break-insert -r callee
# -break-insert -r .*llee
# -break-list
setup_xfail "*-*-*"
mi_gdb_test "122-break-insert -r main" \
"122\\^done,bkpt=\{number=\"5\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
"break-insert -r operation"
setup_xfail "*-*-*"
mi_gdb_test "133-break-insert -r callee2" \
"133\\^done,bkpt=\{number=\"6\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\}" \
"insert breakpoint with regexp callee2"
setup_xfail "*-*-*"
mi_gdb_test "144-break-insert -r callee" \
"144\\^done,bkpt=\{number=\"7\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"8\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"9\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"10\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
"insert breakpoint with regexp callee"
setup_xfail "*-*-*"
mi_gdb_test "155-break-insert -r \.\*llee" \
"155\\^done,bkpt=\{number=\"11\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"12\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"13\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"14\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
"insert breakpoint with regexp .*llee"
setup_xfail "*-*-*"
mi_gdb_test "166-break-list" \
"166\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
"list of breakpoints"
mi_gdb_test "177-break-delete" \
"177\\^done" \
"delete temp breakpoints"
}
test_tbreak_creation_and_listing
test_rbreak_creation_and_listing
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,20 @@
void
hello ()
{
char *hello = "Hello \\\"!\r\n";
int i;
for (i = 0; hello[i]; i++)
write (1, hello + i, 1);
}
int
main ()
{
hello ();
}
/*
Local variables:
change-log-default-name: "ChangeLog-mi"
End:
*/

View File

@ -0,0 +1,101 @@
# Copyright (C) 1999, 2000 Cygnus Solutions.
# 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can run a simple program and perform basic
# debugging activities like: insert breakpoints, run the program,
# step, next, continue until it ends and, last but not least, quit.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
# This test only works when talking to a target that routes its output
# through GDB. Check that we're either talking to a simulator or a
# remote target.
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "mi-console"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
# Halt in main
mi_gdb_test "200-break-insert main" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*mi-console.c\",line=\"13\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
gdb_expect {
-re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*mi-console.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
pass "run to main"
}
timeout {
fail "run to main (timeout)"
}
}
# Next over the hello() call which will produce lots of output
send_gdb "47-exec-next\n"
gdb_expect {
-re "47\\^running\r\n$mi_gdb_prompt" {
pass "Started step over hello"
}
timeout {
fail "Started step over hello (timeout)"
}
}
gdb_expect {
-re "@\"H\"\r\n.*@\"e\"\r\n.*@\"l\"\r\n.*@\"l\"\r\n.*@\"o\"\r\n.*@\" \"\r\n.*@\"\\\\\\\\\"\r\n.*@\"\\\\\"\"\r\n.*@\"!\"\r\n.*@\"\\\\r\"\r\n.*@\"\\\\n\"\r\n" {
pass "Hello message"
}
timeout {
fail "Hello message (timeout)"
}
}
gdb_expect {
-re "47\\*stopped.*$mi_gdb_prompt$" {
pass "Finished step over hello"
}
timeout {
fail "Finished step over hello (timeout)"
}
}
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,295 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test Machine interface (MI) operations for disassembly.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_breakpoints_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert some breakpoints and list them
# Also, disable some so they do not interfere with other tests
# Tests:
# -break-insert
# -break-list
# -break-disable
# -break-info
mi_gdb_test "200-break-insert main" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
"break-insert operation"
mi_gdb_test "204-break-list" \
"204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\}" \
"list of breakpoints"
}
proc test_running_the_program {} {
global mi_gdb_prompt
global hex
# Run the program without args
# Tests:
# -exec-run
# mi_gdb_test cannot be used for asynchronous commands because there are
# two prompts involved and this can lead to a race condition.
# FIXME: We are accepting a duplicate file and line info temporarely.
# The following is equivalent to a send_gdb "000-exec-run\n"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
pass "run to main"
}
-re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
timeout {fail "run to main (timeout 2)"}
}
}
proc test_disassembly_only {} {
global mi_gdb_prompt
global hex
# Test disassembly more only for the current function.
# Tests:
# -data-disassembly $pc 0 0 -1
# -data-disassembly main 0 0 -1
# -data-disassembly $pc $pc+8 0 -1
# -data-disassembly callee2 0 0 -1
mi_gdb_test "print/x \$pc" "" ""
mi_gdb_test "111-data-disassemble \$pc 0 0 -1" \
"111\\^done,asm_insns=\{\{address=\"$hex <main>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},.*\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble from pc assembly only"
mi_gdb_test "222-data-disassemble main 0 0 -1" \
"222\\^done,asm_insns=\{\{address=\"$hex <main>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble main assembly only"
mi_gdb_test "333-data-disassemble \$pc \$pc+8 0 -1" \
"333\\^done,asm_insns=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble range assembly only"
mi_gdb_test "444-data-disassemble callee2 0 0 -1" \
"444\\^done,asm_insns=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\},.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble callee2 assembly only"
}
proc test_disassembly_lines_limit {} {
global mi_gdb_prompt
global hex
# Test disassembly more only for the current function.
# Tests:
# -data-disassembly $pc 0 0 2
# -data-disassembly main 0 0 1
# -data-disassembly main 0 0 0
# -data-disassembly $pc $pc+8 0 99
# -data-disassembly $pc $pc+12 0 2
mi_gdb_test "print/x \$pc" "" ""
mi_gdb_test "100-data-disassemble \$pc 0 0 2" \
"100\\^done,asm_insns=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble from pc two lines - assembly only"
mi_gdb_test "200-data-disassemble main 0 0 1" \
"200\\^done,asm_insns=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble main 1 line - assembly only"
mi_gdb_test "300-data-disassemble main 0 0 0" \
"300\\^done,asm_insns=\{\}" \
"data-disassemble main zero lines - assembly only"
mi_gdb_test "400-data-disassemble \$pc \$pc+8 0 99" \
"400\\^done,asm_insns=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble lines bigger than range - assembly only"
mi_gdb_test "500-data-disassemble \$pc \$pc+12 0 2" \
"500\\^done,asm_insns=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
"data-disassemble lines less than range - assembly only"
}
proc test_disassembly_mixed {} {
global mi_gdb_prompt
global hex
global decimal
# Test disassembly more only for the current function.
# Tests:
# -data-disassembly main 0 1 -1
# -data-disassembly $pc $pc+8 1 -1
# -data-disassembly callee2 0 1 -1
mi_gdb_test "002-data-disassemble callee2 0 1 -1" \
"002\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\}\}\},src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble callee2 assembly mixed"
#
# In mixed mode, the lowest level of granularity is the source line.
# So we are going to get the disassembly for the source line at
# which we are now.
#
mi_gdb_test "003-data-disassemble \$pc \$pc+8 1 -1" \
"003\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}.*\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble range assembly mixed"
mi_gdb_test "004-data-disassemble callee2 0 1 -1" \
"004\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\}\}\},.*src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble callee2 assembly mixed"
}
proc test_disassembly_mixed_lines_limit {} {
global mi_gdb_prompt
global hex
global decimal
# Test disassembly more only for the current function.
# Tests:
# -data-disassembly $pc 0 1 2
# -data-disassembly main 0 1 1
# -data-disassembly main 0 1 0
# -data-disassembly $pc $pc+4 1 99
# -data-disassembly $pc $pc+12 1 2
mi_gdb_test "print/x \$pc" "" ""
mi_gdb_test "100-data-disassemble \$pc 0 1 2" \
"100\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\}\}\},src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble from pc two lines - assembly mixed"
mi_gdb_test "200-data-disassemble main 0 1 1" \
"200\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble main 1 line - assembly mixed"
mi_gdb_test "300-data-disassemble main 0 1 0" \
"300\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\}\}\}" \
"data-disassemble main zero lines - assembly mixed"
mi_gdb_test "400-data-disassemble \$pc \$pc+4 1 99" \
"400\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}.*\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble lines bigger than range - assembly mixed"
mi_gdb_test "500-data-disassemble \$pc \$pc+12 1 2" \
"500\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble lines less than range - assembly mixed"
}
proc test_disassembly_bogus_args {} {
global mi_gdb_prompt
global hex
# Test that bogus input to disassembly command is rejected.
# Tests:
# -data-disassembly 0 0 0 0
# -data-disassembly 0 0 0
# -data-disassembly 0 0
# -data-disassembly 0
mi_gdb_test "123-data-disassemble 0 0 0 0" \
".*123\\^error,msg=\"No function contains specified address\"" \
"data-disassemble bogus arguments"
mi_gdb_test "321-data-disassemble 0 0 0" \
"321\\^error,msg=\"mi_cmd_disassemble: Usage: start_address end_address mixed_mode num_of_lines.\"" \
"data-disassemble wrong num of args (3)"
mi_gdb_test "456-data-disassemble 0 0" \
"456\\^error,msg=\"mi_cmd_disassemble: Usage: start_address end_address mixed_mode num_of_lines.\"" \
"data-disassemble wrong num of args (2)"
mi_gdb_test "789-data-disassemble 0" \
"789\\^error,msg=\"mi_cmd_disassemble: Usage: start_address end_address mixed_mode num_of_lines.\"" \
"data-disassemble wrong num of args (1)"
}
proc test_disassembly_mixed_from_pc {} {
global mi_gdb_prompt
global hex
global decimal
# Test disassembly more only for the current function.
# Tests:
# -data-disassembly $pc 0 1 -1
mi_gdb_test "200-break-insert callee2" \
"200\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
"break-insert operation for mixed"
send_gdb "123-exec-continue\n"
gdb_expect {
-re "123\\^running\r\n$mi_gdb_prompt" {
gdb_expect {
-re "\[\r\n\]*123\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee2\",args=\{.*\},file=\".*basics.c\",line=\"22\"\}\r\n$mi_gdb_prompt$" {
pass "run to callee2"
}
-re ".*$mi_gdb_prompt$" {fail "run to callee2 (2)"}
timeout {fail "run to callee2 (timeout 2)"}
}
}
-re ".*$mi_gdb_prompt$" {fail "continue to callee2 (1)"}
timeout {fail "continue to callee2 (timeout 1)"}
}
mi_gdb_test "001-data-disassemble \$pc 0 1 -1" \
"001\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\}\}\},src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
"data-disassemble from pc assembly mixed"
}
test_breakpoints_creation_and_listing
test_running_the_program
test_disassembly_only
test_disassembly_mixed
test_disassembly_bogus_args
test_disassembly_lines_limit
test_disassembly_mixed_lines_limit
test_disassembly_mixed_from_pc
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,105 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test essential Machine interface (MI) operations
#
# Verify -data-evaluate-expression. There are really minimal tests.
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_running_the_program {} {
global mi_gdb_prompt
global hex
# Run the program without args, then specify srgs and rerun the program
# Tests:
# -exec-run
mi_gdb_test "300-break-insert callee4" \
"300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
"insert breakpoint at callee4"
# mi_gdb_test cannot be used for asynchronous commands because there are
# two prompts involved and this can lead to a race condition.
# The following is equivalent to a send_gdb "000-exec-run\n"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
{ pass "run to callee4" }
-re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
timeout {fail "run to callee4 (timeout 2)"}
}
send_gdb "101-exec-next\n"
gdb_expect {
-re "101\\^running\r\n$mi_gdb_prompt" {
gdb_expect {
-re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"9\"\}\r\n$mi_gdb_prompt$" \
{ pass "next in callee4" }
-re ".*$mi_gdb_prompt$" {fail "next in callee4 (2)"}
timeout {fail "next in callee4 (timeout 2)"}
}
}
-re ".*$mi_gdb_prompt$" {fail "next in callee4 (1)"}
timeout {fail "next in callee4 (timeout 1)"}
}
}
test_running_the_program
mi_gdb_test "211-data-evaluate-expression A" "211\\^done,value=\"1\"" "eval A"
mi_gdb_test "311-data-evaluate-expression &A" "311\\^done,value=\"$hex\"" "eval &A"
mi_gdb_test "411-data-evaluate-expression A+3" "411\\^done,value=\"4\"" "eval A+3"
mi_gdb_test "511-data-evaluate-expression \"A + 3\"" "511\\^done,value=\"4\"" "eval A + 3"
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,43 @@
# Copyright (C) 1999 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# Some basic checks for the CLI.
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
mi_gdb_test "show architecture\n" \
"&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n\\^done" \
"show architecture"
mi_gdb_test "47show architecture\n" \
"&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n47\\^done" \
"47show architecture"
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,20 @@
static char bytes[256];
static short shorts[256];
static void
initialize (void)
{
int i;
for (i = 0; i < sizeof (bytes); i++)
{
bytes[i] = i;
shorts[i] = i * 2;
}
}
int
main ()
{
initialize ();
}

View File

@ -0,0 +1,103 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# test basic Machine interface (MI) operations
#
# Verify that, using the MI, we can load a program and do
# other basic things that are used by all test files through mi_gdb_exit,
# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
# mi_gdb_load, so we can safely use those.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but the command syntax and correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "mi-read-memory"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_run_to_main
#mi_next "do initialization"
send_gdb "101-exec-next\n"
gdb_expect {
-re "101\\^running\r\n$mi_gdb_prompt" {
gdb_expect {
-re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*mi-read-memory.c\",line=\"20\"\}.*$mi_gdb_prompt$" \
{ pass "do initialization" }
-re ".*$mi_gdb_prompt$" {fail "do initialization (2)"}
timeout {fail "do initialization (timeout 2)"}
}
}
-re ".*$mi_gdb_prompt$" {fail "do initialization (1)"}
timeout {fail "do initialization (timeout 1)"}
}
mi_gdb_test "1-data-read-memory" \
"1\\^error,msg=\".*\"" \
"no arguments"
mi_gdb_test "2-data-read-memory bytes x 1 3 2" \
"2\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x00\",\"0x01\"}},{addr=\"$hex\",data={\"0x02\",\"0x03\"}},{addr=\"$hex\",data={\"0x04\",\"0x05\"}}}" \
"3x2, one byte"
mi_gdb_test "9-data-read-memory -o -6 -- -0+bytes+6 x 1 3 2" \
"9\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x00\",\"0x01\"}},{addr=\"$hex\",data={\"0x02\",\"0x03\"}},{addr=\"$hex\",data={\"0x04\",\"0x05\"}}}" \
"3x2, one byte offset by -6"
mi_gdb_test "3-data-read-memory \"(shorts + 128)\" x 2 1 2" \
"3\\^done,addr=\"$hex\",nr-bytes=\"4\",total-bytes=\"4\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x0100\",\"0x0102\"}}}" \
"expression in quotes"
mi_gdb_test "4-data-read-memory bytes+16 x 1 8 4 x" \
"4\\^done,addr=\"$hex\",nr-bytes=\"32\",total-bytes=\"32\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x10\",\"0x11\",\"0x12\",\"0x13\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x14\",\"0x15\",\"0x16\",\"0x17\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x18\",\"0x19\",\"0x1a\",\"0x1b\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x1c\",\"0x1d\",\"0x1e\",\"0x1f\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x20\",\"0x21\",\"0x22\",\"0x23\"},ascii=\" !\\\\\"#\"},{addr=\"$hex\",data={\"0x24\",\"0x25\",\"0x26\",\"0x27\"},ascii=\"\\$%&'\"},{addr=\"$hex\",data={\"0x28\",\"0x29\",\"0x2a\",\"0x2b\"},ascii=\"().+\"},{addr=\"$hex\",data={\"0x2c\",\"0x2d\",\"0x2e\",\"0x2f\"},ascii=\",-\./\"}}" \
"ascii and data"
mi_gdb_test "5-data-read-memory shorts+64 d 2 1 1" \
"5\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"128\"}}}" \
"decimal"
mi_gdb_test "6-data-read-memory shorts+64 o 2 1 1" \
"6\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0200\"}}}" \
"octal"
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,183 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can run a simple program and look at registers.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_breakpoints_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert some breakpoints and list them
# Also, disable some so they do not interfere with other tests
# Tests:
# -break-insert
# -break-list
# -break-disable
# -break-info
mi_gdb_test "200-break-insert main" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
"break-insert operation"
mi_gdb_test "204-break-list" \
"204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\}" \
"list of breakpoints"
}
proc test_running_the_program {} {
global mi_gdb_prompt
global hex
# Run the program without args
# Tests:
# -exec-run
# mi_gdb_test cannot be used for asynchronous commands because there are
# two prompts involved and this can lead to a race condition.
# FIXME: We are accepting a duplicate file and line info temporarely.
# The following is equivalent to a send_gdb "000-exec-run\n"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
pass "run to main"
}
-re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
timeout {fail "run to main (timeout 2)"}
}
}
proc sparc_register_tests_no_exec { } {
# Test the generic IDT chip.
mi_gdb_test "111-data-list-register-values" \
".*111\\^error,msg=\"mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> \\\[<regnum1>...<regnumN>\\\]\"" \
"wrong arguments"
mi_gdb_test "111-data-list-register-values x" \
".*111\\^error,msg=\"mi_cmd_data_list_register_values: No registers\.\"" \
"no executable"
}
# These tests exercise IDT-specific MIPS registers for several
# different processor models.
# This should detect the actual processor in use and change
# the expected results appropriately. FIXME
proc sparc_register_tests { } {
global hex
global decimal
set octal "\[0-7\]+"
set binary "\[0-1\]+"
set float "-?\[0-9\]+(\.\[0-9\]+)?(e\[+\-\]\[0-9\]+)?"
set float2 "\-?\[0-9\]+"
mi_gdb_test "111-data-list-register-names" \
"111\\^done,register-names=\{\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"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\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fpsr\",\"cpsr\"\}" \
"list register names"
mi_gdb_test "222-data-list-register-values x" \
"222\\^done,register-values=\{\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\}" \
"register values x"
mi_gdb_test "333-data-list-register-values f" \
"333\\^done,register-values=\{\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"71\",value=\"$float\"\}\}" \
"register values f"
mi_gdb_test "444-data-list-register-values d" \
"444\\^done,register-values=\{\{number=\"0\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\}" \
"register values d"
mi_gdb_test "555-data-list-register-values o" \
"555\\^done,register-values=\{\{number=\"0\",value=\"$octal\"\}.*\{number=\"71\",value=\"$octal\"\}\}" \
"register values o"
mi_gdb_test "666-data-list-register-values t" \
"666\\^done,register-values=\{\{number=\"0\",value=\"$binary\"\}.*\{number=\"71\",value=\"$binary\"\}\}" \
"register values t"
# On the sparc, registers 0-31 are int, 32-63 float, 64-71 int
mi_gdb_test "777-data-list-register-values N" \
"777\\^done,register-values=\{\{number=\"0\",value=\"$decimal\"\}.*\{number=\"31\",value=\"$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\}" \
"register values N"
mi_gdb_test "888-data-list-register-values r" \
"888\\^done,register-values=\{\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\}" \
"register values r"
mi_gdb_test "999-data-list-register-names 68 69 70 71" \
"999\\^done,register-names=\{\"pc\",\"npc\",\"fpsr\",\"cpsr\"\}" \
"list names of some regs"
mi_gdb_test "001-data-list-register-values x 68 69 70 71" \
"001\\^done,register-values=\{\{number=\"68\",value=\"$hex\"\},\{number=\"69\",value=\"$hex\"\},\{number=\"70\",value=\"$hex\"\},\{number=\"71\",value=\"$hex\"\}\}" \
"list values of some regs"
# Don't know how useful this test is
mi_gdb_test "002-data-list-changed-registers" \
"002\\^done,changed-registers=\{\"1\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"23\",\"24\",\"25\",\"26\",\"27\",\"28\",\"30\",\"31\",\"65\",\"68\",\"69\"\}" \
"list changed registers"
}
if [istarget "sparc-*-*"] then {
sparc_register_tests_no_exec
test_breakpoints_creation_and_listing
test_running_the_program
sparc_register_tests
} else {
verbose "mi-regs.exp tests ignored for this target"
}
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,94 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# Test Machine interface (MI) operations
# Verify that, using the MI, we can run a simple program and perform
# exec-return.
# The goal is not to
# test gdb functionality, which is done by other tests, but to verify
# the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_running_to_callee4 {} {
global mi_gdb_prompt
global hex
mi_gdb_test "200-break-insert callee4" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
gdb_expect {
-re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
pass "run to callee4"
}
timeout {
fail "run to callee4 (timeout)"
}
}
mi_gdb_test "205-break-delete" \
"205\\^done.*" \
"delete all breakpoints"
}
proc test_return_simple {} {
global mi_gdb_prompt
global hex
send_gdb "111-exec-return\n"
gdb_expect {
-re "111\\^done,frame=\{level=\"0 \",addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {pass "return from callee4 now"}
-re ".*\r\n$mi_gdb_prompt$" { fail "return from callee4 now" }
timeout { fail "return from callee4 now (timeout)"
}
}
}
test_running_to_callee4
test_return_simple
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,232 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can run a simple program and perform basic
# debugging activities like: insert breakpoints, run the program,
# step, next, continue until it ends and, last but not least, quit.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_breakpoints_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert some breakpoints and list them
# Also, disable some so they do not interfere with other tests
# Tests:
# -break-insert
# -break-list
# -break-disable
# -break-info
mi_gdb_test "200-break-insert main" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
"break-insert operation"
mi_gdb_test "201-break-insert basics.c:callee2" \
"201\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
"insert breakpoint at basics.c:callee2"
mi_gdb_test "202-break-insert basics.c:15" \
"202\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
"insert breakpoint at basics.c:15 (callee3)"
mi_gdb_test "203-break-insert \"\\\"${srcfile}\\\":6\"" \
"203\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
"insert breakpoint at \"<fullfilename>\":6 (callee4)"
mi_gdb_test "204-break-list" \
"204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
"list of breakpoints"
mi_gdb_test "205-break-disable 2 3 4" \
"205\\^done.*" \
"disabling of breakpoints"
mi_gdb_test "206-break-info 2" \
"206\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"2\",.*,enabled=\"n\",.*\}\}" \
"list of breakpoints, 16 disabled"
}
proc test_running_the_program {} {
global mi_gdb_prompt
global hex
# Run the program without args, then specify srgs and rerun the program
# Tests:
# -exec-run
# -gdb-set
# mi_gdb_test cannot be used for asynchronous commands because there are
# two prompts involved and this can lead to a race condition.
# The following is equivalent to a send_gdb "000-exec-run\n"
mi_run_cmd
gdb_expect {
-re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
pass "run to main"
}
timeout {
fail "run to main (timeout)"
}
}
}
proc test_controlled_execution {} {
global mi_gdb_prompt
global hex
# Continue execution until a breakpoint is reached, step into calls, verifying
# if the arguments are correctly shown, continue to the end of a called
# function, step over a call (next).
# Tests:
# -exec-continue
# -exec-next
# -exec-step
# -exec-finish
# mi_gdb_test cannot be used for asynchronous commands because there are
# two prompts involved and this can lead to a race condition.
send_gdb "220-exec-next\n"
gdb_expect {
-re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"33\"\}\r\n$mi_gdb_prompt$" {
pass "next at main"
}
timeout {
fail "next at main (timeout)"
}
}
# FIXME: A string argument is not printed right; should be fixed and
# we should look for the right thing here.
# NOTE: The ``\\\\\"'' is for \".
send_gdb "221-exec-step\n"
gdb_expect {
-re "221\\^running\r\n${mi_gdb_prompt}221\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee1\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument\.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\},file=\".*basics.c\",line=\"27\"\}\r\n$mi_gdb_prompt$" {
pass "step at main"
}
timeout {
fail "step at main (timeout)"
}
}
# FIXME: A string argument is not printed right; should be fixed and
# we should look for the right thing here.
send_gdb "222-exec-step 3\n"
gdb_expect 30 {
-re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
pass "step to callee4"
}
timeout {
fail "step to callee4 (timeout)"
}
}
# FIXME: A string argument is not printed right; should be fixed and
# we should look for the right thing here.
# NOTE: The ``.'' is part of ``gdb-result-var="$1"''
send_gdb "223-exec-finish\n"
gdb_expect 30 {
-re "223\\^running\r\n${mi_gdb_prompt}223\\*stopped,reason=\"function-finished\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\},gdb-result-var=\".1\",return-value=\"0\"\r\n$mi_gdb_prompt$" {
pass "exec-finish"
}
timeout {
fail "exec-finish (timeout)"
}
}
}
proc test_controlling_breakpoints {} {
global mi_gdb_prompt
# Enable, delete, set ignore counts in breakpoints
# (disable was already tested above)
# Tests:
# -break-delete
# -break-enable
# -break-after
# -break-condition
}
proc test_program_termination {} {
global mi_gdb_prompt
# Run to completion: normal and forced
# Tests:
# -exec-abort
# (normal termination of inferior)
# FIXME: "stopped" doesn't seem appropriate.
# mi_gdb_test cannot be used for asynchronous commands because there are
# two prompts involved and this can lead to a race condition.
send_gdb "999-exec-continue\n"
gdb_expect {
-re "999\\^running\r\n$mi_gdb_prompt" {
gdb_expect {
-re "999\\*stopped,reason=\"exited-normally\"\r\n$mi_gdb_prompt$" {
pass "continue to end"
}
-re ".*$mi_gdb_prompt$" {fail "continue to end (2)"}
timeout {fail "continue to end (timeout 2)"}
}
}
-re ".*$mi_gdb_prompt$" {fail "continue to end (1)"}
timeout {fail "continue to end (timeout 1)"}
}
}
test_breakpoints_creation_and_listing
test_running_the_program
test_controlled_execution
test_controlling_breakpoints
test_program_termination
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,222 @@
# Copyright (C) 1999 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test essential Machine interface (MI) operations
#
# Verify that stack commands work.
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
mi_gdb_test "200-break-insert callee4" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
pass "run to callee4"
}
-re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
timeout {fail "run to callee4 (timeout 2)"}
}
proc test_stack_frame_listing {} {
global mi_gdb_prompt
global hex
# Obtain a stack trace
# Tests:
# -stack-list-frames
# -stack-list-frames 1 1
# -stack-list-frames 1 3
mi_gdb_test "231-stack-list-frames" \
"231\\^done,stack=\{frame=\{level=\"0 \",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\"\},frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\},frame=\{level=\"4 \",addr=\"$hex\",func=\"main\",.*\}\}" \
"stack frame listing"
mi_gdb_test "232-stack-list-frames 1 1" \
"232\\^done,stack=\{frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\}\}" \
"stack frame listing 1 1"
mi_gdb_test "233-stack-list-frames 1 3" \
"233\\^done,stack=\{frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\}\}" \
"stack frame listing 1 3"
mi_gdb_test "234-stack-list-frames 1" \
"234\\^error,msg=\"mi_cmd_stack_list_frames: Usage.*FRAME_LOW FRAME_HIGH.*\"" \
"stack frame listing wrong"
}
proc test_stack_args_listing {} {
global mi_gdb_prompt
global hex
# Obtain lists for args for the stack frames
# Tests:
# -stack-list-arguments 0
# -stack-list-arguments 0 1 1
# -stack-list-arguments 0 1 3
# -stack-list-arguments 1
# -stack-list-arguments 1 1 1
# -stack-list-arguments 1 1 3
# -stack-list-arguments
mi_gdb_test "231-stack-list-arguments 0" \
"231\\^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=\{\}\}\}" \
"stack args listing 0"
mi_gdb_test "232-stack-list-arguments 0 1 1" \
"232\\^done,stack-args=\{frame=\{level=\"1\",args=\{name=\"strarg\"\}\}\}" \
"stack args listing 0 1 1"
mi_gdb_test "233-stack-list-arguments 0 1 3" \
"233\\^done,stack-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\"\}\}\}" \
"stack args listing 0 1 3"
mi_gdb_test "231-stack-list-arguments 1" \
"231\\^done,stack-args=\{frame=\{level=\"0\",args=\{\}\},frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"2\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"3\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\}\},frame=\{level=\"4\",args=\{\}\}\}" \
"stack args listing 1"
mi_gdb_test "232-stack-list-arguments 1 1 1" \
"232\\^done,stack-args=\{frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\}\}" \
"stack args listing 1 1 1"
mi_gdb_test "233-stack-list-arguments 1 1 3" \
"233\\^done,stack-args=\{frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"2\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"3\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\}\}\}" \
"stack args listing 1 1 3"
mi_gdb_test "234-stack-list-arguments" \
"234\\^error,msg=\"mi_cmd_stack_list_args: Usage.*PRINT_VALUES.*FRAME_LOW FRAME_HIGH.*\"" \
"stack args listing wrong"
}
proc test_stack_info_depth {} {
global mi_gdb_prompt
global hex
# Obtain depth of stack
# Tests:
# -stack-info-depth
# -stack-info-depth 3
# -stack-info-depth 99
mi_gdb_test "231-stack-info-depth" \
"231\\^done,depth=\"5\"" \
"stack info-depth"
mi_gdb_test "231-stack-info-depth 3" \
"231\\^done,depth=\"3\"" \
"stack info-depth 3"
mi_gdb_test "231-stack-info-depth 99" \
"231\\^done,depth=\"5\"" \
"stack info-depth 99"
mi_gdb_test "231-stack-info-depth 99 99" \
"231\\^error,msg=\"mi_cmd_stack_info_depth: Usage: .MAX_DEPTH.\"" \
"stack info-depth wrong usage"
}
proc test_stack_locals_listing {} {
global mi_gdb_prompt
global hex
# Obtain lists for locals for the stack frames
# Tests:
# -stack-list-locals 0
# -stack-list-locals 1
# -stack-list-arguments
mi_gdb_test "232-stack-list-locals 0" \
"232\\^done,locals=\{name=\"A\",name=\"B\",name=\"C\"\}" \
"stack locals listing 0"
# step until A, B, C, have some reasonable values.
send_gdb "-exec-next 3\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
pass "next's in callee4"
}
timeout { fail "next in callee4 (timeout)" }
}
mi_gdb_test "232-stack-list-locals 1" \
"232\\^done,locals=\{\{name=\"A\",value=\"1\"\},\{name=\"B\",value=\"2\"\},\{name=\"C\",value=\"3\"\}\}" \
"stack locals listing 1"
mi_gdb_test "234-stack-list-locals" \
"234\\^error,msg=\"mi_cmd_stack_list_locals: Usage.*PRINT_VALUES.*\"" \
"stack locals listing wrong"
mi_gdb_test "232-stack-select-frame 1" \
"232\\^done" \
"stack select frame 1"
mi_gdb_test "232-stack-list-locals 1" \
"232\\^done,locals=\{\}" \
"stack locals listing for new frame"
# this should be a no-op
mi_gdb_test "232-stack-select-frame" \
"232\\^done" \
"stack select same frame"
mi_gdb_test "232-stack-list-locals 1" \
"232\\^done,locals=\{\}" \
"stack locals for same frame (level 1)"
}
test_stack_frame_listing
test_stack_args_listing
test_stack_locals_listing
test_stack_info_depth
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,110 @@
# Copyright (C) 1999 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# Test Machine interface (MI) operations
# Verify that, using the MI, we can run a simple program and perform
# exec-step-instruction and exec-next-instruction.
# The goal is not to
# test gdb functionality, which is done by other tests, but to verify
# the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_running_to_main {} {
global mi_gdb_prompt
global hex
mi_gdb_test "200-break-insert main" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
gdb_expect {
-re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
pass "run to main"
}
timeout {
fail "run to main (timeout)"
}
}
}
proc test_stepi_nexti {} {
global mi_gdb_prompt
global hex
send_gdb "111-exec-step-instruction\n"
gdb_expect {
-re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
pass "step-instruction at main"
}
timeout {
fail "step-instruction at main (timeout)"
}
}
send_gdb "222-exec-next-instruction\n"
gdb_expect {
-re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
pass "next-instruction at main"
}
timeout {
fail "next-instruction at main (timeout)"
}
}
send_gdb "333-exec-next-instruction\n"
gdb_expect {
-re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
pass "next-instruction at main"
}
timeout {
fail "next-instruction at main (timeout)"
}
}
}
test_running_to_main
test_stepi_nexti
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,127 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# Test Machine interface (MI) operations
# Verify that, using the MI, we can run a simple program and perform
# exec-until.
# The goal is not to
# test gdb functionality, which is done by other tests, but to verify
# the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "until"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_running_to_foo {} {
global mi_gdb_prompt
global hex
mi_gdb_test "200-break-insert 10" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"foo\",file=\".*until.c\",line=\"10\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
gdb_expect {
-re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"10\"\}\r\n$mi_gdb_prompt$" {
pass "run to main"
}
timeout {
fail "run to main (timeout)"
}
}
mi_gdb_test "100-break-delete 1" "100\\^done" "break-delete 1"
}
proc test_until {} {
global mi_gdb_prompt
global hex
send_gdb "111-exec-until\n"
gdb_expect {
-re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"12\"\}\r\n$mi_gdb_prompt$" {
pass "until after while loop"
}
timeout {
fail "until after while loop (timeout)"
}
}
send_gdb "222-exec-until 15\n"
gdb_expect {
-re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"location-reached\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"15\"\}\r\n$mi_gdb_prompt$" {
pass "until line number"
}
timeout {
fail "until line number (timeout)"
}
}
send_gdb "333-exec-until until.c:17\n"
gdb_expect {
-re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"location-reached\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"17\"\}\r\n$mi_gdb_prompt$" {
pass "until line number:file"
}
timeout {
fail "until line number:file (timeout)"
}
}
# This is supposed to NOT stop at line 25. It stops right after foo is over.
send_gdb "444-exec-until until.c:25\n"
gdb_expect {
-re "444\\^running\r\n${mi_gdb_prompt}444\\*stopped,reason=\"location-reached\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*until.c\",line=\"24\"\}\r\n$mi_gdb_prompt$" {
pass "until after current function"
}
timeout {
fail "until after current function (timeout)"
}
}
}
test_running_to_foo
test_until
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,233 @@
# Copyright (C) 1999 2000 s Solutions
#
# 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can create, update, delete variables.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "var-cmd"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
mi_gdb_test "200-break-insert do_block_tests" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_block_tests\",file=\".*var-cmd.c\",line=\"154\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"154\"\}\r\n$mi_gdb_prompt$" {
pass "run to do_block_tests"
}
-re ".*$mi_gdb_prompt$" {fail "run to do_block_tests (2)"}
timeout {fail "run to do_block_tests (timeout 2)"}
}
# Test: c_variable-3.2
# Desc: create cb and foo
mi_gdb_test "-var-create cb * cb" \
"\\^done,name=\"cb\",numchild=\"0\",type=\"int\"" \
"create local variable cb"
mi_gdb_test "-var-create foo * foo" \
"&\"No symbol \\\\\"foo\\\\\" in current context.\\\\n\".*\\^error,msg=\"No symbol \\\\\"foo\\\\\" in current context.\"" \
"create local variable foo"
# step to "foo = 123;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"158\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_block_tests"
}
timeout {
fail "step at do_block_tests (timeout)"
}
}
# Be paranoid and assume 3.2 created foo
mi_gdb_test "-var-delete foo" \
"&\"Variable object not found\\\\n\".*\\^error,msg=\"Variable object not found\"" \
"delete var foo"
# Test: c_variable-3.3
# Desc: create foo
mi_gdb_test "-var-create foo * foo" \
"\\^done,name=\"foo\",numchild=\"0\",type=\"int\"" \
"create local variable foo"
# step to "foo2 = 123;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"161\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_block_tests"
}
timeout {
fail "step at do_block_tests (timeout)"
}
}
# Test: c_variable-3.4
# Desc: check foo, cb changed
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"foo\",name=\"cb\"\}" \
"update all vars: cb foo changed"
# step to "foo = 321;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"164\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_block_tests"
}
timeout {
fail "step at do_block_tests (timeout)"
}
}
# Test: c_variable-3.5
# Desc: create inner block foo
mi_gdb_test "-var-create inner_foo * foo" \
"\\^done,name=\"inner_foo\",numchild=\"0\",type=\"int\"" \
"create local variable inner_foo"
# step to "foo2 = 0;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"166\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_block_tests"
}
timeout { fail "step at do_block_tests (timeout)" }
}
# Test: c_variable-3.6
# Desc: create foo2
mi_gdb_test "-var-create foo2 * foo2" \
"\\^done,name=\"foo2\",numchild=\"0\",type=\"int\"" \
"create local variable foo2"
# Test: c_variable-3.7
# Desc: check that outer foo in scope and inner foo out of scope
# Note: also a known gdb problem
setup_xfail *-*-*
mi_gdb_test "-var-update inner_foo" \
"\\^done,changelist=\{FIXME\}" \
"update inner_foo: should be out of scope: KNOWN PROBLEM"
clear_xfail *-*-*
setup_xfail *-*-*
mi_gdb_test "-var-evaluate-expression inner_foo" \
"\\^done,value=\{FIXME\}" \
"evaluate inner_foo: should be out of scope: KNOWN PROBLEM"
clear_xfail *-*-*
mi_gdb_test "-var-update foo" \
"\\^done,changelist=\{\}" \
"update foo: did not change"
mi_gdb_test "-var-delete inner_foo" \
"\\^done,ndeleted=\"1\"" \
"delete var inner_foo"
# step to "foo = 0;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"168\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_block_tests"
}
timeout { fail "step at do_block_tests (timeout)" }
}
# Test: c_variable-3.8
# Desc: check that foo2 out of scope (known gdb problem)
setup_xfail *-*-*
mi_gdb_test "-var-update foo2" \
"\\^done,changelist=\{FIXME\}" \
"update foo2: should be out of scope: KNOWN PROBLEM"
clear_xfail *-*-*
# step to "cb = 21;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"171\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_block_tests"
}
timeout { fail "step at do_block_tests (timeout)" }
}
# Test: c_variable-3.9
# Desc: check that only cb is in scope (known gdb problem)
setup_xfail *-*-*
mi_gdb_test "-var-update foo2" \
"\\^done,changelist=\{FIXME\}" \
"update foo2 should be out of scope: KNOWN PROBLEM"
clear_xfail *-*-*
setup_xfail *-*-*
mi_gdb_test "-var-update foo" \
"\\^done,changelist=\{FIXME\}" \
"update foo should be out of scope: KNOWN PROBLEM"
clear_xfail *-*-*
mi_gdb_test "-var-update cb" \
"\\^done,changelist=\{\}" \
"update cb"
# Test: c_variable-3.10
# Desc: names of editable variables
#gdbtk_test c_variable-3.10 {names of editable variables} {
# editable_variables
#} {{foo cb foo2} {}}
# Done with block tests
mi_gdb_test "-var-delete foo" \
"\\^done,ndeleted=\"1\"" \
"delete var foo"
mi_gdb_test "-var-delete foo2" \
"\\^done,ndeleted=\"1\"" \
"delete var foo2"
mi_gdb_test "-var-delete cb" \
"\\^done,ndeleted=\"1\"" \
"delete var cb"
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,605 @@
# Copyright (C) 1999 2000 Cygnus Solutions
#
# 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can create, update, delete variables.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "var-cmd"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
##### #####
# #
# Variable Creation tests #
# #
##### #####
# Test: c_variable-1.1
# Desc: Create global variable
mi_gdb_test "111-var-create global_simple * global_simple" \
"111\\^done,name=\"global_simple\",numchild=\"6\",type=\"simpleton\"" \
"create global variable"
# Test: c_variable-1.2
# Desc: Create non-existent variable
mi_gdb_test "112-var-create bogus_unknown_variable * bogus_unknown_variable" \
"&\"No symbol \\\\\"bogus_unknown_variable\\\\\" in current context.\\\\n\".*112\\^error,msg=\"No symbol \\\\\"bogus_unknown_variable\\\\\" in current context.\"" \
"create non-existent variable"
# Test: c_variable-1.3
# Desc: Create out of scope variable
mi_gdb_test "113-var-create argc * argc" \
"&\"No symbol \\\\\"argc\\\\\" in current context.\\\\n\".*113\\^error,msg=\"No symbol \\\\\"argc\\\\\" in current context.\"" \
"create out of scope variable"
mi_gdb_test "200-break-insert do_locals_tests" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_locals_tests\",file=\".*var-cmd.c\",line=\"106\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"106\"\}\r\n$mi_gdb_prompt$" {
pass "run to do_locals_tests"
}
-re ".*$mi_gdb_prompt$" {fail "run todo_locals_tests (2)"}
timeout {fail "run to do_locals_tests (timeout 2)"}
}
# Test: c_variable-1.4
# Desc: create local variables
mi_gdb_test "-var-create linteger * linteger" \
"\\^done,name=\"linteger\",numchild=\"0\",type=\"int\"" \
"create local variable linteger"
mi_gdb_test "-var-create lpinteger * lpinteger" \
"\\^done,name=\"lpinteger\",numchild=\"1\",type=\"int \\*\"" \
"create local variable lpinteger"
mi_gdb_test "-var-create lcharacter * lcharacter" \
"\\^done,name=\"lcharacter\",numchild=\"0\",type=\"char\"" \
"create local variablelcharacter "
mi_gdb_test "-var-create lpcharacter * lpcharacter" \
"\\^done,name=\"lpcharacter\",numchild=\"0\",type=\"char \\*\"" \
"create local variable lpcharacter"
mi_gdb_test "-var-create llong * llong" \
"\\^done,name=\"llong\",numchild=\"0\",type=\"long int\"" \
"create local variable llong"
mi_gdb_test "-var-create lplong * lplong" \
"\\^done,name=\"lplong\",numchild=\"1\",type=\"long int \\*\"" \
"create local variable lplong"
mi_gdb_test "-var-create lfloat * lfloat" \
"\\^done,name=\"lfloat\",numchild=\"0\",type=\"float\"" \
"create local variable lfloat"
mi_gdb_test "-var-create lpfloat * lpfloat" \
"\\^done,name=\"lpfloat\",numchild=\"1\",type=\"float \\*\"" \
"create local variable lpfloat"
mi_gdb_test "-var-create ldouble * ldouble" \
"\\^done,name=\"ldouble\",numchild=\"0\",type=\"double\"" \
"create local variable ldouble"
mi_gdb_test "-var-create lpdouble * lpdouble" \
"\\^done,name=\"lpdouble\",numchild=\"1\",type=\"double \\*\"" \
"create local variable lpdouble"
mi_gdb_test "-var-create lsimple * lsimple" \
"\\^done,name=\"lsimple\",numchild=\"6\",type=\"struct _simple_struct\"" \
"create local variable lsimple"
mi_gdb_test "-var-create lpsimple * lpsimple" \
"\\^done,name=\"lpsimple\",numchild=\"6\",type=\"struct _simple_struct \\*\"" \
"create local variable lpsimple"
mi_gdb_test "-var-create func * func" \
"\\^done,name=\"func\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"" \
"create local variable func"
# Test: c_variable-1.5
# Desc: create lsimple.character
mi_gdb_test "-var-create lsimple.character * lsimple.character" \
"\\^done,name=\"lsimple.character\",numchild=\"0\",type=\"char\"" \
"create lsimple.character"
# Test: c_variable-1.6
# Desc: create lpsimple->integer
mi_gdb_test "-var-create lsimple->integer * lsimple->integer" \
"\\^done,name=\"lsimple->integer\",numchild=\"0\",type=\"int\"" \
"create lsimple->integer"
# Test: c_variable-1.7
# Desc: ceate lsimple.integer
mi_gdb_test "-var-create lsimple.integer * lsimple.integer" \
"\\^done,name=\"lsimple.integer\",numchild=\"0\",type=\"int\"" \
"create lsimple->integer"
# Test: c_variable-1.9
# Desc: create type name
# Type names (like int, long, etc..) are all proper expressions to gdb.
# make sure variable code does not allow users to create variables, though.
mi_gdb_test "-var-create int * int" \
"&\"Attempt to use a type name as an expression.mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
"create int"
##### #####
# #
# Value changed tests #
# #
##### #####
# Test: c_variable-2.1
# Desc: check whether values changed at do_block_tests
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{\}" \
"update all vars"
# Step over "linteger = 1234;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"107\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_locals_tests"
}
timeout {
fail "step at do_locals_tests (timeout)"
}
}
# Test: c_variable-2.2
# Desc: check whether only linteger changed values
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"linteger\"\}" \
"update all vars: linteger changed"
# Step over "lpinteger = &linteger;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"108\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_locals_tests"
}
timeout {
fail "step at do_locals_tests (timeout)"
}
}
# Test: c_variable-2.3
# Desc: check whether only lpinteger changed
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"lpinteger\"\}" \
"update all vars: lpinteger changed"
# Step over "lcharacter = 'a';"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"109\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_locals_tests"
}
timeout {
fail "step at do_locals_tests (timeout)"
}
}
# Test: c_variable-2.4
# Desc: check whether only lcharacter changed
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"lcharacter\"\}" \
"update all vars: lcharacter changed"
# Step over "lpcharacter = &lcharacter;"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"110\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_locals_tests"
}
timeout {
fail "step at do_locals_tests (timeout)"
}
}
# Test: c_variable-2.5
# Desc: check whether only lpcharacter changed
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"lpcharacter\"\}" \
"update all vars: lpcharacter changed"
# Step over:
# llong = 2121L;
# lplong = &llong;
# lfloat = 2.1;
# lpfloat = &lfloat;
# ldouble = 2.718281828459045;
# lpdouble = &ldouble;
# lsimple.integer = 1234;
# lsimple.unsigned_integer = 255;
# lsimple.character = 'a';
send_gdb "-exec-step 9\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"119\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_locals_tests"
}
timeout {
fail "step at do_locals_tests (timeout)"
}
}
# Test: c_variable-2.6
# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
# lsimple.unsigned_character lsimple.integer lsimple.character changed
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"lsimple.integer\",name=\"lsimple->integer\",name=\"lsimple.character\",name=\"lpdouble\",name=\"ldouble\",name=\"lpfloat\",name=\"lfloat\",name=\"lplong\",name=\"llong\"\}" \
"update all vars: many changed"
# Step over:
# lsimple.signed_character = 21;
# lsimple.char_ptr = &lcharacter;
# lpsimple = &lsimple;
# func = nothing;
send_gdb "-exec-step 4\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"125\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_locals_tests"
}
timeout {
fail "step at do_locals_tests (timeout)"
}
}
# Test: c_variable-2.7
# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"func\",name=\"lpsimple\"\}" \
"update all vars: func and lpsimple changed"
# Step over
# linteger = 4321;
# lcharacter = 'b';
# llong = 1212L;
# lfloat = 1.2;
# ldouble = 5.498548281828172;
# lsimple.integer = 255;
# lsimple.unsigned_integer = 4321;
# lsimple.character = 'b';
send_gdb "-exec-step 8\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"133\"\}\r\n$mi_gdb_prompt$" {
pass "step at do_locals_tests"
}
timeout {
fail "step at do_locals_tests (timeout)"
}
}
# Test: c_variable-2.8
# Desc: check whether linteger, lcharacter, llong, lfoat, ldouble, lsimple.integer,
# lpsimple.integer lsimple.character changed
# Note: this test also checks that lpsimple->integer and lsimple.integer have
# changed (they are the same)
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"lsimple.integer\",name=\"lsimple->integer\",name=\"lsimple.character\",name=\"ldouble\",name=\"lfloat\",name=\"llong\",name=\"lcharacter\",name=\"linteger\"\}" \
"update all vars: func and lpsimple changed"
###
#
# Test assignment to variables. More tests on assignment are in other files.
#
###
mi_gdb_test "-var-assign global_simple 0" \
"&\"mi_cmd_var_assign: Variable object is not editable\\\\n\".*\\^error,msg=\"mi_cmd_var_assign: Variable object is not editable\"" \
"assign to global_simple"
mi_gdb_test "-var-assign linteger 3333" \
"\\^done,value=\"3333\"" \
"assign to linteger"
mi_gdb_test "-var-evaluate-expression linteger" \
"\\^done,value=\"3333\"" \
"eval linteger"
mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
"\\^done,value=\"$hex\"" \
"assign to lpinteger"
mi_gdb_test "-var-evaluate-expression lpinteger" \
"\\^done,value=\"$hex\"" \
"eval lpinteger"
# reset the values to the original ones so that the rest of the file doesn't suffer.
mi_gdb_test "-var-assign linteger 4321" \
"\\^done,value=\"4321\"" \
"assign to linteger"
mi_gdb_test "-var-assign lpinteger &linteger" \
"\\^done,value=\"$hex\"" \
"assign to lpinteger"
mi_gdb_test "-var-assign lcharacter 'z'" \
"\\^done,value=\"122 'z'\"" \
"assign to lcharacter"
mi_gdb_test "-var-evaluate-expression lcharacter" \
"\\^done,value=\"122 'z'\"" \
"eval lcharacter"
mi_gdb_test "-var-assign llong 1313L" \
"\\^done,value=\"1313\"" \
"assign to llong"
mi_gdb_test "-var-evaluate-expression llong" \
"\\^done,value=\"1313\"" \
"eval llong"
mi_gdb_test "-var-assign llong 1212L" \
"\\^done,value=\"1212\"" \
"assign to llong"
mi_gdb_test "-var-assign lplong &llong+4" \
"\\^done,value=\"$hex\"" \
"assign to lplong"
mi_gdb_test "-var-evaluate-expression lplong" \
"\\^done,value=\"$hex\"" \
"eval lplong"
mi_gdb_test "-var-assign lplong &llong" \
"\\^done,value=\"$hex\"" \
"assign to lplong"
mi_gdb_test "-var-assign lfloat 3.4" \
"\\^done,value=\"3.4.*\"" \
"assign to lfloat"
mi_gdb_test "-var-evaluate-expression lfloat" \
"\\^done,value=\"3.4.*\"" \
"eval lfloat"
mi_gdb_test "-var-assign lfloat 1.2" \
"\\^done,value=\"1.2.*\"" \
"assign to lfloat"
mi_gdb_test "-var-assign lpfloat &lfloat+4" \
"\\^done,value=\"$hex\"" \
"assign to lpfloat"
mi_gdb_test "-var-assign ldouble 5.333318284590435" \
"\\^done,value=\"5.333318284590435\"" \
"assign to ldouble"
mi_gdb_test "-var-assign func do_block_tests" \
"\\^done,value=\"$hex <do_block_tests>\"" \
"assign to func"
mi_gdb_test "-var-assign lsimple.character 'd'" \
"\\^done,value=\"100 'd'\"" \
"assign to lsimple.character"
mi_gdb_test "-var-assign lsimple->integer 222" \
"\\^done,value=\"222\"" \
"assign to lsimple->integer"
mi_gdb_test "-var-assign lsimple.integer 333" \
"\\^done,value=\"333\"" \
"assign to lsimple.integer"
######
# End of assign tests
#####
mi_gdb_test "-break-insert subroutine1" \
"\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"subroutine1\",file=\".*var-cmd.c\",line=\"146\",times=\"0\"\}" \
"break-insert subroutine1"
send_gdb "-exec-continue\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\"4321\"\},\{name=\"l\",value=\"$hex\"\}\},file=\".*var-cmd.c\",line=\"146\"\}\r\n$mi_gdb_prompt$" {
pass "continue to subroutine1"
}
timeout {
fail "continue to subroutine1 (timeout)"
}
}
# Test: c_variable-2.10
# Desc: create variable for locals i,l in subroutine1
mi_gdb_test "-var-create i * i" \
"\\^done,name=\"i\",numchild=\"0\",type=\"int\"" \
"create i"
mi_gdb_test "-var-create l * l" \
"\\^done,name=\"l\",numchild=\"1\",type=\"long int \\*\"" \
"create l"
# Test: c_variable-2.11
# Desc: create do_locals_tests local in subroutine1
mi_gdb_test "-var-create linteger * linteger" \
"&\"No symbol \\\\\"linteger\\\\\" in current context.\\\\n\".*\\^error,msg=\"No symbol \\\\\"linteger\\\\\" in current context.\"" \
"create linteger"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}\},file=\".*var-cmd.c\",line=\"147\"\}\r\n$mi_gdb_prompt$" {
pass "step at subroutine1"
}
timeout {
fail "step at subroutine1 (timeout)"
}
}
# Test: c_variable-2.12
# Desc: change global_simple.integer
# Note: This also tests whether we are reporting changes in structs properly.
# gdb normally would say that global_simple has changed, but we
# special case that, since it is not what a human expects to see.
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{FIXME: WHAT IS CORRECT HERE\}" \
"update all vars: changed FIXME"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}\},file=\".*var-cmd.c\",line=\"148\"\}\r\n$mi_gdb_prompt$" {
pass "step at subroutine1"
}
timeout { fail "step at subroutine1 (timeout)" }
}
# Test: c_variable-2.13
# Desc: change subroutine1 local i
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"i\"\}" \
"update all vars: i changed"
send_gdb "-exec-step\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}\},file=\".*var-cmd.c\",line=\"149\"\}\r\n$mi_gdb_prompt$" {
pass "step at subroutine1"
}
timeout { fail "step at subroutine1 (timeout)" }
}
# Test: c_variable-2.14
# Desc: change do_locals_tests local llong
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{name=\"llong\"\}" \
"update all vars: llong changed"
send_gdb "-exec-next\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"136\"\}\r\n$mi_gdb_prompt$" {
pass "next out of subroutine1"
}
timeout { fail "next out of subroutine1 (timeout)" }
}
# Test: c_variable-2.15
# Desc: check for out of scope subroutine1 locals
mi_gdb_test "-var-update *" \
"\\^done,changelist=\{\}" \
"update all vars: none changed"
# Done with locals/globals tests. Erase all variables
#delete_all_variables
mi_gdb_test "-var-delete global_simple" \
"\\^done,ndeleted=\"1\"" \
"delete var"
mi_gdb_test "-var-delete linteger" \
"\\^done,ndeleted=\"1\"" \
"delete var linteger"
mi_gdb_test "-var-delete lpinteger" \
"\\^done,ndeleted=\"1\"" \
"delete var lpinteger"
mi_gdb_test "-var-delete lcharacter" \
"\\^done,ndeleted=\"1\"" \
"delete var lcharacter"
mi_gdb_test "-var-delete lpcharacter" \
"\\^done,ndeleted=\"1\"" \
"delete var lpcharacter"
mi_gdb_test "-var-delete llong" \
"\\^done,ndeleted=\"1\"" \
"delete var llong"
mi_gdb_test "-var-delete lplong" \
"\\^done,ndeleted=\"1\"" \
"delete var lplong"
mi_gdb_test "-var-delete lfloat" \
"\\^done,ndeleted=\"1\"" \
"delete var lfloat"
mi_gdb_test "-var-delete lpfloat" \
"\\^done,ndeleted=\"1\"" \
"delete var lpfloat"
mi_gdb_test "-var-delete ldouble" \
"\\^done,ndeleted=\"1\"" \
"delete var ldouble"
mi_gdb_test "-var-delete lpdouble" \
"\\^done,ndeleted=\"1\"" \
"delete var lpdouble"
mi_gdb_test "-var-delete lsimple" \
"\\^done,ndeleted=\"1\"" \
"delete var lsimple"
mi_gdb_test "-var-delete lpsimple" \
"\\^done,ndeleted=\"1\"" \
"delete var lpsimple"
mi_gdb_test "-var-delete func" \
"\\^done,ndeleted=\"1\"" \
"delete var func"
mi_gdb_test "-var-delete lsimple.character" \
"\\^done,ndeleted=\"1\"" \
"delete var lsimple.character"
mi_gdb_test "-var-delete lsimple->integer" \
"\\^done,ndeleted=\"1\"" \
"delete var lsimple->integer"
mi_gdb_test "-var-delete lsimple.integer" \
"\\^done,ndeleted=\"1\"" \
"delete var lsimple.integer"
mi_gdb_test "-var-delete i" \
"\\^done,ndeleted=\"1\"" \
"delete var i"
mi_gdb_test "-var-delete l" \
"\\^done,ndeleted=\"1\"" \
"delete var l"
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,628 @@
# Copyright (C) 1999 2000 Cygnus Solutions
#
# 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can create, update, delete variables.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "var-cmd"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
mi_gdb_test "200-break-insert 260" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"260\",times=\"0\"\}" \
"break-insert operation"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" {
pass "run to do_children_tests"
}
-re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"}
timeout {fail "run to do_children_tests (timeout 2)"}
}
##### #####
# #
# Display tests #
# #
##### #####
# Test: c_variable-6.1
# Desc: create variable bar
mi_gdb_test "-var-create bar * bar" \
"\\^done,name=\"bar\",numchild=\"0\",type=\"int\"" \
"create local variable bar"
# Test: c_variable-6.2
# Desc: type of variable bar
mi_gdb_test "-var-info-type bar" \
"\\^done,type=\"int\"" \
"info type variable bar"
# Test: c_variable-6.3
# Desc: format of variable bar
mi_gdb_test "-var-show-format bar" \
"\\^done,format=\"natural\"" \
"show format variable bar"
# Test: c_variable-6.4
# Desc: value of variable bar
mi_gdb_test "-var-evaluate-expression bar" \
"\\^done,value=\"2121\"" \
"eval variable bar"
# Test: c_variable-6.5
# Desc: change format of bar to hex
mi_gdb_test "-var-set-format bar hexadecimal" \
"\\^done,format=\"hexadecimal\"" \
"set format variable bar"
# Test: c_variable-6.6
# Desc: value of bar with new format
mi_gdb_test "-var-evaluate-expression bar" \
"\\^done,value=\"0x849\"" \
"eval variable bar with new format"
# Test: c_variable-6.7
# Desc: change value of bar
mi_gdb_test "-var-assign bar 3" \
"\\^done,value=\"0x3\"" \
"assing to variable bar"
mi_gdb_test "-var-set-format bar decimal" \
"\\^done,format=\"decimal\"" \
"set format variable bar"
mi_gdb_test "-var-evaluate-expression bar" \
"\\^done,value=\"3\"" \
"eval variable bar with new value"
mi_gdb_test "-var-delete bar" \
"\\^done,ndeleted=\"1\"" \
"delete var bar"
# Test: c_variable-6.11
# Desc: create variable foo
mi_gdb_test "-var-create foo * foo" \
"\\^done,name=\"foo\",numchild=\"1\",type=\"int \\*\"" \
"create local variable foo"
# Test: c_variable-6.12
# Desc: type of variable foo
mi_gdb_test "-var-info-type foo" \
"\\^done,type=\"int \\*\"" \
"info type variable foo"
# Test: c_variable-6.13
# Desc: format of variable foo
mi_gdb_test "-var-show-format foo" \
"\\^done,format=\"natural\"" \
"show format variable foo"
# Test: c_variable-6.14
# Desc: value of variable foo
mi_gdb_test "-var-evaluate-expression foo" \
"\\^done,value=\"$hex\"" \
"eval variable foo"
# Test: c_variable-6.15
# Desc: change format of var to octal
mi_gdb_test "-var-set-format foo octal" \
"\\^done,format=\"octal\"" \
"set format variable foo"
mi_gdb_test "-var-show-format foo" \
"\\^done,format=\"octal\"" \
"show format variable foo"
# Test: c_variable-6.16
# Desc: value of foo with new format
mi_gdb_test "-var-evaluate-expression foo" \
"\\^done,value=\"\[0-7\]+\"" \
"eval variable foo"
# Test: c_variable-6.17
# Desc: change value of foo
mi_gdb_test "-var-assign foo 3" \
"\\^done,value=\"03\"" \
"assing to variable foo"
mi_gdb_test "-var-set-format foo decimal" \
"\\^done,format=\"decimal\"" \
"set format variable foo"
# Test: c_variable-6.18
# Desc: check new value of foo
mi_gdb_test "-var-evaluate-expression foo" \
"\\^done,value=\"3\"" \
"eval variable foo"
mi_gdb_test "-var-delete foo" \
"\\^done,ndeleted=\"1\"" \
"delete var foo"
# Test: c_variable-6.21
# Desc: create variable weird and children
mi_gdb_test "-var-create weird * weird" \
"\\^done,name=\"weird\",numchild=\"11\",type=\"weird_struct \\*\"" \
"create local variable weird"
mi_gdb_test "-var-list-children weird" \
"\\^done,numchild=\"11\",children=\{child=\{name=\"weird.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"weird.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child={name=\"weird.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\},child=\{name=\"weird.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"weird.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"weird.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\(\\)\"\},child=\{name=\"weird.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"weird.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
"get children local variable weird"
# Test: c_variable-6.23
# Desc: change format of weird.func_ptr and weird.func_ptr_ptr
mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
"\\^done,format=\"hexadecimal\"" \
"set format variable weird.func_ptr"
mi_gdb_test "-var-show-format weird.func_ptr" \
"\\^done,format=\"hexadecimal\"" \
"show format variable weird.func_ptr"
mi_gdb_test "-var-set-format weird.func_ptr_ptr hexadecimal" \
"\\^done,format=\"hexadecimal\"" \
"set format variable weird.func_ptr_ptr"
mi_gdb_test "-var-show-format weird.func_ptr_ptr" \
"\\^done,format=\"hexadecimal\"" \
"show format variable weird.func_ptr_ptr"
# Test: c_variable-6.24
# Desc: format of weird and children
mi_gdb_test "-var-set-format weird natural" \
"\\^done,format=\"natural\"" \
"set format variable weird"
mi_gdb_test "-var-set-format weird.integer natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.integer"
mi_gdb_test "-var-set-format weird.character natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.character"
mi_gdb_test "-var-set-format weird.char_ptr natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.char_ptr"
mi_gdb_test "-var-set-format weird.long_int natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.long_int"
mi_gdb_test "-var-set-format weird.int_ptr_ptr natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.int_ptr_ptr"
mi_gdb_test "-var-set-format weird.long_array natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.long_array"
mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
"\\^done,format=\"hexadecimal\"" \
"set format variable weird.func_ptr"
mi_gdb_test "-var-set-format weird.func_ptr_struct hexadecimal" \
"\\^done,format=\"hexadecimal\"" \
"set format variable weird.func_ptr_struct"
mi_gdb_test "-var-set-format weird.func_ptr_ptr natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.func_ptr_ptr"
mi_gdb_test "-var-set-format weird.u1 natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.u1"
mi_gdb_test "-var-set-format weird.s2 natural" \
"\\^done,format=\"natural\"" \
"set format variable weird.s2"
# Test: c_variable-6.25
# Desc: value of weird and children
#gdbtk_test c_variable-6.25 {value of weird and children} {
# set values {}
# foreach v [lsort [array names var]] f [list x "" "" x x x x d d d d d] {
# lappend values [value $v $f]
# }
# set values
#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
# Test: c_variable-6.26
# Desc: change format of weird and children to octal
#gdbtk_test c_variable-6.26 {change format of weird and children to octal} {
# set formats {}
# foreach v [lsort [array names var]] {
# $var($v) format octal
# lappend formats [$var($v) format]
# }
# set formats
#} {octal octal octal octal octal octal octal octal octal octal octal octal}
# Test: c_variable-6.27
# Desc: value of weird and children with new format
#gdbtk_test c_variable-6.27 {value of foo with new format} {
# set values {}
# foreach v [lsort [array names var]] {
# lappend values [value $v o]
# }
# set values
#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
# Test: c_variable-6.30
# Desc: create more children of weird
#gdbtk_test c_variable-6.30 {create more children of weird} {
# foreach v [array names var] {
# get_children $v
# }
# # Do it twice to get more children
# foreach v [array names var] {
# get_children $v
# }
# lsort [array names var]
#} {weird weird.char_ptr weird.character weird.func_ptr weird.func_ptr_ptr weird.func_ptr_struct weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.integer weird.long_array weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.long_int weird.s2 weird.s2.g weird.s2.h weird.s2.i weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9 weird.s2.u2 weird.s2.u2.f weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.u1 weird.u1.a weird.u1.b weird.u1.c weird.u1.d}
# Test: c_variable-6.31
# Desc: check that all children of weird change
# Ok, obviously things like weird.s2 and weird.u1 will not change!
#gdbtk_test *c_variable-6.31 {check that all children of weird change (ops, we are now reporting array names as changed in this case - seems harmless though)} {
# $var(weird) value 0x2121
# check_update
#} {{weird.integer weird.character weird.char_ptr weird.long_int weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.func_ptr weird.func_ptr_struct weird.func_ptr_ptr weird.u1.a weird.u1.b weird.u1.c weird.u1.d weird.s2.u2.f weird.s2.g weird.s2.h weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9} {weird.s2.i weird.s2.u2 weird weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.s2 weird.long_array weird.u1} {}}
mi_gdb_test "-var-delete weird" \
"\\^done,ndeleted=\"12\"" \
"delete var weird"
##### #####
# #
# Special Display Tests #
# #
##### #####
# Stop in "do_special_tests"
mi_gdb_test "200-break-insert do_special_tests" \
"200\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_special_tests\",file=\".*var-cmd.c\",line=\"282\",times=\"0\"\}" \
"break-insert operation"
send_gdb "-exec-continue\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_special_tests\",args=\{\},file=\".*var-cmd.c\",line=\"282\"\}\r\n$mi_gdb_prompt$" {
pass "continue to do_special_tests"
}
timeout {
fail "continue to do_special_tests (timeout)"
}
}
# Test: c_variable-7.10
# Desc: create union u
mi_gdb_test "-var-create u * u" \
"\\^done,name=\"u\",numchild=\"2\",type=\"union named_union\"" \
"create local variable u"
# Test: c_variable-7.11
# Desc: value of u
mi_gdb_test "-var-evaluate-expression u" \
"\\^done,value=\"\{\\.\\.\\.\}\"" \
"eval variable u"
# Test: c_variable-7.12
# Desc: type of u
mi_gdb_test "-var-info-type u" \
"\\^done,type=\"union named_union\"" \
"info type variable u"
# Test: c_variable-7.13
# Desc: is u editable
mi_gdb_test "-var-show-attributes u" \
"\\^done,attr=\"noneditable\"" \
"is u editable"
# Test: c_variable-7.14
# Desc: number of children of u
mi_gdb_test "-var-info-num-children u" \
"\\^done,numchild=\"2\"" \
"get number of children of u"
# Test: c_variable-7.15
# Desc: children of u
mi_gdb_test "-var-list-children u" \
"\\^done,numchild=\"2\",children=\{child=\{name=\"u.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"u.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\}\}" \
"get children of u"
# Test: c_variable-7.20
# Desc: create anonu
mi_gdb_test "-var-create anonu * anonu" \
"\\^done,name=\"anonu\",numchild=\"3\",type=\"union \{\\.\\.\\.\}\"" \
"create local variable anonu"
# Test: c_variable-7.21
# Desc: value of anonu
mi_gdb_test "-var-evaluate-expression anonu" \
"\\^done,value=\"\{\\.\\.\\.\}\"" \
"eval variable anonu"
# Test: c_variable-7.22
# Desc: type of anonu
mi_gdb_test "-var-info-type anonu" \
"\\^done,type=\"union \{\\.\\.\\.\}\"" \
"info type variable anonu"
# Test: c_variable-7.23
# Desc: is anonu editable
mi_gdb_test "-var-show-attributes anonu" \
"\\^done,attr=\"noneditable\"" \
"is anonu editable"
# Test: c_variable-7.24
# Desc: number of children of anonu
mi_gdb_test "-var-info-num-children anonu" \
"\\^done,numchild=\"3\"" \
"get number of children of anonu"
# Test: c_variable-7.25
# Desc: children of anonu
mi_gdb_test "-var-list-children anonu" \
"\\^done,numchild=\"3\",children=\{child=\{name=\"anonu.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anonu.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anonu.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
"get children of anonu"
# Test: c_variable-7.30
# Desc: create struct s
mi_gdb_test "-var-create s * s" \
"\\^done,name=\"s\",numchild=\"6\",type=\"struct _simple_struct\"" \
"create local variable s"
# Test: c_variable-7.31
# Desc: value of s
mi_gdb_test "-var-evaluate-expression s" \
"\\^done,value=\"\{\\.\\.\\.\}\"" \
"eval variable s"
# Test: c_variable-7.32
# Desc: type of s
mi_gdb_test "-var-info-type s" \
"\\^done,type=\"struct _simple_struct\"" \
"info type variable s"
# Test: c_variable-7.33
# Desc: is s editable
mi_gdb_test "-var-show-attributes s" \
"\\^done,attr=\"noneditable\"" \
"is s editable"
# Test: c_variable-7.34
# Desc: number of children of s
mi_gdb_test "-var-info-num-children s" \
"\\^done,numchild=\"6\"" \
"get number of children of s"
# Test: c_variable-7.35
# Desc: children of s
mi_gdb_test "-var-list-children s" \
"\\^done,numchild=\"6\",children=\{child=\{name=\"s.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"s.unsigned_integer\",exp=\"unsigned_integer\",numchild=\"0\",type=\"unsigned int\"\},child=\{name=\"s.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child=\{name=\"s.signed_character\",exp=\"signed_character\",numchild=\"0\",type=\"signed char\"\},child=\{name=\"s.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\},child=\{name=\"s.array_of_10\",exp=\"array_of_10\",numchild=\"10\",type=\"int \\\[10\\\]\"\}\}" \
"get children of s"
#} {integer unsigned_integer character signed_character char_ptr array_of_10}
# Test: c_variable-7.40
# Desc: create anons
mi_gdb_test "-var-create anons * anons" \
"\\^done,name=\"anons\",numchild=\"3\",type=\"struct \{\\.\\.\\.\}\"" \
"create local variable anons"
# Test: c_variable-7.41
# Desc: value of anons
mi_gdb_test "-var-evaluate-expression anons" \
"\\^done,value=\"\{\\.\\.\\.\}\"" \
"eval variable anons"
# Test: c_variable-7.42
# Desc: type of anons
mi_gdb_test "-var-info-type anons" \
"\\^done,type=\"struct \{\\.\\.\\.\}\"" \
"info type variable anons"
# Test: c_variable-7.43
# Desc: is anons editable
mi_gdb_test "-var-show-attributes anons" \
"\\^done,attr=\"noneditable\"" \
"is anons editable"
# Test: c_variable-7.44
# Desc: number of children of anons
mi_gdb_test "-var-info-num-children anons" \
"\\^done,numchild=\"3\"" \
"get number of children of anons"
# Test: c_variable-7.45
# Desc: children of anons
mi_gdb_test "-var-list-children anons" \
"\\^done,numchild=\"3\",children=\{child=\{name=\"anons.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anons.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anons.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
"get children of anons"
# Test: c_variable-7.50
# Desc: create enum e
mi_gdb_test "-var-create e * e" \
"\\^done,name=\"e\",numchild=\"0\",type=\"enum foo\"" \
"create local variable e"
setup_xfail "*-*-*"
# Test: c_variable-7.51
# Desc: value of e
mi_gdb_test "-var-evaluate-expression e" \
"\\^done,value=\"FIXME\"" \
"eval variable e"
clear_xfail "*-*-*"
# Test: c_variable-7.52
# Desc: type of e
mi_gdb_test "-var-info-type e" \
"\\^done,type=\"enum foo\"" \
"info type variable e"
# Test: c_variable-7.53
# Desc: is e editable
mi_gdb_test "-var-show-attributes e" \
"\\^done,attr=\"editable\"" \
"is e editable"
# Test: c_variable-7.54
# Desc: number of children of e
mi_gdb_test "-var-info-num-children e" \
"\\^done,numchild=\"0\"" \
"get number of children of e"
# Test: c_variable-7.55
# Desc: children of e
mi_gdb_test "-var-list-children e" \
"\\^done,numchild=\"0\"" \
"get children of e"
# Test: c_variable-7.60
# Desc: create anone
mi_gdb_test "-var-create anone * anone" \
"\\^done,name=\"anone\",numchild=\"0\",type=\"enum \{\\.\\.\\.\}\"" \
"create local variable anone"
setup_xfail "*-*-*"
# Test: c_variable-7.61
# Desc: value of anone
mi_gdb_test "-var-evaluate-expression anone" \
"\\^done,value=\"A\"" \
"eval variable anone"
clear_xfail "*-*-*"
# Test: c_variable-7.70
# Desc: create anone
mi_gdb_test "-var-create anone * anone" \
"&\"Duplicate variable object name\\\\n\".*\\^error,msg=\"Duplicate variable object name\"" \
"create duplicate local variable anone"
# Test: c_variable-7.72
# Desc: type of anone
mi_gdb_test "-var-info-type anone" \
"\\^done,type=\"enum \{\\.\\.\\.\}\"" \
"info type variable anone"
# Test: c_variable-7.73
# Desc: is anone editable
mi_gdb_test "-var-show-attributes anone" \
"\\^done,attr=\"editable\"" \
"is anone editable"
# Test: c_variable-7.74
# Desc: number of children of anone
mi_gdb_test "-var-info-num-children anone" \
"\\^done,numchild=\"0\"" \
"get number of children of anone"
# Test: c_variable-7.75
# Desc: children of anone
mi_gdb_test "-var-list-children anone" \
"\\^done,numchild=\"0\"" \
"get children of anone"
# Record fp
send_gdb "p/x \$fp\n"
gdb_expect {
-re ".*($hex).*\\^done\r\n$mi_gdb_prompt$" {
pass "print FP register"
set fp $expect_out(1,string)
}
# -re ".*" { fail "print FP register"}
timeout { fail "print FP register (timeout)"}
}
mi_gdb_test "200-break-insert incr_a" \
"200\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"incr_a\",file=\".*var-cmd.c\",line=\"85\",times=\"0\"\}" \
"break-insert operation"
send_gdb "-exec-continue\n"
gdb_expect {
-re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\{\{name=\"a\",value=\"2\.*\"\}\},file=\".*var-cmd.c\",line=\"85\"\}\r\n$mi_gdb_prompt$" {
pass "continue to incr_a"
}
timeout {
fail "continue to incr_a (timeout)"
}
}
# Test: c_variable-7.81
# Desc: Create variables in different scopes
mi_gdb_test "-var-create a1 * a" \
"\\^done,name=\"a1\",numchild=\"0\",type=\"char\"" \
"create local variable a1"
mi_gdb_test "-var-create a2 $fp a" \
"\\^done,name=\"a2\",numchild=\"0\",type=\"int\"" \
"create variable a2 in different scope"
#gdbtk_test c_variable-7.81 {create variables in different scopes} {
# set a1 [gdb_variable create -expr a]
# set a2 [gdb_variable create -expr a -frame $fp]
# set vals {}
# lappend vals [$a1 value]
# lappend vals [$a2 value]
# set vals
#} {2 1}
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,195 @@
# Copyright (C) 1999 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
#
# Test essential Machine interface (MI) operations
#
# Verify that, using the MI, we can run a simple program and perform basic
# debugging activities like: insert breakpoints, run the program,
# step, next, continue until it ends and, last but not least, quit.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but to verify the correct output response to MI operations.
#
load_lib mi-support.exp
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "basics"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
proc test_watchpoint_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert a watchpoint and list
# Tests:
# -break-watch C
# -break-list
mi_gdb_test "111-break-watch C" \
"111\\^done,wpt=\{number=\"2\",exp=\"C\"\}" \
"break-watch operation"
mi_gdb_test "222-break-list" \
"222\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"1\"\},bkpt=\{number=\"2\",type=\"watchpoint\",disp=\"keep\",enabled=\"y\",addr=\"\",what=\"C\",times=\"0\"\}\}" \
"list of watchpoints"
}
# UNUSED at the time
proc test_awatch_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert an access watchpoint and list it
# Tests:
# -break-watch -a A
# -break-list
mi_gdb_test "333-break-watch -a A" \
"333\\^done,bkpt=\{number=\"1\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
"break-watch -a operation"
mi_gdb_test "444-break-list" \
"444\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"3\",type=\"watchpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
"list of watchpoints awatch"
mi_gdb_test "777-break-delete 3" \
"777\\^done" \
"delete access watchpoint"
}
# UNUSED at the time
proc test_rwatch_creation_and_listing {} {
global mi_gdb_prompt
global srcfile
global hex
# Insert a read watchpoint and list it.
# Tests:
# -break-insert -r B
# -break-list
mi_gdb_test "200-break-watch -r C" \
"200\\^done,bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
"break-insert -r operation"
mi_gdb_test "300-break-list" \
"300\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
"list of breakpoints"
mi_gdb_test "177-break-delete 4" \
"177\\^done" \
"delete read watchpoint"
}
proc test_running_the_program {} {
global mi_gdb_prompt
global hex
# Run the program without args, then specify srgs and rerun the program
# Tests:
# -exec-run
mi_gdb_test "300-break-insert callee4" \
"300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
"insert breakpoint at callee4"
# mi_gdb_test cannot be used for asynchronous commands because there are
# two prompts involved and this can lead to a race condition.
# The following is equivalent to a send_gdb "000-exec-run\n"
mi_run_cmd
# The running part has been checked already by mi_run_cmd
gdb_expect {
-re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
{ pass "run to callee4" }
-re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
timeout {fail "run to callee4 (timeout 2)"}
}
}
proc test_watchpoint_triggering {} {
global mi_gdb_prompt
global hex
# Continue execution until the watchpoint is reached, continue again,
# to see the watchpoint go out of scope.
# Does:
# -exec-continue (Here wp triggers)
# -exec-continue (Here wp goes out of scope)
send_gdb "222-exec-continue\n"
gdb_expect {
-re "222\\^running\r\n$mi_gdb_prompt" {
gdb_expect {
-re "222\\*stopped,reason=\"watchpoint-trigger\",wpt=\{number=\"2\",exp=\"C\"\},value=\{old=\".*\",new=\"3\"\},thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
pass "watchpoint trigger"
}
-re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (2)"}
timeout {fail "watchpoint trigger (timeout 2)"}
}
}
-re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (1)"}
timeout {fail "watchpoint trigger (timeout 1)"}
}
send_gdb "223-exec-continue\n"
gdb_expect {
-re "223\\^running\r\n$mi_gdb_prompt" {
gdb_expect {
-re "\[\r\n\]*223\\*stopped,reason=\"watchpoint-scope\",wpnum=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {
pass "wp out of scope"
}
-re ".*$mi_gdb_prompt$" {fail "wp out of scope (2)"}
timeout {fail "wp out of scope (timeout 2)"}
}
}
-re ".*$mi_gdb_prompt$" {fail "wp out of scope (1)"}
timeout {fail "wp out of scope (timeout 1)"}
}
}
test_running_the_program
test_watchpoint_creation_and_listing
#test_rwatch_creation_and_listing
#test_awatch_creation_and_listing
test_watchpoint_triggering
mi_gdb_exit
return 0
# Local variables:
# change-log-default-name: "ChangeLog-mi"
# End:

View File

@ -0,0 +1,25 @@
# This is a (bogus) sample user command built to test the printing
# of commands.
define test
set $a = 1
set $b = 2
if ($a > $b)
set $a = 1
set $b = 2
while ($a > $b)
set $a = 1
set $b = 2
end
else
set $a = 1
set $b = 2
end
while ($a < $b)
set $a = $a + 1
set $c = $a
if ($a = $b)
set $c = 5
end
set $a = 1
set $b = 2
end

View File

@ -0,0 +1,26 @@
foo (void)
{
int i, x, y, z;
x = 0;
y = 1;
i = 0;
while (i < 2)
i++;
x = i;
y = 2 * x;
z = x + y;
y = x + z;
x = 9;
y = 10;
}
main ()
{
int a = 1;
foo ();
a += 2;
return 0;
}

View File

@ -0,0 +1,296 @@
struct _simple_struct {
int integer;
unsigned int unsigned_integer;
char character;
signed char signed_character;
char *char_ptr;
int array_of_10[10];
};
typedef struct _simple_struct simpleton;
simpleton global_simple;
enum foo {
bar = 1,
baz
};
typedef enum foo efoo;
union named_union
{
int integer;
char *char_ptr;
};
typedef struct _struct_decl {
int integer;
char character;
char *char_ptr;
long long_int;
int **int_ptr_ptr;
long long_array[10];
void (*func_ptr) (void);
struct _struct_decl (*func_ptr_struct) (int, char *, long);
struct _struct_decl *(*func_ptr_ptr) (int, char *, long);
union {
int a;
char *b;
long c;
enum foo d;
} u1;
struct {
union {
struct {
int d;
char e[10];
int *(*func) (void);
efoo foo;
} u1s1;
long f;
struct {
char array_ptr[2];
int (*func) (int, char *);
} u1s2;
} u2;
int g;
char h;
long i[10];
} s2;
} weird_struct;
struct _struct_n_pointer {
char ****char_ptr;
long ****long_ptr;
struct _struct_n_pointer *ptrs[3];
struct _struct_n_pointer *next;
};
void do_locals_tests (void);
void do_block_tests (void);
void subroutine1 (int, long *);
void nothing (void);
void do_children_tests (void);
void do_special_tests (void);
void incr_a (char);
void incr_a (char a)
{
int b;
b = a;
}
void
do_locals_tests ()
{
int linteger;
int *lpinteger;
char lcharacter;
char *lpcharacter;
long llong;
long *lplong;
float lfloat;
float *lpfloat;
double ldouble;
double *lpdouble;
struct _simple_struct lsimple;
struct _simple_struct *lpsimple;
void (*func) (void);
/* Simple assignments */
linteger = 1234;
lpinteger = &linteger;
lcharacter = 'a';
lpcharacter = &lcharacter;
llong = 2121L;
lplong = &llong;
lfloat = 2.1;
lpfloat = &lfloat;
ldouble = 2.718281828459045;
lpdouble = &ldouble;
lsimple.integer = 1234;
lsimple.unsigned_integer = 255;
lsimple.character = 'a';
lsimple.signed_character = 21;
lsimple.char_ptr = &lcharacter;
lpsimple = &lsimple;
func = nothing;
/* Check pointers */
linteger = 4321;
lcharacter = 'b';
llong = 1212L;
lfloat = 1.2;
ldouble = 5.498548281828172;
lsimple.integer = 255;
lsimple.unsigned_integer = 4321;
lsimple.character = 'b';
lsimple.signed_character = 0;
subroutine1 (linteger, &llong);
}
void
nothing ()
{
}
void
subroutine1 (int i, long *l)
{
global_simple.integer = i + 3;
i = 212;
*l = 12;
}
void
do_block_tests ()
{
int cb = 12;
{
int foo;
foo = 123;
{
int foo2;
foo2 = 123;
{
int foo;
foo = 321;
}
foo2 = 0;
}
foo = 0;
}
cb = 21;
}
void
do_children_tests (void)
{
weird_struct *weird;
struct _struct_n_pointer *psnp;
struct _struct_n_pointer snp0, snp1, snp2;
char a0, *a1, **a2, ***a3;
char b0, *b1, **b2, ***b3;
char c0, *c1, **c2, ***c3;
long z0, *z1, **z2, ***z3;
long y0, *y1, **y2, ***y3;
long x0, *x1, **x2, ***x3;
int *foo;
int bar;
struct _struct_decl struct_declarations;
weird = &struct_declarations;
struct_declarations.integer = 123;
weird->char_ptr = "hello";
bar = 2121;
foo = &bar;
struct_declarations.int_ptr_ptr = &foo;
weird->long_array[0] = 1234;
struct_declarations.long_array[1] = 2345;
weird->long_array[2] = 3456;
struct_declarations.long_array[3] = 4567;
weird->long_array[4] = 5678;
struct_declarations.long_array[5] = 6789;
weird->long_array[6] = 7890;
struct_declarations.long_array[7] = 8901;
weird->long_array[8] = 9012;
struct_declarations.long_array[9] = 1234;
weird->func_ptr = nothing;
/* Struct/pointer/array tests */
a0 = '0';
a1 = &a0;
a2 = &a1;
a3 = &a2;
b0 = '1';
b1 = &b0;
b2 = &b1;
b3 = &b2;
c0 = '2';
c1 = &c0;
c2 = &c1;
c3 = &c2;
z0 = 0xdead + 0;
z1 = &z0;
z2 = &z1;
z3 = &z2;
y0 = 0xdead + 1;
y1 = &y0;
y2 = &y1;
y3 = &y2;
x0 = 0xdead + 2;
x1 = &x0;
x2 = &x1;
x3 = &x2;
snp0.char_ptr = &a3;
snp0.long_ptr = &z3;
snp0.ptrs[0] = &snp0;
snp0.ptrs[1] = &snp1;
snp0.ptrs[2] = &snp2;
snp0.next = &snp1;
snp1.char_ptr = &b3;
snp1.long_ptr = &y3;
snp1.ptrs[0] = &snp0;
snp1.ptrs[1] = &snp1;
snp1.ptrs[2] = &snp2;
snp1.next = &snp2;
snp2.char_ptr = &c3;
snp2.long_ptr = &x3;
snp2.ptrs[0] = &snp0;
snp2.ptrs[1] = &snp1;
snp2.ptrs[2] = &snp2;
snp2.next = 0x0;
psnp = &snp0;
snp0.char_ptr = &b3;
snp1.char_ptr = &c3;
snp2.char_ptr = &a3;
snp0.long_ptr = &y3;
snp1.long_ptr = &x3;
snp2.long_ptr = &z3;
}
void
do_special_tests (void)
{
union named_union u;
union {
int a;
char b;
long c;
} anonu;
struct _simple_struct s;
struct {
int a;
char b;
long c;
} anons;
enum foo e;
enum { A, B, C } anone;
int array[21];
int a;
a = 1;
incr_a(2);
}
int
main (int argc, char *argv [])
{
do_locals_tests ();
do_block_tests ();
do_children_tests ();
do_special_tests ();
exit (0);
}

View File

@ -0,0 +1,683 @@
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# This file was based on a file written by Fred Fish. (fnf@cygnus.com)
# Test setup routines that work with the MI interpreter.
# The variable mi_gdb_prompt is a regexp which matches the gdb mi prompt.
# Set it if it is not already set.
global mi_gdb_prompt
if ![info exists mi_gdb_prompt] then {
set mi_gdb_prompt "\[(\]gdb\[)\] \r\n"
}
set MIFLAGS "-i=mi"
#
# mi_gdb_exit -- exit the GDB, killing the target program if necessary
#
proc mi_gdb_exit {} {
catch mi_uncatched_gdb_exit
}
proc mi_uncatched_gdb_exit {} {
global GDB
global GDBFLAGS
global verbose
global gdb_spawn_id;
global gdb_prompt
global mi_gdb_prompt
global MIFLAGS
gdb_stop_suppressing_tests;
if { [info procs sid_exit] != "" } {
sid_exit
}
if ![info exists gdb_spawn_id] {
return;
}
verbose "Quitting $GDB $GDBFLAGS $MIFLAGS"
if { [is_remote host] && [board_info host exists fileid] } {
send_gdb "999-gdb-exit\n";
gdb_expect 10 {
-re "y or n" {
send_gdb "y\n";
exp_continue;
}
-re "Undefined command.*$gdb_prompt $" {
send_gdb "quit\n"
exp_continue;
}
-re "DOSEXIT code" { }
default { }
}
}
if ![is_remote host] {
remote_close host;
}
unset gdb_spawn_id
}
#
# start gdb -- start gdb running, default procedure
#
# When running over NFS, particularly if running many simultaneous
# tests on different hosts all using the same server, things can
# get really slow. Give gdb at least 3 minutes to start up.
#
proc mi_gdb_start { } {
global verbose
global GDB
global GDBFLAGS
global gdb_prompt
global mi_gdb_prompt
global timeout
global gdb_spawn_id;
global MIFLAGS
gdb_stop_suppressing_tests;
verbose "Spawning $GDB -nw $GDBFLAGS $MIFLAGS"
if [info exists gdb_spawn_id] {
return 0;
}
if ![is_remote host] {
if { [which $GDB] == 0 } then {
perror "$GDB does not exist."
exit 1
}
}
set res [remote_spawn host "$GDB -nw $GDBFLAGS $MIFLAGS [host_info gdb_opts]"];
if { $res < 0 || $res == "" } {
perror "Spawning $GDB failed."
return 1;
}
gdb_expect {
-re ".*UI_OUT.*$mi_gdb_prompt$" {
verbose "GDB initialized."
}
-re ".*$mi_gdb_prompt$" {
untested "Skip mi tests (output not in headless format)."
remote_close host;
return -1;
}
-re ".*$gdb_prompt $" {
untested "Skip mi tests (got non-mi prompt)."
remote_close host;
return -1;
}
timeout {
perror "(timeout) GDB never initialized after 10 seconds."
remote_close host;
return -1
}
}
set gdb_spawn_id -1;
# FIXME: mi output does not go through pagers, so these can be removed.
# force the height to "unlimited", so no pagers get used
send_gdb "100-gdb-set height 0\n"
gdb_expect 10 {
-re ".*100-gdb-set height 0\r\n100\\\^done\r\n$mi_gdb_prompt$" {
verbose "Setting height to 0." 2
}
timeout {
warning "Couldn't set the height to 0"
}
}
# force the width to "unlimited", so no wraparound occurs
send_gdb "101-gdb-set width 0\n"
gdb_expect 10 {
-re ".*101-gdb-set width 0\r\n101\\\^done\r\n$mi_gdb_prompt$" {
verbose "Setting width to 0." 2
}
timeout {
warning "Couldn't set the width to 0."
}
}
# Finally start SID.
if { [info procs sid_start] != "" } {
verbose "Spawning SID"
sid_start
}
return 0;
}
# Many of the tests depend on setting breakpoints at various places and
# running until that breakpoint is reached. At times, we want to start
# with a clean-slate with respect to breakpoints, so this utility proc
# lets us do this without duplicating this code everywhere.
#
proc mi_delete_breakpoints {} {
global mi_gdb_prompt
# FIXME: The mi operation won't accept a prompt back and will use the 'all' arg
send_gdb "102-break-delete\n"
gdb_expect 30 {
-re "Delete all breakpoints.*y or n.*$" {
send_gdb "y\n";
exp_continue
}
-re ".*102-break-delete\r\n102\\\^done\r\n$mi_gdb_prompt$" {
# This happens if there were no breakpoints
}
timeout { perror "Delete all breakpoints in delete_breakpoints (timeout)" ; return }
}
# The correct output is not "No breakpoints or watchpoints." but an
# empty BreakpointTable. Also, a query is not acceptable with mi.
send_gdb "103-break-list\n"
gdb_expect 30 {
-re "103-break-list\r\n103\\\^done,BreakpointTable=\{\}\r\n$mi_gdb_prompt$" {}
-re "103-break-list\r\n103\\\^doneNo breakpoints or watchpoints.\r\n\r\n$mi_gdb_prompt$" {warning "Unexpected console text received"}
-re "$mi_gdb_prompt$" { perror "Breakpoints not deleted" ; return }
-re "Delete all breakpoints.*or n.*$" {
warning "Unexpected prompt for breakpoints deletion";
send_gdb "y\n";
exp_continue
}
timeout { perror "-break-list (timeout)" ; return }
}
}
proc mi_gdb_reinitialize_dir { subdir } {
global mi_gdb_prompt
global suppress_flag
if { $suppress_flag } {
return
}
if [is_remote host] {
return "";
}
send_gdb "104-environment-directory\n"
gdb_expect 60 {
-re ".*Reinitialize source path to empty.*y or n. " {
warning "Got confirmation prompt for dir reinitialization."
send_gdb "y\n"
gdb_expect 60 {
-re "$mi_gdb_prompt$" {}
timeout {error "Dir reinitialization failed (timeout)"}
}
}
-re "$mi_gdb_prompt$" {}
timeout {error "Dir reinitialization failed (timeout)"}
}
send_gdb "105-environment-directory $subdir\n"
gdb_expect 60 {
-re "Source directories searched.*$mi_gdb_prompt$" {
verbose "Dir set to $subdir"
}
-re "105\\\^done\r\n$mi_gdb_prompt$" {
# FIXME: We return just the prompt for now.
verbose "Dir set to $subdir"
# perror "Dir \"$subdir\" failed."
}
}
}
#
# load a file into the debugger.
# return a -1 if anything goes wrong.
#
proc mi_gdb_load { arg } {
global verbose
global loadpath
global loadfile
global GDB
global mi_gdb_prompt
upvar timeout timeout
# ``gdb_unload''
# ``gdb_file_cmd''
# FIXME: Several of these patterns are only acceptable for console
# output. Queries are an error for mi.
send_gdb "105-file-exec-and-symbols $arg\n"
gdb_expect 120 {
-re "Reading symbols from.*done.*$mi_gdb_prompt$" {
verbose "\t\tLoaded $arg into the $GDB"
# All OK
}
-re "has no symbol-table.*$mi_gdb_prompt$" {
perror "$arg wasn't compiled with \"-g\""
return -1
}
-re "A program is being debugged already.*Kill it.*y or n. $" {
send_gdb "y\n"
verbose "\t\tKilling previous program being debugged"
exp_continue
}
-re "Load new symbol table from \".*\".*y or n. $" {
send_gdb "y\n"
gdb_expect 120 {
-re "Reading symbols from.*done.*$mi_gdb_prompt$" {
verbose "\t\tLoaded $arg with new symbol table into $GDB"
# All OK
}
timeout {
perror "(timeout) Couldn't load $arg, other program already loaded."
return -1
}
}
}
-re "No such file or directory.*$mi_gdb_prompt$" {
perror "($arg) No such file or directory\n"
return -1
}
-re "105-file-exec-and-symbols .*\r\n105\\\^done\r\n$mi_gdb_prompt$" {
# We are just giving the prompt back for now
# All OK
}
timeout {
perror "couldn't load $arg into $GDB (timed out)."
return -1
}
eof {
# This is an attempt to detect a core dump, but seems not to
# work. Perhaps we need to match .* followed by eof, in which
# gdb_expect does not seem to have a way to do that.
perror "couldn't load $arg into $GDB (end of file)."
return -1
}
}
# ``load''
if { [info procs send_target_sid] != "" } {
# For SID, things get complex
send_target_sid
gdb_expect 60 {
-re "\\^done,.*$mi_gdb_prompt$" {
}
timeout {
perror "Unable to connect to SID target"
return -1
}
}
send_gdb "48-target-download\n"
gdb_expect 10 {
-re "48\\^done.*$mi_gdb_prompt$" {
}
timeout {
perror "Unable to download to SID target"
return -1
}
}
} elseif { [target_info protocol] == "sim" } {
# For the simulator, just connect to it directly.
send_gdb "47-target-select sim\n"
gdb_expect 10 {
-re "47\\^connected.*$mi_gdb_prompt$" {
}
timeout {
perror "Unable to select sim target"
return -1
}
}
send_gdb "48-target-download\n"
gdb_expect 10 {
-re "48\\^done.*$mi_gdb_prompt$" {
}
timeout {
perror "Unable to download to sim target"
return -1
}
}
}
return 0
}
# mi_gdb_test COMMAND PATTERN MESSAGE -- send a command to gdb; test the result.
#
# COMMAND is the command to execute, send to GDB with send_gdb. If
# this is the null string no command is sent.
# PATTERN is the pattern to match for a PASS, and must NOT include
# the \r\n sequence immediately before the gdb prompt.
# MESSAGE is an optional message to be printed. If this is
# omitted, then the pass/fail messages use the command string as the
# message. (If this is the empty string, then sometimes we don't
# call pass or fail at all; I don't understand this at all.)
#
# Returns:
# 1 if the test failed,
# 0 if the test passes,
# -1 if there was an internal error.
#
proc mi_gdb_test { args } {
global verbose
global mi_gdb_prompt
global GDB
upvar timeout timeout
if [llength $args]>2 then {
set message [lindex $args 2]
} else {
set message [lindex $args 0]
}
set command [lindex $args 0]
set pattern [lindex $args 1]
if [llength $args]==5 {
set question_string [lindex $args 3];
set response_string [lindex $args 4];
} else {
set question_string "^FOOBAR$"
}
if $verbose>2 then {
send_user "Sending \"$command\" to gdb\n"
send_user "Looking to match \"$pattern\"\n"
send_user "Message is \"$message\"\n"
}
set result -1
set string "${command}\n";
if { $command != "" } {
while { "$string" != "" } {
set foo [string first "\n" "$string"];
set len [string length "$string"];
if { $foo < [expr $len - 1] } {
set str [string range "$string" 0 $foo];
if { [send_gdb "$str"] != "" } {
global suppress_flag;
if { ! $suppress_flag } {
perror "Couldn't send $command to GDB.";
}
fail "$message";
return $result;
}
gdb_expect 2 {
-re "\[\r\n\]" { }
timeout { }
}
set string [string range "$string" [expr $foo + 1] end];
} else {
break;
}
}
if { "$string" != "" } {
if { [send_gdb "$string"] != "" } {
global suppress_flag;
if { ! $suppress_flag } {
perror "Couldn't send $command to GDB.";
}
fail "$message";
return $result;
}
}
}
if [info exists timeout] {
set tmt $timeout;
} else {
global timeout;
if [info exists timeout] {
set tmt $timeout;
} else {
set tmt 60;
}
}
gdb_expect $tmt {
-re "\\*\\*\\* DOSEXIT code.*" {
if { $message != "" } {
fail "$message";
}
gdb_suppress_entire_file "GDB died";
return -1;
}
-re "Ending remote debugging.*$mi_gdb_prompt\[ \]*$" {
if ![isnative] then {
warning "Can`t communicate to remote target."
}
gdb_exit
gdb_start
set result -1
}
-re "(${question_string})$" {
send_gdb "$response_string\n";
exp_continue;
}
-re "Undefined.* command:.*$mi_gdb_prompt\[ \]*$" {
perror "Undefined command \"$command\"."
fail "$message"
set result 1
}
-re "Ambiguous command.*$mi_gdb_prompt\[ \]*$" {
perror "\"$command\" is not a unique command name."
fail "$message"
set result 1
}
-re "\[\r\n\]*($pattern)\[\r\n\]+$mi_gdb_prompt\[ \]*$" {
if ![string match "" $message] then {
pass "$message"
}
set result 0
}
-re "Program exited with code \[0-9\]+.*$mi_gdb_prompt\[ \]*$" {
if ![string match "" $message] then {
set errmsg "$message: the program exited"
} else {
set errmsg "$command: the program exited"
}
fail "$errmsg"
return -1
}
-re "The program is not being run.*$mi_gdb_prompt\[ \]*$" {
if ![string match "" $message] then {
set errmsg "$message: the program is no longer running"
} else {
set errmsg "$command: the program is no longer running"
}
fail "$errmsg"
return -1
}
-re ".*$mi_gdb_prompt\[ \]*$" {
if ![string match "" $message] then {
fail "$message"
}
set result 1
}
"<return>" {
send_gdb "\n"
perror "Window too small."
fail "$message"
}
-re "\\(y or n\\) " {
send_gdb "n\n"
perror "Got interactive prompt."
fail "$message"
}
eof {
perror "Process no longer exists"
if { $message != "" } {
fail "$message"
}
return -1
}
full_buffer {
perror "internal buffer is full."
fail "$message"
}
timeout {
if ![string match "" $message] then {
fail "$message (timeout)"
}
set result 1
}
}
return $result
}
#
# MI run command. (A modified version of gdb_run_cmd)
#
# In patterns, the newline sequence ``\r\n'' is matched explicitly as
# ``.*$'' could swallow up output that we attempt to match elsewhere.
proc mi_run_cmd {args} {
global suppress_flag
if { $suppress_flag } {
return -1
}
global mi_gdb_prompt
if [target_info exists gdb_init_command] {
send_gdb "[target_info gdb_init_command]\n";
gdb_expect 30 {
-re "$mi_gdb_prompt$" { }
default {
perror "gdb_init_command for target failed";
return;
}
}
}
if [target_info exists use_gdb_stub] {
if [target_info exists gdb,do_reload_on_run] {
# Specifying no file, defaults to the executable
# currently being debugged.
if { [mi_gdb_load ""] < 0 } {
return;
}
send_gdb "000-exec-continue\n";
gdb_expect 60 {
-re "Continu\[^\r\n\]*\[\r\n\]" {}
default {}
}
return;
}
}
send_gdb "000-exec-run $args\n"
gdb_expect {
-re "000\\^running\r\n${mi_gdb_prompt}" {
}
timeout {
perror "Unable to start target"
return
}
}
# NOTE: Shortly after this there will be a ``000*stopping,...(gdb)''
}
#
# Just like run-to-main but works with the MI interface
#
proc mi_run_to_main { } {
global suppress_flag
if { $suppress_flag } {
return -1
}
global mi_gdb_prompt
global hex
global decimal
global srcdir
global subdir
global binfile
global srcfile
set test "mi run-to-main"
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
mi_gdb_test "200-break-insert main" \
"200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*\",line=\"\[0-9\]*\",times=\"0\"\}" \
"breakpoint at main"
mi_run_cmd
gdb_expect {
-re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
pass "$test"
return 0
}
timeout {
fail "$test (timeout)"
return -1
}
}
}
# Next to the next statement
proc mi_next { test } {
global suppress_flag
if { $suppress_flag } {
return -1
}
global mi_gdb_prompt
send_gdb "220-exec-next\n"
gdb_expect {
-re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\{.*\},,file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
pass "$test"
return 0
}
timeout {
fail "$test"
return -1
}
}
}
# Step to the next statement
proc mi_step { test } {
global suppress_flag
if { $suppress_flag } {
return -1
}
global mi_gdb_prompt
send_gdb "220-exec-step\n"
gdb_expect {
-re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\{.*\},,file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
pass "$test"
return 0
}
timeout {
fail "$test"
return -1
}
}
}
# Local variables:
# change-log-default-name: "../gdb.mi/ChangeLog-mi"
# End:

View File

@ -801,6 +801,17 @@ gdb_init (argv0)
uiout = cli_out_new (gdb_stdout);
#endif
#ifdef UI_OUT
/* All the interpreters should have had a look at things by now.
Initialize the selected interpreter. */
if (interpreter_p && !init_ui_hook)
{
fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n",
interpreter_p);
exit (1);
}
#endif
if (init_ui_hook)
init_ui_hook (argv0);
}