diff options
author | Tom Tromey <tromey@adacore.com> | 2022-03-04 11:29:27 -0700 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2022-03-31 13:48:07 -0600 |
commit | 49a82d50c0ee41bf51db6899291a8beaea4e7e2a (patch) | |
tree | cf079ae28dd9a264a8d7d091899735d51676c941 /gdb | |
parent | 0653f01479ecbcbf3c4dfa6083187a5b2c2258c2 (diff) | |
download | gdb-49a82d50c0ee41bf51db6899291a8beaea4e7e2a.zip gdb-49a82d50c0ee41bf51db6899291a8beaea4e7e2a.tar.gz gdb-49a82d50c0ee41bf51db6899291a8beaea4e7e2a.tar.bz2 |
Remove dbx mode
This patch removes gdb's dbx mode. Regression tested on x86-64 Fedora
34.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/NEWS | 2 | ||||
-rw-r--r-- | gdb/breakpoint.c | 99 | ||||
-rw-r--r-- | gdb/cli/cli-cmds.c | 6 | ||||
-rw-r--r-- | gdb/defs.h | 3 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 3 | ||||
-rw-r--r-- | gdb/exec.c | 7 | ||||
-rw-r--r-- | gdb/infrun.c | 42 | ||||
-rw-r--r-- | gdb/main.c | 8 | ||||
-rw-r--r-- | gdb/printcmd.c | 12 | ||||
-rw-r--r-- | gdb/source.c | 3 | ||||
-rw-r--r-- | gdb/stack.c | 23 | ||||
-rw-r--r-- | gdb/symtab.c | 11 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/dbx.exp | 308 |
13 files changed, 24 insertions, 503 deletions
@@ -8,6 +8,8 @@ * Remove support for building against Python 2, it is now only possible to build GDB against Python 3. +* DBX mode has been removed. + * Python API ** New function gdb.format_address(ADDRESS, PROGSPACE, ARCHITECTURE), diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 8275624..1b340bd 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -9296,79 +9296,6 @@ thbreak_command (const char *arg, int 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 with a prewired command list consisting of a single output 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 ("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 = add_info ("breakpoints", info_breakpoints_command, _("\ Status of specified breakpoints (all user-settable breakpoints if no argument).\n\ diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index e12ccee..945fd35 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -2421,8 +2421,7 @@ User-defined commands.\n\ The commands in this class are those defined by the user.\n\ Use the \"define\" command to define a command."), &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."), &cmdlist); add_cmd ("breakpoints", class_breakpoint, @@ -2667,9 +2666,6 @@ can be shown using \"show listsize\".")); 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, _("\ Disassemble a specified section of memory.\n\ Usage: disassemble[/m|/r|/s] START [, END]\n\ @@ -118,9 +118,6 @@ using RequireLongest = gdb::Requires<gdb::Or<std::is_same<T, LONGEST>, #include "hashtab.h" -/* * Enable dbx commands if set. */ -extern int dbx_commands; - /* * System root path, used to find libraries etc. */ extern std::string gdb_sysroot; diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 729f9d7..a4afa75 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -47713,9 +47713,6 @@ Read all symbols from the given symfile on the first access. @item --readnever Do not read symbol files. -@item --dbx -Run in DBX compatibility mode. - @item --return-child-result @value{GDBN}'s exit code will be the same as the child's exit code. @@ -1060,17 +1060,14 @@ _initialize_exec () { 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\ 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\ If FILE cannot be found as specified, your execution directory path\n\ ($PATH) is searched for a command of that name.\n\ 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, _("\ Use FILE as program for getting contents of pure memory.\n\ diff --git a/gdb/infrun.c b/gdb/infrun.c index 12661b5..ca6666c 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -8564,28 +8564,25 @@ normal_stop (void) /* Look up the hook_stop and run it (CLI internally handles problem of stop_command's pre-hook not existing). */ - if (stop_command != NULL) - { - stop_context saved_context; - - try - { - execute_cmd_pre_hook (stop_command); - } - catch (const gdb_exception &ex) - { - exception_fprintf (gdb_stderr, ex, - "Error while running hook_stop:\n"); - } + stop_context saved_context; - /* 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; + 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; /* Notify observers about the stop. This is where the interpreters print the stop event. */ @@ -9489,9 +9486,8 @@ may be interspersed with actions, with the actions being performed for\n\ all signals cumulatively specified.")); set_cmd_completer (c, handle_completer); - if (!dbx_commands) - stop_command = add_cmd ("stop", class_obscure, - not_just_help_class_command, _("\ + stop_command = add_cmd ("stop", class_obscure, + not_just_help_class_command, _("\ 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\ of the program stops."), &cmdlist); @@ -61,9 +61,6 @@ do_setshow_command will free it. */ char *interpreter_p; -/* Whether dbx commands will be handled. */ -int dbx_commands = 0; - /* System root path, used to find libraries etc. */ std::string gdb_sysroot; @@ -766,7 +763,6 @@ captured_main_1 (struct captured_main_args *context) static struct option long_options[] = { {"tui", no_argument, 0, OPT_TUI}, - {"dbx", no_argument, &dbx_commands, 1}, {"readnow", no_argument, NULL, OPT_READNOW}, {"readnever", no_argument, NULL, OPT_READNEVER}, {"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); /* Try to set up an alternate signal stack for SIGSEGV handlers. */ @@ -1437,7 +1430,6 @@ Output and user interface control:\n\n\ "), stream); #endif gdb_puts (_("\ - --dbx DBX compatibility mode.\n\ -q, --quiet, --silent\n\ Do not print version number on startup.\n\n\ "), stream); diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 3930d08..3c78edf 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -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\ You can see these environment settings with the \"show\" command."), &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. */ c = add_com ("call", class_vars, call_command, _("\ diff --git a/gdb/source.c b/gdb/source.c index 954f479..020e94d 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -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."), &cmdlist); - if (dbx_commands) - add_com_alias ("use", directory_cmd, class_files, 0); - set_cmd_completer (directory_cmd, filename_completer); add_setshow_optional_filename_cmd ("directories", diff --git a/gdb/stack.c b/gdb/stack.c index 3a6a01b..1ccad83 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -2903,24 +2903,6 @@ find_frame_for_function (const char *function_name) 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 this in sync with the "thread apply" commands. */ @@ -3560,11 +3542,6 @@ Prints the argument variables of the current stack frame.\n"), false)); 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 "set print raw-frame-arguments". */ set_show_commands set_show_frame_args diff --git a/gdb/symtab.c b/gdb/symtab.c index 804b882..b3b7489 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -6932,17 +6932,6 @@ Prints the global and static variables.\n"), _("global and static variables"), true)); 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, info_print_args_help (_("\ diff --git a/gdb/testsuite/gdb.base/dbx.exp b/gdb/testsuite/gdb.base/dbx.exp deleted file mode 100644 index a6f975c..0000000 --- a/gdb/testsuite/gdb.base/dbx.exp +++ /dev/null @@ -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 |