Remove dbx mode

This patch removes gdb's dbx mode.  Regression tested on x86-64 Fedora
34.
This commit is contained in:
Tom Tromey 2022-03-04 11:29:27 -07:00
parent 0653f01479
commit 49a82d50c0
13 changed files with 24 additions and 503 deletions

View file

@ -8,6 +8,8 @@
* Remove support for building against Python 2, it is now only possible to * Remove support for building against Python 2, it is now only possible to
build GDB against Python 3. build GDB against Python 3.
* DBX mode has been removed.
* Python API * Python API
** New function gdb.format_address(ADDRESS, PROGSPACE, ARCHITECTURE), ** New function gdb.format_address(ADDRESS, PROGSPACE, ARCHITECTURE),

View file

@ -9296,79 +9296,6 @@ thbreak_command (const char *arg, int from_tty)
break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty); break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
} }
static void
stop_command (const char *arg, int from_tty)
{
gdb_printf (_("Specify the type of breakpoint to set.\n\
Usage: stop in <function | address>\n\
stop at <line>\n"));
}
static void
stopin_command (const char *arg, int from_tty)
{
int badInput = 0;
if (arg == NULL)
badInput = 1;
else if (*arg != '*')
{
const char *argptr = arg;
int hasColon = 0;
/* Look for a ':'. If this is a line number specification, then
say it is bad, otherwise, it should be an address or
function/method name. */
while (*argptr && !hasColon)
{
hasColon = (*argptr == ':');
argptr++;
}
if (hasColon)
badInput = (*argptr != ':'); /* Not a class::method */
else
badInput = isdigit (*arg); /* a simple line number */
}
if (badInput)
gdb_printf (_("Usage: stop in <function | address>\n"));
else
break_command_1 (arg, 0, from_tty);
}
static void
stopat_command (const char *arg, int from_tty)
{
int badInput = 0;
if (arg == NULL || *arg == '*') /* no line number */
badInput = 1;
else
{
const char *argptr = arg;
int hasColon = 0;
/* Look for a ':'. If there is a '::' then get out, otherwise
it is probably a line number. */
while (*argptr && !hasColon)
{
hasColon = (*argptr == ':');
argptr++;
}
if (hasColon)
badInput = (*argptr == ':'); /* we have class::method */
else
badInput = !isdigit (*arg); /* not a line number */
}
if (badInput)
gdb_printf (_("Usage: stop at LINE\n"));
else
break_command_1 (arg, 0, from_tty);
}
/* The dynamic printf command is mostly like a regular breakpoint, but /* The dynamic printf command is mostly like a regular breakpoint, but
with a prewired command list consisting of a single output command, with a prewired command list consisting of a single output command,
built from extra arguments supplied on the dprintf command built from extra arguments supplied on the dprintf command
@ -15105,32 +15032,6 @@ BREAK_ARGS_HELP ("break")));
add_com_alias ("bre", break_cmd, class_run, 1); add_com_alias ("bre", break_cmd, class_run, 1);
add_com_alias ("brea", break_cmd, class_run, 1); add_com_alias ("brea", break_cmd, class_run, 1);
if (dbx_commands)
{
add_abbrev_prefix_cmd ("stop", class_breakpoint, stop_command, _("\
Break in function/address or break at a line in the current file."),
&stoplist, 1, &cmdlist);
add_cmd ("in", class_breakpoint, stopin_command,
_("Break in function or address."), &stoplist);
add_cmd ("at", class_breakpoint, stopat_command,
_("Break at a line in the current file."), &stoplist);
add_com ("status", class_info, info_breakpoints_command, _("\
Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
The \"Type\" column indicates one of:\n\
\tbreakpoint - normal breakpoint\n\
\twatchpoint - watchpoint\n\
The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
address and file/line number respectively.\n\
\n\
Convenience variable \"$_\" and default examine address for \"x\"\n\
are set to the address of the last breakpoint listed unless the command\n\
is prefixed with \"server \".\n\n\
Convenience variable \"$bpnum\" contains the number of the last\n\
breakpoint set."));
}
cmd_list_element *info_breakpoints_cmd cmd_list_element *info_breakpoints_cmd
= add_info ("breakpoints", info_breakpoints_command, _("\ = add_info ("breakpoints", info_breakpoints_command, _("\
Status of specified breakpoints (all user-settable breakpoints if no argument).\n\ Status of specified breakpoints (all user-settable breakpoints if no argument).\n\

View file

@ -2421,8 +2421,7 @@ User-defined commands.\n\
The commands in this class are those defined by the user.\n\ The commands in this class are those defined by the user.\n\
Use the \"define\" command to define a command."), &cmdlist); Use the \"define\" command to define a command."), &cmdlist);
add_cmd ("support", class_support, _("Support facilities."), &cmdlist); add_cmd ("support", class_support, _("Support facilities."), &cmdlist);
if (!dbx_commands) add_cmd ("status", class_info, _("Status inquiries."), &cmdlist);
add_cmd ("status", class_info, _("Status inquiries."), &cmdlist);
add_cmd ("files", class_files, _("Specifying and examining files."), add_cmd ("files", class_files, _("Specifying and examining files."),
&cmdlist); &cmdlist);
add_cmd ("breakpoints", class_breakpoint, add_cmd ("breakpoints", class_breakpoint,
@ -2667,9 +2666,6 @@ can be shown using \"show listsize\"."));
add_com_alias ("l", list_cmd, class_files, 1); add_com_alias ("l", list_cmd, class_files, 1);
if (dbx_commands)
add_com_alias ("file", list_cmd, class_files, 1);
c = add_com ("disassemble", class_vars, disassemble_command, _("\ c = add_com ("disassemble", class_vars, disassemble_command, _("\
Disassemble a specified section of memory.\n\ Disassemble a specified section of memory.\n\
Usage: disassemble[/m|/r|/s] START [, END]\n\ Usage: disassemble[/m|/r|/s] START [, END]\n\

View file

@ -118,9 +118,6 @@ using RequireLongest = gdb::Requires<gdb::Or<std::is_same<T, LONGEST>,
#include "hashtab.h" #include "hashtab.h"
/* * Enable dbx commands if set. */
extern int dbx_commands;
/* * System root path, used to find libraries etc. */ /* * System root path, used to find libraries etc. */
extern std::string gdb_sysroot; extern std::string gdb_sysroot;

View file

@ -47713,9 +47713,6 @@ Read all symbols from the given symfile on the first access.
@item --readnever @item --readnever
Do not read symbol files. Do not read symbol files.
@item --dbx
Run in DBX compatibility mode.
@item --return-child-result @item --return-child-result
@value{GDBN}'s exit code will be the same as the child's exit code. @value{GDBN}'s exit code will be the same as the child's exit code.

View file

@ -1060,17 +1060,14 @@ _initialize_exec ()
{ {
struct cmd_list_element *c; struct cmd_list_element *c;
if (!dbx_commands) c = add_cmd ("file", class_files, file_command, _("\
{
c = add_cmd ("file", class_files, file_command, _("\
Use FILE as program to be debugged.\n\ Use FILE as program to be debugged.\n\
It is read for its symbols, for getting the contents of pure memory,\n\ It is read for its symbols, for getting the contents of pure memory,\n\
and it is the program executed when you use the `run' command.\n\ and it is the program executed when you use the `run' command.\n\
If FILE cannot be found as specified, your execution directory path\n\ If FILE cannot be found as specified, your execution directory path\n\
($PATH) is searched for a command of that name.\n\ ($PATH) is searched for a command of that name.\n\
No arg means to have no executable file and no symbols."), &cmdlist); No arg means to have no executable file and no symbols."), &cmdlist);
set_cmd_completer (c, filename_completer); set_cmd_completer (c, filename_completer);
}
c = add_cmd ("exec-file", class_files, exec_file_command, _("\ c = add_cmd ("exec-file", class_files, exec_file_command, _("\
Use FILE as program for getting contents of pure memory.\n\ Use FILE as program for getting contents of pure memory.\n\

View file

@ -8564,28 +8564,25 @@ normal_stop (void)
/* Look up the hook_stop and run it (CLI internally handles problem /* Look up the hook_stop and run it (CLI internally handles problem
of stop_command's pre-hook not existing). */ of stop_command's pre-hook not existing). */
if (stop_command != NULL) stop_context saved_context;
try
{ {
stop_context saved_context; execute_cmd_pre_hook (stop_command);
try
{
execute_cmd_pre_hook (stop_command);
}
catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error while running hook_stop:\n");
}
/* If the stop hook resumes the target, then there's no point in
trying to notify about the previous stop; its context is
gone. Likewise if the command switches thread or inferior --
the observers would print a stop for the wrong
thread/inferior. */
if (saved_context.changed ())
return 1;
} }
catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error while running hook_stop:\n");
}
/* If the stop hook resumes the target, then there's no point in
trying to notify about the previous stop; its context is
gone. Likewise if the command switches thread or inferior --
the observers would print a stop for the wrong
thread/inferior. */
if (saved_context.changed ())
return 1;
/* Notify observers about the stop. This is where the interpreters /* Notify observers about the stop. This is where the interpreters
print the stop event. */ print the stop event. */
@ -9489,9 +9486,8 @@ may be interspersed with actions, with the actions being performed for\n\
all signals cumulatively specified.")); all signals cumulatively specified."));
set_cmd_completer (c, handle_completer); set_cmd_completer (c, handle_completer);
if (!dbx_commands) stop_command = add_cmd ("stop", class_obscure,
stop_command = add_cmd ("stop", class_obscure, not_just_help_class_command, _("\
not_just_help_class_command, _("\
There is no `stop' command, but you can set a hook on `stop'.\n\ There is no `stop' command, but you can set a hook on `stop'.\n\
This allows you to set a list of commands to be run each time execution\n\ This allows you to set a list of commands to be run each time execution\n\
of the program stops."), &cmdlist); of the program stops."), &cmdlist);

View file

@ -61,9 +61,6 @@
do_setshow_command will free it. */ do_setshow_command will free it. */
char *interpreter_p; char *interpreter_p;
/* Whether dbx commands will be handled. */
int dbx_commands = 0;
/* System root path, used to find libraries etc. */ /* System root path, used to find libraries etc. */
std::string gdb_sysroot; std::string gdb_sysroot;
@ -766,7 +763,6 @@ captured_main_1 (struct captured_main_args *context)
static struct option long_options[] = static struct option long_options[] =
{ {
{"tui", no_argument, 0, OPT_TUI}, {"tui", no_argument, 0, OPT_TUI},
{"dbx", no_argument, &dbx_commands, 1},
{"readnow", no_argument, NULL, OPT_READNOW}, {"readnow", no_argument, NULL, OPT_READNOW},
{"readnever", no_argument, NULL, OPT_READNEVER}, {"readnever", no_argument, NULL, OPT_READNEVER},
{"r", no_argument, NULL, OPT_READNOW}, {"r", no_argument, NULL, OPT_READNOW},
@ -1028,9 +1024,6 @@ captured_main_1 (struct captured_main_args *context)
} }
} }
if (dbx_commands)
warning (_("--dbx mode is deprecated and will be removed"));
save_original_signals_state (quiet); save_original_signals_state (quiet);
/* Try to set up an alternate signal stack for SIGSEGV handlers. */ /* Try to set up an alternate signal stack for SIGSEGV handlers. */
@ -1437,7 +1430,6 @@ Output and user interface control:\n\n\
"), stream); "), stream);
#endif #endif
gdb_puts (_("\ gdb_puts (_("\
--dbx DBX compatibility mode.\n\
-q, --quiet, --silent\n\ -q, --quiet, --silent\n\
Do not print version number on startup.\n\n\ Do not print version number on startup.\n\n\
"), stream); "), stream);

View file

@ -3298,18 +3298,6 @@ Use \"set variable\" for variables with names identical to set subcommands.\n\
With a subcommand, this command modifies parts of the gdb environment.\n\ With a subcommand, this command modifies parts of the gdb environment.\n\
You can see these environment settings with the \"show\" command."), You can see these environment settings with the \"show\" command."),
&setlist, 1, &cmdlist); &setlist, 1, &cmdlist);
if (dbx_commands)
add_com ("assign", class_vars, set_command, _("\
Evaluate expression EXP and assign result to variable VAR.\n\
Usage: assign VAR = EXP\n\
This uses assignment syntax appropriate for the current language\n\
(VAR = EXP or VAR := EXP for example).\n\
VAR may be a debugger \"convenience\" variable (names starting\n\
with $), a register (a few standard names starting with $), or an actual\n\
variable in the program being debugged. EXP is any valid expression.\n\
Use \"set variable\" for variables with names identical to set subcommands.\n\
\nWith a subcommand, this command modifies parts of the gdb environment.\n\
You can see these environment settings with the \"show\" command."));
/* "call" is the same as "set", but handy for dbx users to call fns. */ /* "call" is the same as "set", but handy for dbx users to call fns. */
c = add_com ("call", class_vars, call_command, _("\ c = add_com ("call", class_vars, call_command, _("\

View file

@ -1926,9 +1926,6 @@ directory in which the source file was compiled into object code.\n\
With no argument, reset the search path to $cdir:$cwd, the default."), With no argument, reset the search path to $cdir:$cwd, the default."),
&cmdlist); &cmdlist);
if (dbx_commands)
add_com_alias ("use", directory_cmd, class_files, 0);
set_cmd_completer (directory_cmd, filename_completer); set_cmd_completer (directory_cmd, filename_completer);
add_setshow_optional_filename_cmd ("directories", add_setshow_optional_filename_cmd ("directories",

View file

@ -2903,24 +2903,6 @@ find_frame_for_function (const char *function_name)
return frame; return frame;
} }
/* Implements the dbx 'func' command. */
static void
func_command (const char *arg, int from_tty)
{
if (arg == NULL)
return;
struct frame_info *frame = find_frame_for_function (arg);
if (frame == NULL)
error (_("'%s' not within current stack frame."), arg);
if (frame != get_selected_frame (NULL))
{
select_frame (frame);
print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}
}
/* The qcs command line flags for the "frame apply" commands. Keep /* The qcs command line flags for the "frame apply" commands. Keep
this in sync with the "thread apply" commands. */ this in sync with the "thread apply" commands. */
@ -3560,11 +3542,6 @@ Prints the argument variables of the current stack frame.\n"),
false)); false));
set_cmd_completer_handle_brkchars (cmd, info_print_command_completer); set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);
if (dbx_commands)
add_com ("func", class_stack, func_command, _("\
Select the stack frame that contains NAME.\n\
Usage: func NAME"));
/* Install "set print raw frame-arguments", a deprecated spelling of /* Install "set print raw frame-arguments", a deprecated spelling of
"set print raw-frame-arguments". */ "set print raw-frame-arguments". */
set_show_commands set_show_frame_args set_show_commands set_show_frame_args

View file

@ -6932,17 +6932,6 @@ Prints the global and static variables.\n"),
_("global and static variables"), _("global and static variables"),
true)); true));
set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer); set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
if (dbx_commands)
{
c = add_com ("whereis", class_info, info_variables_command,
info_print_args_help (_("\
All global and static variable names, or those matching REGEXPs.\n\
Usage: whereis [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the global and static variables.\n"),
_("global and static variables"),
true));
set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
}
c = add_info ("functions", info_functions_command, c = add_info ("functions", info_functions_command,
info_print_args_help (_("\ info_print_args_help (_("\

View file

@ -1,308 +0,0 @@
# Copyright 1998-2022 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
standard_testfile average.c sum.c
if {[build_executable $testfile.exp $testfile \
[list $srcfile $srcfile2] debug] == -1} {
untested "failed to compile"
return -1
}
#
# start gdb -- start gdb running, default procedure
#
proc dbx_gdb_start { } {
global prompt
global timeout
global gdb_spawn_id
save_vars { GDBFLAGS } {
append GDBFLAGS " -dbx"
set res [gdb_spawn]
if { $res != 0} {
return $res
}
}
set oldtimeout $timeout
set timeout [expr "$timeout + 60"]
gdb_expect {
-re ".*\r\n$gdb_prompt $" {
verbose "GDB initialized."
}
-re "$prompt $" {
perror "GDB never initialized."
unset gdb_spawn_id
return -1
}
timeout {
perror "(timeout) GDB never initialized."
unset gdb_spawn_id
return -1
}
}
set timeout $oldtimeout
# force the height to "unlimited", so no pagers get used
send_gdb "set height 0\n"
gdb_expect {
-re ".*$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 "set width 0\n"
gdb_expect {
-re ".*$prompt $" {
verbose "Setting width to 0." 2
}
timeout {
warning "Couldn't set the width to 0."
}
}
}
proc dbx_reinitialize_dir { subdir } {
global gdb_prompt
send_gdb "use\n"
gdb_expect {
-re "Reinitialize source path to empty.*y or n. " {
send_gdb "y\n"
gdb_expect {
-re "Source directories searched.*$gdb_prompt $" {
send_gdb "use $subdir\n"
gdb_expect {
-re "Source directories searched.*$gdb_prompt $" {
verbose "Dir set to $subdir"
}
-re ".*$gdb_prompt $" {
perror "Dir \"$subdir\" failed."
}
}
}
-re ".*$gdb_prompt $" {
perror "Dir \"$subdir\" failed."
}
}
}
-re ".*$gdb_prompt $" {
perror "Dir \"$subdir\" failed."
}
}
}
# In "testsuite/config/unix-gdb.exp", the routine "gdb_load"
# is defined as "gdb_file_cmd". The binding of "gdb_file_cmd"
# is done at invocation time. Before this file is processed,
# it binds to the definition in "testsuite/lib/gdb.exp"; after
# this file is processed, it binds to this definition.
# TCL lets us overrides a previous routine definition without a
# warning (isn't that special?).
#
# This means that tests before use "file" to load a target, and
# tests afterwards use the pair "symbol-file" "exec-file".
#
# I'm leaving it as it is for now because at the moment it
# is the only test we have of the use of the combination of
# "symbol-file" and "exec-file" to load a debugging target (the
# other definition uses "file".
#
# Symbol-file and exec-file should be tested explicitly, not
# as a side effect of running a particular test (in this case,
# "testsuite/gdb.compat/dbx.exp").
#
# CM: Renamed the procedure so it does not override the orginal file name.
# Having the test suite change behavior depending on the tests run makes
# it extremely difficult to reproduce errors. I've also added a
# "dbx_gdb_load" procedure. This and only this test will call these
# procedures now. I also added an "expect" to the "send exec-file" line.
# The "expect" waits for a prompt to appear. Otherwise, if the tests run
# too quickly, the caller could send another command before the prompt
# of this command returns, causing the test to get out of sync and fail
# seemingly randomly or only on a loaded system.
#
# Problem is, though, that the testsuite config files can override the definition of
# gdb_load (without notice, as was mentioned above). Unfortunately, the gdb_load proc
# that was copied into this test was a copy of the unix native version.
#
# The real problem that we're attempting to solve is how to load an exec and symbol
# file into gdb for a dbx session. So why not just override gdb_file_cmd with the
# right sequence of events, allowing gdb_load to do its normal thing? This way
# remotes and simulators will work, too.
#
proc local_gdb_file_cmd {arg} {
global loadpath
global loadfile
global GDB
global gdb_prompt
global spawn_id
upvar timeout timeout
global last_loaded_file
set last_loaded_file $arg
if [is_remote host] {
set arg [remote_download host $arg]
if { $arg == "" } {
error "download failed"
return -1
}
}
send_gdb "symbol-file $arg\n"
gdb_expect {
-re "Reading symbols from.*$gdb_prompt $" {
verbose "\t\tLoaded $arg into the $GDB"
send_gdb "exec-file $arg\n"
gdb_expect {
-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 ".*$gdb_prompt $" {
verbose "\t\tLoaded $arg with new symbol table into $GDB"
return 0
}
timeout {
perror "(timeout) Couldn't load $arg"
return -1
}
}
return 0
}
-re "has no symbol-table.*$gdb_prompt $" {
perror "$arg wasn't compiled with \"-g\""
return -1
}
-re "Load new symbol table from \".*\".*y or n. $" {
send_gdb "y\n"
exp_continue
}
-re ".*No such file or directory.*$gdb_prompt $" {
perror "($arg) No such file or directory\n"
return -1
}
-re "$gdb_prompt $" {
perror "couldn't load $arg into $GDB."
return -1
}
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
# expect does not seem to have a way to do that.
perror "couldn't load $arg into $GDB (end of file)."
return -1
}
}
}
#
#test_breakpoints
#
proc test_breakpoints { } {
set stop_line [gdb_get_line_number "stop-in-main"]
gdb_test "stop in main" "Breakpoint.*at.*: file.*average\.c, line $stop_line\."
gdb_test "status" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:$stop_line.*"
set stop_line [gdb_get_line_number "stop-at-call"]
gdb_test "stop at average.c:$stop_line" "Breakpoint.*at.*: file.*average\.c, line $stop_line.*"
gdb_test "stop in average.c:$stop_line" "Usage: stop in <function . address>"
gdb_test "stop at main" "Usage: stop at LINE"
}
#
#test_assign
#
proc test_assign { } {
global decimal
global gdb_prompt
gdb_run_cmd
set test "running to main"
gdb_test_multiple "" $test {
-re "Break.* at .*:$decimal.*$gdb_prompt $" {
pass $test
}
-re "Breakpoint \[0-9\]*, \[0-9xa-f\]* in .*$gdb_prompt $" {
pass $test
}
}
send_gdb "assign first=1\n"
gdb_expect {
-re "No symbol \"first\" in current context.*$" { fail "assign first" }
-re "$gdb_prompt $" { pass "assign first" }
timeout { fail "assign first (timeout)" }
}
gdb_test "print first" ".1 = 1"
}
#
#test_whereis
#
proc test_whereis { } {
gdb_test "whereis my_list" "All variables matching regular expression \"my_list\":\r\n\r\nFile.*average\.c:\r\n.*\tstatic int my_list\\\[10\\\];"
}
#
#test_func
#
proc test_func { } {
global decimal
global srcfile2
gdb_test "cont" ".*" "cont 1"
gdb_test "step" ".*"
gdb_test "func sum" "'sum' not within current stack frame\."
set stop_line [gdb_get_line_number "stop-in-sum" $srcfile2]
gdb_test "stop in sum" "Breakpoint.*at.*: file.*sum\.c, line $stop_line\."
gdb_test "cont" ".*" "cont 2"
gdb_test "func print_average" ".*in print_average.*\\(list=.*, low=0, high=6\\).*at.*average\.c:${decimal}\r\n${decimal}\[ \t\]+total = sum\\(list, low, high\\);"
}
# Start with a fresh gdb.
gdb_exit
with_override gdb_file_cmd local_gdb_file_cmd {
save_vars GDBFLAGS {
set GDBFLAGS "$GDBFLAGS --dbx"
gdb_start
dbx_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
test_breakpoints
test_assign
test_whereis
gdb_test "file average.c:1" "1\[ \t\]+/. This is a sample program.*"
test_func
#exit and cleanup
gdb_exit
}
}
return 0