Implement *running.
authorVladimir Prus <vladimir@codesourcery.com>
Tue, 10 Jun 2008 10:23:54 +0000 (10:23 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Tue, 10 Jun 2008 10:23:54 +0000 (10:23 +0000)
        * Makefile.in: Update dependencies.
        * gdbthread.h (struct thread_info): New field
        running_.
        (set_running, is_running): New.
        * thread.c (set_running, is_running): New.
        * inferior.h (suppress_normal_stop_observer): Rename to...
        (suppress_run_stop_observers): ..this.
        * infcmd.c (suppress_normal_stop_observer): Rename to...
        (suppress_run_stop_observers): ..this.
        (finish_command_continuation, finish_command): Adjust.
        * infcall.c (call_function_by_hand): Adjust.
        * infrun.c (normal_stop): Call set_running.
        * target.c (target_resume): New.  Call set_running.
        * target.h (target_resume): Convert from macro to
        a function.

        * mi/mi-interp.c (mi_on_resume): New.
        (mi_interpreter_init): Register mi_on_resume.

20 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/doc/observer.texi
gdb/gdbthread.h
gdb/infcall.c
gdb/infcmd.c
gdb/inferior.h
gdb/infrun.c
gdb/mi/mi-interp.c
gdb/target.c
gdb/target.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.mi/mi-console.exp
gdb/testsuite/gdb.mi/mi-syn-frame.exp
gdb/testsuite/gdb.mi/mi2-console.exp
gdb/testsuite/gdb.mi/mi2-syn-frame.exp
gdb/testsuite/lib/mi-support.exp
gdb/thread.c

index f18c6c98c3323a44e66156264433090447c93e45..d3ba89ab8adc21cc845c1da9c63676d067ca5109 100644 (file)
@@ -1,3 +1,25 @@
+2008-06-10  Vladimir Prus  <vladimir@codesourcery.com>
+
+       Implement *running.
+        * Makefile.in: Update dependencies.
+        * gdbthread.h (struct thread_info): New field
+        running_.
+        (set_running, is_running): New.
+        * thread.c (set_running, is_running): New.
+        * inferior.h (suppress_normal_stop_observer): Rename to...
+        (suppress_run_stop_observers): ..this.
+        * infcmd.c (suppress_normal_stop_observer): Rename to...
+        (suppress_run_stop_observers): ..this.
+        (finish_command_continuation, finish_command): Adjust.
+        * infcall.c (call_function_by_hand): Adjust.
+        * infrun.c (normal_stop): Call set_running.
+        * target.c (target_resume): New.  Call set_running.
+        * target.h (target_resume): Convert from macro to
+        a function.
+
+        * mi/mi-interp.c (mi_on_resume): New.
+        (mi_interpreter_init): Register mi_on_resume.
+
 2008-06-10  Vladimir Prus  <vladimir@codesourcery.com>
 
        Use observers to report stop events in MI.
index c14dc1ab4accbe8d2fccfadee6f8c5e2bb063dbd..81480f9dd81e7a53f807aa75e8fe45527abe3a7b 100644 (file)
@@ -2923,7 +2923,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
        $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
        $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
-       $(exceptions_h) $(target_descriptions_h) $(gdb_stdint_h)
+       $(exceptions_h) $(target_descriptions_h) $(gdb_stdint_h) $(gdbthread_h)
 target-descriptions.o: target-descriptions.c $(defs_h) $(arch_utils_h) \
        $(target_h) $(target_descriptions_h) $(vec_h) $(xml_tdesc_h) \
        $(gdbcmd_h) $(gdb_assert_h) $(gdbtypes_h) $(reggroups_h) \
index c24925392bc0918d98392e49ccc2a0d898c9850d..d2d5349ae69668901d86e5fc0755aa54b8503bc2 100644 (file)
@@ -1,3 +1,8 @@
+2008-06-10  Vladimir Prus  <vladimir@codesourcery.com>
+
+       * observer.texi (target_resumed): New observer.
+        * gdb.texinfo (GDB/MI Output Records): Document *running.
+
 2008-06-06  Tom Tromey  <tromey@redhat.com>
 
        * gdb.texinfo (Completion): Add field name example.
index 5cef05b5efb9b9e75757a3de84621ac4e33ecfe9..df1f1a26372db88176933164b084de1ee560bed7 100644 (file)
@@ -18335,6 +18335,17 @@ The following is the list of possible async records:
 
 @table @code
 
+@item *running,thread-id="@var{thread}"
+The target is now running.  The @var{thread} field tells which
+specific thread is now running, and can be @samp{all} if all threads
+are running.  The frontend should assume that no interaction with a 
+running thread is possible after this notification is produced.
+The frontend should not assume that this notification is output
+only once for any command.  @value{GDBN} may emit this notification 
+several times, either for different threads, because it cannot resume
+all threads together, or even for a single thread, if the thread must
+be stepped though some code before letting it run freely.
+
 @item *stopped,reason="@var{reason}"
 The target has stopped.  The @var{reason} field can have one of the
 following values:
index af3835bafb2ecc040608eba7b7153f55caec9e67..7d4d808b25eb30435f3f5e0db2553f9d8b4cdc9a 100644 (file)
@@ -137,3 +137,8 @@ The thread specified by @var{t} has been created.
 The thread specified by @var{t} has exited.
 @end deftypefun
 
+@deftypefun void target_resumed (ptid_t @var{ptid})
+The target was resumed.  The @var{ptid} parameter specifies which
+thread was resume, and may be RESUME_ALL if all threads are resumed.
+@end deftypefun
+
index 5f9e98523f97c7f50a16d440c1a298f99c5ca378..4440417674dbd4177307aa4ec2ba30a8ef05c4ec 100644 (file)
@@ -63,6 +63,10 @@ struct thread_info
      when we finally do stop stepping.  */
   bpstat stepping_through_solib_catchpoints;
 
+  /* This field is internal for thread.c.  Never access it directly,
+     use is_running instead.  */
+  int running_;
+
   /* Private data used by the target vector implementation.  */
   struct private_thread_info *private;
 };
@@ -146,6 +150,13 @@ extern void load_infrun_state (ptid_t ptid,
 /* Switch from one thread to another.  */
 extern void switch_to_thread (ptid_t ptid);
 
+/* Marks thread PTID is running, or stopped. 
+   If PIDGET (PTID) is -1, marks all threads.  */
+extern void set_running (ptid_t ptid, int running);
+
+/* Reports if thread PTID is know to be running right now.  */
+extern int is_running (ptid_t ptid);
+
 /* Commands with a prefix of `thread'.  */
 extern struct cmd_list_element *thread_cmd_list;
 
index ded3211ac2f37ae9e27b6851824eef0f1a6101b1..33a098ff59ee571785798066e7fe3612d5f52830 100644 (file)
@@ -721,8 +721,8 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
       saved_async = target_async_mask (0);
 
     old_cleanups2 = make_cleanup_restore_integer 
-      (&suppress_normal_stop_observer);
-    suppress_normal_stop_observer = 1;
+      (&suppress_run_stop_observers);
+    suppress_run_stop_observers = 1;
     proceed (real_pc, TARGET_SIGNAL_0, 0);
     do_cleanups (old_cleanups2);
     
index 01e1ebea6699432bf065f55676758e9764c6479f..a4f40a5d6fc3a7532ab9327a66da509a26a429fc 100644 (file)
@@ -207,8 +207,9 @@ int step_multi;
 
 struct gdb_environ *inferior_environ;
 
-/* When set, normal_stop will not call the normal_stop observer.  */
-int suppress_normal_stop_observer = 0;
+/* When set, normal_stop will not call the normal_stop observer.
+   Resume observer likewise will not be called.  */
+int suppress_run_stop_observers = 0;
 \f
 /* Accessor routines. */
 
@@ -1303,7 +1304,7 @@ finish_command_continuation (struct continuation_arg *arg, int error_p)
       observer_notify_normal_stop (stop_bpstat);
     }
 
-  suppress_normal_stop_observer = 0;
+  suppress_run_stop_observers = 0;
   delete_breakpoint (breakpoint);
 }
 
@@ -1370,8 +1371,8 @@ finish_command (char *arg, int from_tty)
     }
 
   proceed_to_finish = 1;       /* We want stop_registers, please...  */
-  make_cleanup_restore_integer (&suppress_normal_stop_observer);
-  suppress_normal_stop_observer = 1;
+  make_cleanup_restore_integer (&suppress_run_stop_observers);
+  suppress_run_stop_observers = 1;
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
 
   arg1 =
index 7f85507a0c191a214dd8a6178f662312119cc663..1042a447fea532efe6897399fabcf94ed27aa48a 100644 (file)
@@ -393,7 +393,7 @@ void displaced_step_dump_bytes (struct ui_file *file,
 
 
 /* When set, normal_stop will not call the normal_stop observer.  */
-extern int suppress_normal_stop_observer;
+extern int suppress_run_stop_observers;
 \f
 /* Possible values for gdbarch_call_dummy_location.  */
 #define ON_STACK 1
index 1e10ecc701a03fa2562f4c9e272f01d31edd4c11..cfc3d9bb507262ed8440f8e5b75655ccfdae3c77 100644 (file)
@@ -3772,11 +3772,12 @@ Further execution is probably impossible.\n"));
 
 done:
   annotate_stopped ();
-  if (!suppress_normal_stop_observer && !step_multi)
+  if (!suppress_run_stop_observers && !step_multi)
     observer_notify_normal_stop (stop_bpstat);
   /* Delete the breakpoint we stopped at, if it wants to be deleted.
      Delete any breakpoint that is to be deleted at the next stop.  */
   breakpoint_auto_delete (stop_bpstat);
+  set_running (pid_to_ptid (-1), 0);
 }
 
 static int
index 583c288a76d5e26a159a2c4ad4bf62cbc0b22d9b..5719c56d32819895cb2358dad57adb5d10bbd96b 100644 (file)
@@ -69,6 +69,7 @@ static void mi_on_normal_stop (struct bpstats *bs);
 
 static void mi_new_thread (struct thread_info *t);
 static void mi_thread_exit (struct thread_info *t);
+static void mi_on_resume (ptid_t ptid);
 
 static void *
 mi_interpreter_init (int top_level)
@@ -94,6 +95,7 @@ mi_interpreter_init (int top_level)
       observer_attach_new_thread (mi_new_thread);
       observer_attach_thread_exit (mi_thread_exit);
       observer_attach_normal_stop (mi_on_normal_stop);
+      observer_attach_target_resumed (mi_on_resume);
     }
 
   return mi;
@@ -327,6 +329,19 @@ mi_on_normal_stop (struct bpstats *bs)
   gdb_flush (raw_stdout);
 }
 
+static void
+mi_on_resume (ptid_t ptid)
+{
+  if (PIDGET (ptid) == -1)
+    fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
+  else
+    {
+      struct thread_info *ti = find_thread_pid (ptid);
+      gdb_assert (ti);
+      fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num);
+    }
+}
+
 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
 
 void
index be7f3a11e229ee33fde5227de9f3e7f9a50b31bd..6b009a8e76cfb1322a9a0c28b44d2aee394dbfb7 100644 (file)
@@ -40,6 +40,7 @@
 #include "exceptions.h"
 #include "target-descriptions.h"
 #include "gdb_stdint.h"
+#include "gdbthread.h"
 
 static void target_info (char *, int);
 
@@ -1715,6 +1716,14 @@ target_disconnect (char *args, int from_tty)
   tcomplain ();
 }
 
+void
+target_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+  dcache_invalidate (target_dcache);
+  (*current_target.to_resume) (ptid, step, signal);
+  set_running (ptid, 1);
+
+}
 /* Look through the list of possible targets for a target that can
    follow forks.  */
 
index f1e414750edc67ff178e2f21b500ea812d258961..902d4283de59143cb15405f9d1f263dfd6e2b889 100644 (file)
@@ -586,11 +586,7 @@ extern void target_disconnect (char *, int);
    the target, or TARGET_SIGNAL_0 for no signal.  The caller may not
    pass TARGET_SIGNAL_DEFAULT.  */
 
-#define        target_resume(ptid, step, siggnal)                              \
-  do {                                                                 \
-    dcache_invalidate(target_dcache);                                  \
-    (*current_target.to_resume) (ptid, step, siggnal);                 \
-  } while (0)
+extern void target_resume (ptid_t ptid, int step, enum target_signal signal);
 
 /* Wait for process pid to do something.  PTID = -1 to wait for any
    pid to do something.  Return pid of child, or -1 in case of error;
index d994d1fbc435e64221ff019e4abb79ae75836530..13c5d31e8a13abf15d955dd4a2346c7c0a76dee9 100644 (file)
@@ -1,3 +1,12 @@
+2008-06-10  Vladimir Prus  <vladimir@codesourcery.com>
+
+        * gdb.mi/mi-console.exp: Adjust.
+        * gdb.mi/mi-syn-frame.exp: Adjust.
+        * gdb.mi/mi2-console.exp: Adjust.
+        * gdb.mi/mi2-syn-frame.exp: Adjust.
+        * lib/mi-support.exp (mi_run_cmd): Adjust.
+        (mi_send_resuming_command): Adjust.
+
 2008-06-10  Vladimir Prus  <vladimir@codesourcery.com>
 
        * gdb.mi/mi-break.exp (test_ignore_count): Adjust stopped pattern.
index 7d093dc42965b2ebd8254efa6863d69d6d943784..70d9342c74d4cc5b76802054e73eeb5e02208570 100644 (file)
@@ -52,7 +52,7 @@ mi_run_to_main
 
 # Next over the hello() call which will produce lots of output
 mi_gdb_test "220-exec-next" \
-           "220\\^running" \
+           "220\\^running(\r\n\\*running,thread-id=\"all\")?" \
            "Testing console output" \
            "Hello \\\\\"!\[\r\n\]+"
 
index 208678bb83b96481e3d2888843f3b34b6b6c50f6..59b8e440a30ab2c4c84372bbe2cf26acdd2e4fd8 100644 (file)
@@ -46,7 +46,7 @@ mi_create_breakpoint "foo" 2 keep foo ".*mi-syn-frame.c" $decimal $hex \
 # Call foo() by hand, where we'll hit a breakpoint.
 #
 
-mi_gdb_test "401-data-evaluate-expression foo()" "401\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" "call inferior's function with a breakpoint set in it"
+mi_gdb_test "401-data-evaluate-expression foo()" ".*401\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" "call inferior's function with a breakpoint set in it"
 
 
 mi_gdb_test "402-stack-list-frames" "402\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"foo\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\}.*\\\]" "backtrace from inferior function stopped at bp, showing gdb dummy frame"
@@ -54,9 +54,7 @@ mi_gdb_test "402-stack-list-frames" "402\\^done,stack=\\\[frame=\{level=\"0\",ad
 #
 # Continue back to main()
 #
-mi_gdb_test "403-exec-continue" \
-  "403\\^running" \
-  "testing exec continue"
+mi_send_resuming_command "exec-continue" "testing exec continue"
 
 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
 
@@ -73,7 +71,7 @@ mi_create_breakpoint "subroutine" 3 keep subroutine ".*mi-syn-frame.c" $decimal
     "insert breakpoint subroutine"
 
 mi_gdb_test "406-data-evaluate-expression have_a_very_merry_interrupt()" \
-  "406\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" \
+  ".*406\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" \
   "data evaluate expression"
 
 # We should have both a signal handler and a call dummy frame
@@ -84,7 +82,7 @@ mi_gdb_test "407-stack-list-frames" \
   "list stack frames"
 
 
-mi_gdb_test "408-exec-continue" "408\\^running"
+mi_send_resuming_command "exec-continue" "testing exec continue"
 
 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
 
@@ -97,7 +95,7 @@ mi_gdb_test "409-stack-list-frames 0 0" \
 # 
 
 mi_gdb_test "410-data-evaluate-expression bar()" \
-  "410\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB remains in the frame where the signal was received.\\\\nTo change this behavior use \\\\\"set unwindonsignal on\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\"" \
+  ".*410\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB remains in the frame where the signal was received.\\\\nTo change this behavior use \\\\\"set unwindonsignal on\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\"" \
   "call inferior function which raises exception"
 
 mi_gdb_test "411-stack-list-frames" "411\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"bar\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"},frame=\{level=\"1\",addr=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"}.*\\\]" "backtrace from inferior function at exception"
index 88b4fdd3795ff58b2cf433251add82c63d5ce3f5..c5f6f817113ee5328b88fdadd5df14b6d9523aca 100644 (file)
@@ -53,7 +53,7 @@ mi_run_to_main
 # Next over the hello() call which will produce lots of output
 send_gdb "220-exec-next\n"
 gdb_expect {
-    -re "220\\^running\r\n$mi_gdb_prompt" {
+    -re "220\\^running\r\n(\\*running,thread-id=\"all\"\r\n)?$mi_gdb_prompt" {
        pass "Started step over hello"
     }
     timeout {
index b69812fb78fe7467f669eec86227fcf84695b8c4..948e98dc90f2d555c1e403b8d8e3c77d1a617078 100644 (file)
@@ -48,7 +48,7 @@ mi_create_breakpoint "foo" 2 keep foo ".*mi-syn-frame.c" $decimal $hex \
 # Call foo() by hand, where we'll hit a breakpoint.
 #
 
-mi_gdb_test "401-data-evaluate-expression foo()" "401\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" "call inferior's function with a breakpoint set in it"
+mi_gdb_test "401-data-evaluate-expression foo()" ".*401\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" "call inferior's function with a breakpoint set in it"
 
 mi_gdb_test "402-stack-list-frames" "402\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"foo\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\}.*\\\]" "backtrace from inferior function stopped at bp, showing gdb dummy frame"
 
@@ -56,9 +56,7 @@ mi_gdb_test "402-stack-list-frames" "402\\^done,stack=\\\[frame=\{level=\"0\",ad
 # Continue back to main()
 #
 
-mi_gdb_test "403-exec-continue" \
-  "403\\^running" \
-  "testing exec continue"
+mi_send_resuming_command "exec-continue" "testing exec continue"
 
 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
 
@@ -75,7 +73,7 @@ mi_create_breakpoint "subroutine" 3 keep subroutine ".*mi-syn-frame.c" $decimal
     "insert breakpoint subroutine"
 
 mi_gdb_test "406-data-evaluate-expression have_a_very_merry_interrupt()" \
-  "406\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" \
+  ".*406\\^error,msg=\"The program being debugged stopped while in a function called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt\\) is done executing, GDB will silently\\\\nstop \\(instead of continuing to evaluate the expression containing\\\\nthe function call\\).\"" \
   "evaluate expression have_a_very_merry_interrupt"
 
 # We should have both a signal handler and a call dummy frame
@@ -85,7 +83,7 @@ mi_gdb_test "407-stack-list-frames" \
   "407\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"subroutine\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"handler\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"<signal handler called>\"\},.*frame=\{level=\"$decimal\",addr=\"$hex\",func=\"have_a_very_merry_interrupt\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\},frame=\{level=\"$decimal\",addr=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"$decimal\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",line=\"$decimal\"\}.*\\\]" \
   "list stack frames"
 
-mi_gdb_test "408-exec-continue" "408\\^running"
+mi_send_resuming_command "exec-continue" "testing exec continue"
 
 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
 
@@ -97,7 +95,7 @@ mi_gdb_test "409-stack-list-frames 0 0" \
 # Call bar() by hand, which should get an exception while running.
 # 
 
-mi_gdb_test "410-data-evaluate-expression bar()" "410\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB remains in the frame where the signal was received.\\\\nTo change this behavior use \\\\\"set unwindonsignal on\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\"" "call inferior function which raises exception"
+mi_gdb_test "410-data-evaluate-expression bar()" ".*410\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB remains in the frame where the signal was received.\\\\nTo change this behavior use \\\\\"set unwindonsignal on\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\"" "call inferior function which raises exception"
 
 mi_gdb_test "411-stack-list-frames" "411\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"bar\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"},frame=\{level=\"1\",addr=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"}.*\\\]" "backtrace from inferior function at exception"
 
index 23f3f078a78b2e263583a65069720e9a78dd0081..7a821b8920b028bdc218dc8cac562735d61dd3f9 100644 (file)
@@ -802,7 +802,7 @@ proc mi_run_cmd {args} {
        if [target_info exists gdb,do_reload_on_run] {
            send_gdb "220-exec-continue\n";
            gdb_expect 60 {
-               -re "220\\^running\[\r\n\]+$mi_gdb_prompt$" {}
+               -re "220\\^running\[\r\n\]+(\\*running,thread-id=\"\[^\"\]+\"\r\n)?$mi_gdb_prompt$" {}
                default {}
            }
            return;
@@ -823,7 +823,7 @@ proc mi_run_cmd {args} {
 
     send_gdb "220-exec-run $args\n"
     gdb_expect {
-       -re "220\\^running\r\n(=thread-created,id=\"1\"\r\n)?${mi_gdb_prompt}" {
+       -re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*${mi_gdb_prompt}" {
        }
        timeout {
            perror "Unable to start target"
@@ -1399,7 +1399,7 @@ proc mi_send_resuming_command {command test} {
 
     send_gdb "220-$command\n"
     gdb_expect {
-        -re "220\\^running\r\n${mi_gdb_prompt}" {
+        -re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n)?${mi_gdb_prompt}" {
         }
         -re ".*${mi_gdb_prompt}" {
             fail "$test (failed to resume)"
index 446a55ece0309c8cebc3651921e9314a59953fb3..64d41eb0541d3ba3e60ed3b1e31cbb29afbfbea5 100644 (file)
@@ -414,6 +414,67 @@ prune_threads (void)
     }
 }
 
+static int main_thread_running = 0;
+
+void
+set_running (ptid_t ptid, int running)
+{
+  struct thread_info *tp;
+
+  if (!thread_list)
+    {
+      /* This is one of the targets that does not add main
+        thread to the thread list.  Just use a single
+        global flag to indicate that a thread is running.  
+
+        This problem is unique to ST programs.  For MT programs,
+        the main thread is always present in the thread list.  If it's
+        not, the first call to context_switch will mess up GDB internal
+        state.  */
+      if (running && !main_thread_running && !suppress_run_stop_observers)
+       observer_notify_target_resumed (ptid);
+      main_thread_running = running;
+      return;
+    }
+
+  /* We try not to notify the observer if no thread has actually changed 
+     the running state -- merely to reduce the number of messages to 
+     frontend.  Frontend is supposed to handle multiple *running just fine.  */
+  if (PIDGET (ptid) == -1)
+    {
+      int any_started = 0;
+      for (tp = thread_list; tp; tp = tp->next)
+       {
+         if (running && !tp->running_)
+           any_started = 1;
+         tp->running_ = running;
+       }
+      if (any_started && !suppress_run_stop_observers)
+       observer_notify_target_resumed (ptid);      
+    }
+  else
+    {
+      tp = find_thread_pid (ptid);
+      gdb_assert (tp);
+      if (running && !tp->running_ && !suppress_run_stop_observers)
+       observer_notify_target_resumed (ptid);
+      tp->running_ = running;
+    }  
+}
+
+int
+is_running (ptid_t ptid)
+{
+  struct thread_info *tp;
+
+  if (!thread_list)
+    return main_thread_running;
+
+  tp = find_thread_pid (ptid);
+  gdb_assert (tp);
+  return tp->running_;  
+}
+
 /* Prints the list of threads and their details on UIOUT.
    This is a version of 'info_thread_command' suitable for
    use from MI.