[rfc] Stop unlikely "run"'s earlier

Daniel Jacobowitz
2007-11-07T21:18:41Z

When you connect to a remote target using "target remote", it's
already running. A common mistake at this point is to say "run"
instead of "continue". If you do, GDB first asks you to kill the
currently running program, and then depending on its configuration
does one of two things. A cross debugger will say "Don't know how to
run". A native debugger will run the program... natively, not on
the remote target you were previously connected to!

I don't think this behavior is useful. "run" should select a native
target when the current target is an executable or core file, but
not when it's connected to some other target. This patch changes
the behavior to:

(gdb) run
The "remote" target can not run programs. Try "help target" or "continue".

Any comments? Shall I commit this?

--
Daniel Jacobowitz
CodeSourcery

2007-11-07 Daniel Jacobowitz <dan@codesourcery.com>

* infcmd.c (kill_if_already_running): Make static. Use
target_require_runnable.
* target.c (target_require_runnable): New.
* target.h (target_require_runnable): Declare.

Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.162
diff -u -p -r1.162 infcmd.c
--- infcmd.c 25 Oct 2007 11:30:55 -0000 1.162
+++ infcmd.c 7 Nov 2007 21:09:45 -0000
@@ -444,11 +444,15 @@ post_create_inferior (struct target_ops
from the beginning. Ask the user to confirm that he wants to restart
the program being debugged when FROM_TTY is non-null. */

-void
+static void
kill_if_already_running (int from_tty)
{
if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
{
+ /* Bail out before killing the program if we will not be able to
+ restart it. */
+ target_require_runnable ();
+
if (from_tty
&& !query ("The program being debugged has been started already.\n\
Start it from the beginning? "))
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.149
diff -u -p -r1.149 target.c
--- target.c 22 Oct 2007 14:03:37 -0000 1.149
+++ target.c 7 Nov 2007 21:09:46 -0000
@@ -1730,6 +1730,41 @@ target_read_description (struct target_o
return NULL;
}

+/* Look through the currently pushed targets. If none of them will
+ be able to restart the currently running process, issue an error
+ message. */
+
+void
+target_require_runnable (void)
+{
+ struct target_ops *t;
+
+ for (t = target_stack; t != NULL; t = t->beneath)
+ {
+ /* If this target knows how to create a new program, then
+ assume we will still be able to after killing the current
+ one. Either killing and mourning will not pop T, or else
+ find_default_run_target will find it again. */
+ if (t->to_create_inferior != NULL)
+ return;
+
+ /* Do not worry about thread_stratum targets that can not
+ create inferiors. Assume they will be pushed again if
+ necessary, and continue to the process_stratum. */
+ if (t->to_stratum == thread_stratum)
+ continue;
+
+ error (_("\
+The \"%s\" target can not run programs. Try \"help target\" or \"continue\"."),
+ t->to_shortname);
+ }
+
+ /* This function is only called if the target is running. In that
+ case there should have been a process_stratum target and it
+ should either know how to create inferiors, or not... */
+ internal_error (__FILE__, __LINE__, "No targets found");
+}
+
/* Look through the list of possible targets for a target that can
execute a run or attach command without any other data. This is
used to locate the default process stratum.
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.104
diff -u -p -r1.104 target.h
--- target.h 23 Aug 2007 18:08:46 -0000 1.104
+++ target.h 7 Nov 2007 21:09:46 -0000
@@ -1203,6 +1203,8 @@ extern void initialize_targets (void);

extern void noprocess (void);

+extern void target_require_runnable (void);
+
extern void find_default_attach (char *, int);

extern void find_default_create_inferior (char *, char *, char **, int);