diff options
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/NEWS | 3 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 18 | ||||
-rw-r--r-- | gdb/infcmd.c | 87 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/starti.c | 30 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/starti.exp | 51 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 37 |
9 files changed, 225 insertions, 26 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4779273..4d544f1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2017-09-19 John Baldwin <jhb@FreeBSD.org> + + * NEWS (Changes since GDB 8.0): Add starti. + * infcmd.c (enum run_break): New. + (run_command_1): Queue pending event for RUN_STOP_AT_FIRST_INSN + case. + (run_command): Use enum run_how. + (start_command): Likewise. + (starti_command): New function. + (RUN_ARGS_HELP): New macro. + (_initialize_infcmd): Use RUN_ARGS_HELP for run and start + commands. Add starti command. + 2017-09-19 Yao Qi <yao.qi@linaro.org> * Makefile.in (monitor.o): Remove the rule. @@ -75,6 +75,9 @@ show debug separate-debug-file maint info selftests List the registered selftests. +starti + Start the debugged program stopping at the first instruction. + * TUI Single-Key mode now supports two new shortcut keys: `i' for stepi and `o' for nexti. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index aaec840..971f0c1 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2017-09-19 John Baldwin <jhb@FreeBSD.org> + + * gdb.texinfo (Starting your Program): Add description of + starti command. Mention starti command as an alternative for + debugging the elaboration phase. + 2017-09-16 Simon Marchi <simon.marchi@ericsson.com> * gdb.texinfo (Maintenance Commands): Document filter parameter diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index af5fe6f..d50a1fd 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -2117,10 +2117,20 @@ reused if no argument is provided during subsequent calls to @samp{start} or @samp{run}. It is sometimes necessary to debug the program during elaboration. In -these cases, using the @code{start} command would stop the execution of -your program too late, as the program would have already completed the -elaboration phase. Under these circumstances, insert breakpoints in your -elaboration code before running your program. +these cases, using the @code{start} command would stop the execution +of your program too late, as the program would have already completed +the elaboration phase. Under these circumstances, either insert +breakpoints in your elaboration code before running your program or +use the @code{starti} command. + +@kindex starti +@item starti +@cindex run to first instruction +The @samp{starti} command does the equivalent of setting a temporary +breakpoint at the first instruction of a program's execution and then +invoking the @samp{run} command. For programs containing an +elaboration phase, the @code{starti} command will stop execution at +the start of the elaboration phase. @anchor{set exec-wrapper} @kindex set exec-wrapper diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 25cf025..c38b00a 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -518,12 +518,25 @@ prepare_execution_command (struct target_ops *target, int background) } } -/* Implement the "run" command. If TBREAK_AT_MAIN is set, then insert - a temporary breakpoint at the begining of the main program before - running the program. */ +/* Determine how the new inferior will behave. */ + +enum run_how + { + /* Run program without any explicit stop during startup. */ + RUN_NORMAL, + + /* Stop at the beginning of the program's main function. */ + RUN_STOP_AT_MAIN, + + /* Stop at the first instruction of the program. */ + RUN_STOP_AT_FIRST_INSN + }; + +/* Implement the "run" command. Force a stop during program start if + requested by RUN_HOW. */ static void -run_command_1 (char *args, int from_tty, int tbreak_at_main) +run_command_1 (char *args, int from_tty, enum run_how run_how) { const char *exec_file; struct cleanup *old_chain; @@ -532,6 +545,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) struct target_ops *run_target; int async_exec; struct cleanup *args_chain; + CORE_ADDR pc; dont_repeat (); @@ -569,8 +583,8 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) /* Done. Can now set breakpoints, change inferior args, etc. */ - /* Insert the temporary breakpoint if a location was specified. */ - if (tbreak_at_main) + /* Insert temporary breakpoint in main function if requested. */ + if (run_how == RUN_STOP_AT_MAIN) tbreak_command (main_name (), 0); exec_file = get_exec_file (0); @@ -630,6 +644,15 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) has done its thing; now we are setting up the running program. */ post_create_inferior (¤t_target, 0); + /* Queue a pending event so that the program stops immediately. */ + if (run_how == RUN_STOP_AT_FIRST_INSN) + { + thread_info *thr = inferior_thread (); + thr->suspend.waitstatus_pending_p = 1; + thr->suspend.waitstatus.kind = TARGET_WAITKIND_STOPPED; + thr->suspend.waitstatus.value.sig = GDB_SIGNAL_0; + } + /* Start the target running. Do not use -1 continuation as it would skip breakpoint right at the entry point. */ proceed (regcache_read_pc (get_current_regcache ()), GDB_SIGNAL_0); @@ -642,7 +665,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) static void run_command (char *args, int from_tty) { - run_command_1 (args, from_tty, 0); + run_command_1 (args, from_tty, RUN_NORMAL); } /* Start the execution of the program up until the beginning of the main @@ -658,7 +681,16 @@ start_command (char *args, int from_tty) error (_("No symbol table loaded. Use the \"file\" command.")); /* Run the program until reaching the main procedure... */ - run_command_1 (args, from_tty, 1); + run_command_1 (args, from_tty, RUN_STOP_AT_MAIN); +} + +/* Start the execution of the program stopping at the first + instruction. */ + +static void +starti_command (char *args, int from_tty) +{ + run_command_1 (args, from_tty, RUN_STOP_AT_FIRST_INSN); } static int @@ -3178,6 +3210,22 @@ info_proc_cmd_all (char *args, int from_tty) info_proc_cmd_1 (args, IP_ALL, from_tty); } +/* This help string is used for the run, start, and starti commands. + It is defined as a macro to prevent duplication. */ + +#define RUN_ARGS_HELP \ +"You may specify arguments to give it.\n\ +Args may include \"*\", or \"[...]\"; they are expanded using the\n\ +shell that will start the program (specified by the \"$SHELL\" environment\n\ +variable). Input and output redirection with \">\", \"<\", or \">>\"\n\ +are also allowed.\n\ +\n\ +With no arguments, uses arguments last specified (with \"run\" or \n\ +\"set args\"). To cancel previous arguments and run with no arguments,\n\ +use \"set args\" without arguments.\n\ +\n\ +To start the inferior without using a shell, use \"set startup-with-shell off\"." + void _initialize_infcmd (void) { @@ -3384,24 +3432,19 @@ Specifying -a and an ignore count simultaneously is an error.")); add_com_alias ("fg", "cont", class_run, 1); c = add_com ("run", class_run, run_command, _("\ -Start debugged program. You may specify arguments to give it.\n\ -Args may include \"*\", or \"[...]\"; they are expanded using the\n\ -shell that will start the program (specified by the \"$SHELL\"\ -environment\nvariable). Input and output redirection with \">\",\ -\"<\", or \">>\"\nare also allowed.\n\n\ -With no arguments, uses arguments last specified (with \"run\" \ -or \"set args\").\n\ -To cancel previous arguments and run with no arguments,\n\ -use \"set args\" without arguments.\n\ -To start the inferior without using a shell, use \"set \ -startup-with-shell off\".")); +Start debugged program.\n" +RUN_ARGS_HELP)); set_cmd_completer (c, filename_completer); add_com_alias ("r", "run", class_run, 1); c = add_com ("start", class_run, start_command, _("\ -Run the debugged program until the beginning of the main procedure.\n\ -You may specify arguments to give to your program, just as with the\n\ -\"run\" command.")); +Start the debugged program stopping at the beginning of the main procedure.\n" +RUN_ARGS_HELP)); + set_cmd_completer (c, filename_completer); + + c = add_com ("starti", class_run, starti_command, _("\ +Start the debugged program stopping at the first instruction.\n" +RUN_ARGS_HELP)); set_cmd_completer (c, filename_completer); add_com ("interrupt", class_run, interrupt_command, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 745d2d1..d68072a 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-09-19 John Baldwin <jhb@FreeBSD.org> + + * gdb.base/starti.c: New file. + * gdb.base/starti.exp: New file. + * lib/gdb.exp (gdb_starti_cmd): New procedure. + 2017-09-14 Pedro Alves <palves@redhat.com> * gdb.base/nodebug.exp (nodebug_runto): New procedure. diff --git a/gdb/testsuite/gdb.base/starti.c b/gdb/testsuite/gdb.base/starti.c new file mode 100644 index 0000000..f1f359d --- /dev/null +++ b/gdb/testsuite/gdb.base/starti.c @@ -0,0 +1,30 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2017 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/>. */ + +int x; + +__attribute__((constructor)) void +ctor () +{ + x = 1; +} + +int +main () +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/starti.exp b/gdb/testsuite/gdb.base/starti.exp new file mode 100644 index 0000000..98167ce --- /dev/null +++ b/gdb/testsuite/gdb.base/starti.exp @@ -0,0 +1,51 @@ +# Copyright 2017 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 + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +# Define a stop hook that outputs the value of 'x' + +gdb_test_multiple "define hook-stop" "hook-stop" { + -re "Type commands for definition of \"hook-stop\".\r\nEnd with a line saying just \"end\".\r\n>$" { + gdb_test "print x\nend" "" "hook-stop" + } +} + +if { [gdb_starti_cmd] < 0 } { + untested starti + return -1 +} + +# The program should stop at the first instruction, so the constructor +# should not have run yet and 'x' should be 0. + +gdb_test_sequence "" "starti" { + "Program stopped." + "\\$1 = 0" +} + +# Continue to the start of main(). The constructor should have run so +# 'x' should be 1. + +gdb_breakpoint main +gdb_test_sequence "continue" "" { + "\\$2 = 1" + ".*Breakpoint .*main \\(\\) at .*starti.c.*" +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 8af1b77..48fec2f 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -370,6 +370,43 @@ proc gdb_start_cmd {args} { return -1 } +# Generic starti command. Return 0 if we could start the program, -1 +# if we could not. +# +# N.B. This function does not wait for gdb to return to the prompt, +# that is the caller's responsibility. + +proc gdb_starti_cmd {args} { + global gdb_prompt use_gdb_stub + + foreach command [gdb_init_commands] { + send_gdb "$command\n" + gdb_expect 30 { + -re "$gdb_prompt $" { } + default { + perror "gdb_init_command for target failed" + return -1 + } + } + } + + if $use_gdb_stub { + return -1 + } + + send_gdb "starti $args\n" + gdb_expect 60 { + -re "The program .* has been started already.*y or n. $" { + send_gdb "y\n" + exp_continue + } + -re "Starting program: \[^\r\n\]*" { + return 0 + } + } + return -1 +} + # Set a breakpoint at FUNCTION. If there is an additional argument it is # a list of options; the supported options are allow-pending, temporary, # message, no-message, and passfail. |