* [RFA] Implement *running.
@ 2008-05-01 13:36 Vladimir Prus
2008-05-02 9:57 ` Eli Zaretskii
2008-05-02 15:59 ` Daniel Jacobowitz
0 siblings, 2 replies; 10+ messages in thread
From: Vladimir Prus @ 2008-05-01 13:36 UTC (permalink / raw)
To: gdb-patches
As previously discussed, we need a new async notification for MI --
"*running", that is output whenever any thread, or entire program is
resumed. We have "^running" but this one is a response to a command,
and therefore can be emitted only once.
This patch introduces new observer, makes that observer called, and
make MI connect to that observer. In the case of MT programs, or
targets where main thread is always added to the thread table, we
just use a flag inside thread_info. For the case of target where main
thread of ST program is not added to the table, we just use the global
flag. (I could not test on any such target).
This has no regressions in default and async modes on x86. OK?
- Volodya
* Makefile.in: Update dependencies.
* doc/observer.texi (target_resumed): New observer.
* 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.
[testsuite]
* gdb.mi/mi-break.exp: Adjust.
* 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.
---
gdb/Makefile.in | 2 +-
gdb/doc/observer.texi | 4 ++
gdb/gdbthread.h | 11 ++++++
gdb/infcall.c | 2 +-
gdb/infcmd.c | 9 +++--
gdb/inferior.h | 2 +-
gdb/infrun.c | 3 +-
gdb/mi/mi-interp.c | 15 ++++++++
gdb/target.c | 9 +++++
gdb/target.h | 6 +---
gdb/testsuite/gdb.mi/mi-break.exp | 4 +-
gdb/testsuite/gdb.mi/mi-console.exp | 2 +-
gdb/testsuite/gdb.mi/mi-syn-frame.exp | 12 +++----
gdb/testsuite/gdb.mi/mi2-console.exp | 2 +-
gdb/testsuite/gdb.mi/mi2-syn-frame.exp | 12 +++----
gdb/testsuite/lib/mi-support.exp | 6 ++--
gdb/thread.c | 61 ++++++++++++++++++++++++++++++++
17 files changed, 128 insertions(+), 34 deletions(-)
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 5ab8caa..124e94c 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2904,7 +2904,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) \
diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
index af3835b..b83d642 100644
--- a/gdb/doc/observer.texi
+++ b/gdb/doc/observer.texi
@@ -135,5 +135,9 @@ The thread specified by @var{t} has been created.
@deftypefun void thread_exit (struct thread_info *@var{t})
The thread specified by @var{t} has exited.
+
+@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
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 56cbd51..8e0da6f 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -69,6 +69,10 @@ struct thread_info
int proceed_to_finish;
+ /* 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;
};
@@ -162,6 +166,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;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index d8257da..28408ec 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -721,7 +721,7 @@ 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, 1);
+ (&suppress_run_stop_observers, 1);
proceed (real_pc, TARGET_SIGNAL_0, 0);
do_cleanups (old_cleanups2);
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 37ca2bb..b672b6a 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -206,8 +206,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. */
@@ -1288,7 +1289,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);
}
@@ -1355,7 +1356,7 @@ finish_command (char *arg, int from_tty)
}
proceed_to_finish = 1; /* We want stop_registers, please... */
- make_cleanup_restore_integer (&suppress_normal_stop_observer, 1);
+ make_cleanup_restore_integer (&suppress_run_stop_observers, 1);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
arg1 =
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 630cc52..8958aef 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -401,7 +401,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
diff --git a/gdb/infrun.c b/gdb/infrun.c
index e153cba..170ee81 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3631,11 +3631,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
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index a9a5ffc..4ba1ce1 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -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;
@@ -317,6 +319,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
diff --git a/gdb/target.c b/gdb/target.c
index 944d601..162196f 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -40,6 +40,7 @@
#include "exceptions.h"
#include "target-descriptions.h"
#include "gdb_stdint.h"
+#include "gdbthread.h"
static void target_info (char *, int);
@@ -1705,6 +1706,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. */
diff --git a/gdb/target.h b/gdb/target.h
index e0341e1..ffabb0e 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -567,11 +567,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;
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 48527fd..b895020 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -174,11 +174,11 @@ proc test_error {} {
# containing function call, the internal breakpoint created to handle
# function call would be reported, messing up MI output.
mi_gdb_test "-var-create V * return_1()" \
- "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
+ ".*\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
"create varobj for function call"
mi_gdb_test "-var-update *" \
- "\\^done,changelist=\\\[\\\]" \
+ ".*\\^done,changelist=\\\[\\\]" \
"update varobj for function call"
}
diff --git a/gdb/testsuite/gdb.mi/mi-console.exp b/gdb/testsuite/gdb.mi/mi-console.exp
index 7d093dc..70d9342 100644
--- a/gdb/testsuite/gdb.mi/mi-console.exp
+++ b/gdb/testsuite/gdb.mi/mi-console.exp
@@ -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\]+"
diff --git a/gdb/testsuite/gdb.mi/mi-syn-frame.exp b/gdb/testsuite/gdb.mi/mi-syn-frame.exp
index 208678b..59b8e44 100644
--- a/gdb/testsuite/gdb.mi/mi-syn-frame.exp
+++ b/gdb/testsuite/gdb.mi/mi-syn-frame.exp
@@ -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"
diff --git a/gdb/testsuite/gdb.mi/mi2-console.exp b/gdb/testsuite/gdb.mi/mi2-console.exp
index 88b4fdd..c5f6f81 100644
--- a/gdb/testsuite/gdb.mi/mi2-console.exp
+++ b/gdb/testsuite/gdb.mi/mi2-console.exp
@@ -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 {
diff --git a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
index b69812f..948e98d 100644
--- a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
+++ b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
@@ -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"
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 0783936..b373bd5 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -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${mi_gdb_prompt}" {
+ -re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\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)"
diff --git a/gdb/thread.c b/gdb/thread.c
index bba32e8..47a573c 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -437,6 +437,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. */
+ main_thread_running = running;
+ return;
+ }
+
+ /* We try not to notify the observer is not
+ 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.
--
1.5.3.5
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [RFA] Implement *running.
2008-05-01 13:36 [RFA] Implement *running Vladimir Prus
@ 2008-05-02 9:57 ` Eli Zaretskii
2008-05-02 15:59 ` Daniel Jacobowitz
1 sibling, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2008-05-02 9:57 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <vladimir@codesourcery.com>
> Date: Thu, 1 May 2008 16:35:52 +0300
>
>
> As previously discussed, we need a new async notification for MI --
> "*running", that is output whenever any thread, or entire program is
> resumed. We have "^running" but this one is a response to a command,
> and therefore can be emitted only once.
>
> This patch introduces new observer, makes that observer called, and
> make MI connect to that observer. In the case of MT programs, or
> targets where main thread is always added to the thread table, we
> just use a flag inside thread_info. For the case of target where main
> thread of ST program is not added to the table, we just use the global
> flag. (I could not test on any such target).
>
> This has no regressions in default and async modes on x86. OK?
Do we need to document it?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Implement *running.
2008-05-01 13:36 [RFA] Implement *running Vladimir Prus
2008-05-02 9:57 ` Eli Zaretskii
@ 2008-05-02 15:59 ` Daniel Jacobowitz
2008-05-04 16:33 ` Vladimir Prus
1 sibling, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2008-05-02 15:59 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
On Thu, May 01, 2008 at 04:35:52PM +0300, Vladimir Prus wrote:
> This has no regressions in default and async modes on x86. OK?
Just minor concerns. Docs - yes, I know very well that you know this
- but making sure we see docs before the code change goes in makes
sure that no one forgets in the crush of other patches. So, sorry,
but expect to keep getting this reply :-)
Also, what are the expected changes in async and non-async? Will we
start generating this for non-async and is that likely to break any
frontend?
> * doc/observer.texi (target_resumed): New observer.
Doc has its own changelog.
> diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
> index 48527fd..b895020 100644
> --- a/gdb/testsuite/gdb.mi/mi-break.exp
> +++ b/gdb/testsuite/gdb.mi/mi-break.exp
> @@ -174,11 +174,11 @@ proc test_error {} {
> # containing function call, the internal breakpoint created to handle
> # function call would be reported, messing up MI output.
> mi_gdb_test "-var-create V * return_1()" \
> - "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
> + ".*\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
> "create varobj for function call"
The comment suggests this test is supposed to fail if there is stray
output... adding a leading .* is not nice.
> + /* We try not to notify the observer is not
is not -> if no.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [RFA] Implement *running.
2008-05-02 15:59 ` Daniel Jacobowitz
@ 2008-05-04 16:33 ` Vladimir Prus
2008-05-04 19:50 ` Eli Zaretskii
2008-05-27 19:07 ` Vladimir Prus
0 siblings, 2 replies; 10+ messages in thread
From: Vladimir Prus @ 2008-05-04 16:33 UTC (permalink / raw)
To: Daniel Jacobowitz, Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1835 bytes --]
On Friday 02 May 2008 19:57:19 Daniel Jacobowitz wrote:
> On Thu, May 01, 2008 at 04:35:52PM +0300, Vladimir Prus wrote:
> > This has no regressions in default and async modes on x86. OK?
>
> Just minor concerns. Docs - yes, I know very well that you know this
> - but making sure we see docs before the code change goes in makes
> sure that no one forgets in the crush of other patches. So, sorry,
> but expect to keep getting this reply :-)
I've added the docs. Eli, are those OK?
> Also, what are the expected changes in async and non-async? Will we
> start generating this for non-async and is that likely to break any
> frontend?
The expected change than any command that resumes a target will produce
*running, in either all-stop or non-stop mode. I don't expect this
to break any frontend, as frontends are supposed to ignore things
they don't understand.
>
> > * doc/observer.texi (target_resumed): New observer.
>
> Doc has its own changelog.
>
> > diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
> > index 48527fd..b895020 100644
> > --- a/gdb/testsuite/gdb.mi/mi-break.exp
> > +++ b/gdb/testsuite/gdb.mi/mi-break.exp
> > @@ -174,11 +174,11 @@ proc test_error {} {
> > # containing function call, the internal breakpoint created to handle
> > # function call would be reported, messing up MI output.
> > mi_gdb_test "-var-create V * return_1()" \
> > - "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
> > + ".*\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
> > "create varobj for function call"
>
> The comment suggests this test is supposed to fail if there is stray
> output... adding a leading .* is not nice.
Right. In fact, this test no longer has to be changed.
Here's a revised patch, OK?
- Volodya
[-- Attachment #2: 0001-Implement-running.patch --]
[-- Type: text/x-diff, Size: 24547 bytes --]
From c269adfcba95237ead4911a3498e82d822275707 Mon Sep 17 00:00:00 2001
From: Vladimir Prus <vladimir@codesourcery.com>
Date: Fri, 14 Mar 2008 13:12:37 +0300
Subject: [RFA] Implement *running.
To: gdb-patches@sources.redhat.com
X-KMail-Transport: CodeSourcery
X-KMail-Identity: 901867920
* 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.
[doc]
* observer.texi (target_resumed): New observer.
* gdb.texinfo (GDB/MI Output Records): Document
*running.
[testsuite]
* 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.
---
gdb/Makefile.in | 2 +-
gdb/doc/gdb.texinfo | 8 ++++
gdb/doc/observer.texi | 5 +++
gdb/gdbthread.h | 11 ++++++
gdb/infcall.c | 2 +-
gdb/infcmd.c | 9 +++--
gdb/inferior.h | 2 +-
gdb/infrun.c | 3 +-
gdb/mi/mi-interp.c | 15 ++++++++
gdb/target.c | 9 +++++
gdb/target.h | 6 +---
gdb/testsuite/gdb.mi/mi-console.exp | 2 +-
gdb/testsuite/gdb.mi/mi-syn-frame.exp | 12 +++----
gdb/testsuite/gdb.mi/mi2-console.exp | 2 +-
gdb/testsuite/gdb.mi/mi2-syn-frame.exp | 12 +++----
gdb/testsuite/lib/mi-support.exp | 6 ++--
gdb/thread.c | 61 ++++++++++++++++++++++++++++++++
17 files changed, 135 insertions(+), 32 deletions(-)
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 6bf3a55..e618ae2 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2919,7 +2919,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) \
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index f4b9417..14eaf43 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18154,6 +18154,14 @@ 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.
+@value{GDBN} may emit this notification several times for a given
+thread, and the frontend should handle this gracefully.
+
@item *stopped,reason="@var{reason}"
The target has stopped. The @var{reason} field can have one of the
following values:
diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
index af3835b..7d4d808 100644
--- a/gdb/doc/observer.texi
+++ b/gdb/doc/observer.texi
@@ -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
+
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 56cbd51..8e0da6f 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -69,6 +69,10 @@ struct thread_info
int proceed_to_finish;
+ /* 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;
};
@@ -162,6 +166,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;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 3b5f5ba..b580ecc 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -721,7 +721,7 @@ 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, 1);
+ (&suppress_run_stop_observers, 1);
proceed (real_pc, TARGET_SIGNAL_0, 0);
do_cleanups (old_cleanups2);
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index db0bfaf..b7f6435 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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. */
@@ -1288,7 +1289,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);
}
@@ -1355,7 +1356,7 @@ finish_command (char *arg, int from_tty)
}
proceed_to_finish = 1; /* We want stop_registers, please... */
- make_cleanup_restore_integer (&suppress_normal_stop_observer, 1);
+ make_cleanup_restore_integer (&suppress_run_stop_observers, 1);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
arg1 =
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 630cc52..8958aef 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -401,7 +401,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
diff --git a/gdb/infrun.c b/gdb/infrun.c
index c061a16..1f8e9b3 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3757,11 +3757,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
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index a9a5ffc..4ba1ce1 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -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;
@@ -317,6 +319,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
diff --git a/gdb/target.c b/gdb/target.c
index a8f1afb..159b0fe 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -40,6 +40,7 @@
#include "exceptions.h"
#include "target-descriptions.h"
#include "gdb_stdint.h"
+#include "gdbthread.h"
static void target_info (char *, int);
@@ -1714,6 +1715,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. */
diff --git a/gdb/target.h b/gdb/target.h
index 8822a40..9339d00 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -575,11 +575,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;
diff --git a/gdb/testsuite/gdb.mi/mi-console.exp b/gdb/testsuite/gdb.mi/mi-console.exp
index 7d093dc..70d9342 100644
--- a/gdb/testsuite/gdb.mi/mi-console.exp
+++ b/gdb/testsuite/gdb.mi/mi-console.exp
@@ -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\]+"
diff --git a/gdb/testsuite/gdb.mi/mi-syn-frame.exp b/gdb/testsuite/gdb.mi/mi-syn-frame.exp
index 208678b..59b8e44 100644
--- a/gdb/testsuite/gdb.mi/mi-syn-frame.exp
+++ b/gdb/testsuite/gdb.mi/mi-syn-frame.exp
@@ -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"
diff --git a/gdb/testsuite/gdb.mi/mi2-console.exp b/gdb/testsuite/gdb.mi/mi2-console.exp
index 88b4fdd..c5f6f81 100644
--- a/gdb/testsuite/gdb.mi/mi2-console.exp
+++ b/gdb/testsuite/gdb.mi/mi2-console.exp
@@ -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 {
diff --git a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
index b69812f..948e98d 100644
--- a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
+++ b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
@@ -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"
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 23f3f07..7a821b8 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -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)"
diff --git a/gdb/thread.c b/gdb/thread.c
index fe93b75..60948b8 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -440,6 +440,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.
--
1.5.3.5
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [RFA] Implement *running.
2008-05-04 16:33 ` Vladimir Prus
@ 2008-05-04 19:50 ` Eli Zaretskii
2008-05-11 15:32 ` Vladimir Prus
2008-05-27 19:07 ` Vladimir Prus
1 sibling, 1 reply; 10+ messages in thread
From: Eli Zaretskii @ 2008-05-04 19:50 UTC (permalink / raw)
To: Vladimir Prus; +Cc: drow, gdb-patches
> From: Vladimir Prus <vladimir@codesourcery.com>
> Date: Sun, 4 May 2008 18:37:43 +0400
> Cc: gdb-patches@sources.redhat.com
>
> I've added the docs. Eli, are those OK?
Thanks. Yes, it's okay, except for a couple of comments:
> +@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.
> +@value{GDBN} may emit this notification several times for a given
> +thread, and the frontend should handle this gracefully.
The last sentence begs a question: why would this notification emitted
more than once, and what do you mean by "gracefully"? just that it
shouldn't assume the notification is emitted only once?
> +@deftypefun void target_resumed (ptid_t @var{ptid})
> +The target was resumed. The @var{ptid} parameter specifies which
> +thread was resume
^^^^^^
"resumed".
> , and may be RESUME_ALL if all threads are resumed.
"RESUME_ALL" should be in @code, since it's a C symbol.
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [RFA] Implement *running.
2008-05-04 19:50 ` Eli Zaretskii
@ 2008-05-11 15:32 ` Vladimir Prus
2008-05-11 21:46 ` Eli Zaretskii
0 siblings, 1 reply; 10+ messages in thread
From: Vladimir Prus @ 2008-05-11 15:32 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: drow, gdb-patches
On Sunday 04 May 2008 22:38:03 Eli Zaretskii wrote:
> > From: Vladimir Prus <vladimir@codesourcery.com>
> > Date: Sun, 4 May 2008 18:37:43 +0400
> > Cc: gdb-patches@sources.redhat.com
> >
> > I've added the docs. Eli, are those OK?
>
> Thanks. Yes, it's okay, except for a couple of comments:
>
> > +@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.
> > +@value{GDBN} may emit this notification several times for a given
> > +thread, and the frontend should handle this gracefully.
>
> The last sentence begs a question: why would this notification emitted
> more than once,
Because internally, gdb might resume target more than once before letting
it run freely (e.g. to step over a breakpoint), and it might be hard to
reliably suppress duplicate *running
> and what do you mean by "gracefully"? just that it
> shouldn't assume the notification is emitted only once?
Yes.
How about this wording:
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.
- Volodya
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [RFA] Implement *running.
2008-05-11 15:32 ` Vladimir Prus
@ 2008-05-11 21:46 ` Eli Zaretskii
0 siblings, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2008-05-11 21:46 UTC (permalink / raw)
To: Vladimir Prus; +Cc: drow, gdb-patches
> From: Vladimir Prus <vladimir@codesourcery.com>
> Date: Sun, 11 May 2008 17:57:45 +0400
> Cc: drow@false.org,
> gdb-patches@sources.redhat.com
>
> How about this wording:
>
> 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.
Fine with me, thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Implement *running.
2008-05-04 16:33 ` Vladimir Prus
2008-05-04 19:50 ` Eli Zaretskii
@ 2008-05-27 19:07 ` Vladimir Prus
2008-06-05 15:50 ` Daniel Jacobowitz
1 sibling, 1 reply; 10+ messages in thread
From: Vladimir Prus @ 2008-05-27 19:07 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Eli Zaretskii, gdb-patches
On Sunday 04 May 2008 18:37:43 Vladimir Prus wrote:
> On Friday 02 May 2008 19:57:19 Daniel Jacobowitz wrote:
> > On Thu, May 01, 2008 at 04:35:52PM +0300, Vladimir Prus wrote:
> > > This has no regressions in default and async modes on x86. OK?
> >
> > Just minor concerns. Docs - yes, I know very well that you know this
> > - but making sure we see docs before the code change goes in makes
> > sure that no one forgets in the crush of other patches. So, sorry,
> > but expect to keep getting this reply :-)
>
> I've added the docs. Eli, are those OK?
>
> > Also, what are the expected changes in async and non-async? Will we
> > start generating this for non-async and is that likely to break any
> > frontend?
>
> The expected change than any command that resumes a target will produce
> *running, in either all-stop or non-stop mode. I don't expect this
> to break any frontend, as frontends are supposed to ignore things
> they don't understand.
>
> >
> > > * doc/observer.texi (target_resumed): New observer.
> >
> > Doc has its own changelog.
> >
> > > diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
> > > index 48527fd..b895020 100644
> > > --- a/gdb/testsuite/gdb.mi/mi-break.exp
> > > +++ b/gdb/testsuite/gdb.mi/mi-break.exp
> > > @@ -174,11 +174,11 @@ proc test_error {} {
> > > # containing function call, the internal breakpoint created to handle
> > > # function call would be reported, messing up MI output.
> > > mi_gdb_test "-var-create V * return_1()" \
> > > - "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
> > > + ".*\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \
> > > "create varobj for function call"
> >
> > The comment suggests this test is supposed to fail if there is stray
> > output... adding a leading .* is not nice.
>
> Right. In fact, this test no longer has to be changed.
>
> Here's a revised patch, OK?
Dan,
do you have any further comments on this patch, or it's OK to commit?
- Volodya
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [RFA] Implement *running.
2008-05-27 19:07 ` Vladimir Prus
@ 2008-06-05 15:50 ` Daniel Jacobowitz
2008-06-10 12:43 ` Vladimir Prus
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2008-06-05 15:50 UTC (permalink / raw)
To: Vladimir Prus; +Cc: Eli Zaretskii, gdb-patches
On Tue, May 27, 2008 at 07:55:03PM +0400, Vladimir Prus wrote:
> Dan,
> do you have any further comments on this patch, or it's OK to commit?
The code patch is OK with the revised docs.
Why are the *running checks in the testsuite optional - shouldn't it
always be produced now?
I hope you're right that adding *running in mi2 output won't break
frontends :-)
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Implement *running.
2008-06-05 15:50 ` Daniel Jacobowitz
@ 2008-06-10 12:43 ` Vladimir Prus
0 siblings, 0 replies; 10+ messages in thread
From: Vladimir Prus @ 2008-06-10 12:43 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Eli Zaretskii, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 633 bytes --]
On Thursday 05 June 2008 19:50:33 Daniel Jacobowitz wrote:
> On Tue, May 27, 2008 at 07:55:03PM +0400, Vladimir Prus wrote:
> > Dan,
> > do you have any further comments on this patch, or it's OK to commit?
>
> The code patch is OK with the revised docs.
Thanks. For the record, the final patch I've checked in is attached.
> Why are the *running checks in the testsuite optional - shouldn't it
> always be produced now?
I think they should; I'll check if changing the testsuite to require
those does not reveal any breakage.
> I hope you're right that adding *running in mi2 output won't break
> frontends :-)
Heh.
- Volodya
[-- Attachment #2: commit.diff --]
[-- Type: text/x-diff, Size: 27456 bytes --]
Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.9470
diff -u -p -r1.9470 ChangeLog
--- gdb/ChangeLog 10 Jun 2008 09:35:08 -0000 1.9470
+++ gdb/ChangeLog 10 Jun 2008 10:21:40 -0000
@@ -1,5 +1,27 @@
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.
* mi/mi-interp.c (mi_on_normal_stop): New.
(mi_interpreter_init): Register mi_on_normal_stop.
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1026
diff -u -p -r1.1026 Makefile.in
--- gdb/Makefile.in 6 Jun 2008 20:58:08 -0000 1.1026
+++ gdb/Makefile.in 10 Jun 2008 10:21:43 -0000
@@ -2923,7 +2923,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_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: gdb/gdbthread.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbthread.h,v
retrieving revision 1.23
diff -u -p -r1.23 gdbthread.h
--- gdb/gdbthread.h 4 May 2008 19:38:59 -0000 1.23
+++ gdb/gdbthread.h 10 Jun 2008 10:21:43 -0000
@@ -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 pt
/* 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: gdb/infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.98
diff -u -p -r1.98 infcall.c
--- gdb/infcall.c 10 Jun 2008 09:32:05 -0000 1.98
+++ gdb/infcall.c 10 Jun 2008 10:21:44 -0000
@@ -721,8 +721,8 @@ call_function_by_hand (struct value *fun
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: gdb/infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.186
diff -u -p -r1.186 infcmd.c
--- gdb/infcmd.c 10 Jun 2008 09:35:08 -0000 1.186
+++ gdb/infcmd.c 10 Jun 2008 10:21:44 -0000
@@ -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 cont
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: gdb/inferior.h
===================================================================
RCS file: /cvs/src/src/gdb/inferior.h,v
retrieving revision 1.90
diff -u -p -r1.90 inferior.h
--- gdb/inferior.h 10 Jun 2008 09:32:05 -0000 1.90
+++ gdb/inferior.h 10 Jun 2008 10:21:44 -0000
@@ -393,7 +393,7 @@ void displaced_step_dump_bytes (struct u
/* 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: gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.279
diff -u -p -r1.279 infrun.c
--- gdb/infrun.c 10 Jun 2008 09:32:05 -0000 1.279
+++ gdb/infrun.c 10 Jun 2008 10:21:45 -0000
@@ -3772,11 +3772,12 @@ Further execution is probably impossible
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: gdb/target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.163
diff -u -p -r1.163 target.c
--- gdb/target.c 9 May 2008 17:37:36 -0000 1.163
+++ gdb/target.c 10 Jun 2008 10:21:46 -0000
@@ -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_
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: gdb/target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.121
diff -u -p -r1.121 target.h
--- gdb/target.h 9 May 2008 17:02:01 -0000 1.121
+++ gdb/target.h 10 Jun 2008 10:21:47 -0000
@@ -586,11 +586,7 @@ extern void target_disconnect (char *, i
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: gdb/thread.c
===================================================================
RCS file: /cvs/src/src/gdb/thread.c,v
retrieving revision 1.71
diff -u -p -r1.71 thread.c
--- gdb/thread.c 6 Jun 2008 00:32:51 -0000 1.71
+++ gdb/thread.c 10 Jun 2008 10:21:47 -0000
@@ -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.
Index: gdb/doc/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/doc/ChangeLog,v
retrieving revision 1.790
diff -u -p -r1.790 ChangeLog
--- gdb/doc/ChangeLog 6 Jun 2008 20:58:08 -0000 1.790
+++ gdb/doc/ChangeLog 10 Jun 2008 10:21:49 -0000
@@ -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: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.503
diff -u -p -r1.503 gdb.texinfo
--- gdb/doc/gdb.texinfo 6 Jun 2008 20:58:08 -0000 1.503
+++ gdb/doc/gdb.texinfo 10 Jun 2008 10:21:54 -0000
@@ -18335,6 +18335,17 @@ The following is the list of possible as
@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: gdb/doc/observer.texi
===================================================================
RCS file: /cvs/src/src/gdb/doc/observer.texi,v
retrieving revision 1.15
diff -u -p -r1.15 observer.texi
--- gdb/doc/observer.texi 3 May 2008 15:10:42 -0000 1.15
+++ gdb/doc/observer.texi 10 Jun 2008 10:21:54 -0000
@@ -137,3 +137,8 @@ The thread specified by @var{t} has been
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: gdb/mi/mi-interp.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-interp.c,v
retrieving revision 1.31
diff -u -p -r1.31 mi-interp.c
--- gdb/mi/mi-interp.c 10 Jun 2008 09:35:08 -0000 1.31
+++ gdb/mi/mi-interp.c 10 Jun 2008 10:21:55 -0000
@@ -69,6 +69,7 @@ static void mi_on_normal_stop (struct bp
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: gdb/testsuite/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/ChangeLog,v
retrieving revision 1.1660
diff -u -p -r1.1660 ChangeLog
--- gdb/testsuite/ChangeLog 10 Jun 2008 09:35:08 -0000 1.1660
+++ gdb/testsuite/ChangeLog 10 Jun 2008 10:22:01 -0000
@@ -1,5 +1,14 @@
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.
* gdb.mi/mi-syn-frame.exp: Use mi_expect_stop instead of direct
testing of stopped.
Index: gdb/testsuite/gdb.mi/mi-console.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-console.exp,v
retrieving revision 1.22
diff -u -p -r1.22 mi-console.exp
--- gdb/testsuite/gdb.mi/mi-console.exp 5 Apr 2008 17:12:46 -0000 1.22
+++ gdb/testsuite/gdb.mi/mi-console.exp 10 Jun 2008 10:22:01 -0000
@@ -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: gdb/testsuite/gdb.mi/mi-syn-frame.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-syn-frame.exp,v
retrieving revision 1.18
diff -u -p -r1.18 mi-syn-frame.exp
--- gdb/testsuite/gdb.mi/mi-syn-frame.exp 10 Jun 2008 09:35:08 -0000 1.18
+++ gdb/testsuite/gdb.mi/mi-syn-frame.exp 10 Jun 2008 10:22:01 -0000
@@ -46,7 +46,7 @@ mi_create_breakpoint "foo" 2 keep foo ".
# 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
#
# 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
"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: gdb/testsuite/gdb.mi/mi2-console.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi2-console.exp,v
retrieving revision 1.10
diff -u -p -r1.10 mi2-console.exp
--- gdb/testsuite/gdb.mi/mi2-console.exp 5 Apr 2008 17:12:46 -0000 1.10
+++ gdb/testsuite/gdb.mi/mi2-console.exp 10 Jun 2008 10:22:01 -0000
@@ -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: gdb/testsuite/gdb.mi/mi2-syn-frame.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi2-syn-frame.exp,v
retrieving revision 1.14
diff -u -p -r1.14 mi2-syn-frame.exp
--- gdb/testsuite/gdb.mi/mi2-syn-frame.exp 10 Jun 2008 09:35:08 -0000 1.14
+++ gdb/testsuite/gdb.mi/mi2-syn-frame.exp 10 Jun 2008 10:22:01 -0000
@@ -48,7 +48,7 @@ mi_create_breakpoint "foo" 2 keep foo ".
# 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
# 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
"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: gdb/testsuite/lib/mi-support.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/mi-support.exp,v
retrieving revision 1.61
diff -u -p -r1.61 mi-support.exp
--- gdb/testsuite/lib/mi-support.exp 10 Jun 2008 09:35:09 -0000 1.61
+++ gdb/testsuite/lib/mi-support.exp 10 Jun 2008 10:22:05 -0000
@@ -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 t
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)"
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-06-10 10:26 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-01 13:36 [RFA] Implement *running Vladimir Prus
2008-05-02 9:57 ` Eli Zaretskii
2008-05-02 15:59 ` Daniel Jacobowitz
2008-05-04 16:33 ` Vladimir Prus
2008-05-04 19:50 ` Eli Zaretskii
2008-05-11 15:32 ` Vladimir Prus
2008-05-11 21:46 ` Eli Zaretskii
2008-05-27 19:07 ` Vladimir Prus
2008-06-05 15:50 ` Daniel Jacobowitz
2008-06-10 12:43 ` Vladimir Prus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox