aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/infcmd.c5
-rw-r--r--gdb/mi/mi-interp.c40
-rw-r--r--gdb/mi/mi-main.c37
-rw-r--r--gdb/testsuite/ChangeLog11
-rw-r--r--gdb/testsuite/gdb.mi/mi-break.exp2
-rw-r--r--gdb/testsuite/gdb.mi/mi-syn-frame.exp6
-rw-r--r--gdb/testsuite/gdb.mi/mi2-syn-frame.exp25
-rw-r--r--gdb/testsuite/lib/mi-support.exp64
9 files changed, 114 insertions, 89 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4f4e28c..f18c6c9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,18 @@
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.
+ (mi_interpreter_exec_continuation): Remove.
+ (mi_cmd_interpreter_exec): Don't register the above.
+ * mi/mi-main.c (captured_mi_execute_command): Don't care
+ about sync_execution.
+ (mi_execute_async_cli_command): Don't install continuation. Don't
+ print *stopped.
+ (mi_exec_async_cli_cmd_continuation): Remove.
+
+2008-06-10 Vladimir Prus <vladimir@codesourcery.com>
+
Suppress normal stop observer when it's problematic.
* inferior.h (suppress_normal_stop_observer): New.
* infcall.c (call_function_by_hand): Disable stop events when
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index a844b7d..01e1ebe 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1383,10 +1383,7 @@ finish_command (char *arg, int from_tty)
arg1->data.pointer = breakpoint;
arg2->data.pointer = function;
add_continuation (finish_command_continuation, arg1);
-
- /* Do this only if not running asynchronously or if the target
- cannot do async execution. Otherwise, complete this command when
- the target actually stops, in fetch_inferior_event. */
+
discard_cleanups (old_chain);
if (!target_can_async_p ())
do_all_continuations (0);
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 8b0d909..583c288 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -65,6 +65,7 @@ static void mi1_command_loop (void);
static void mi_insert_notify_hooks (void);
static void mi_remove_notify_hooks (void);
+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);
@@ -92,6 +93,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);
}
return mi;
@@ -171,26 +173,6 @@ mi_interpreter_prompt_p (void *data)
return 0;
}
-static void
-mi_interpreter_exec_continuation (struct continuation_arg *arg, int error_p)
-{
- bpstat_do_actions (&stop_bpstat);
- /* It's not clear what to do in the case of errror -- should we assume that
- the target is stopped, or that it still runs? */
- if (!target_executing)
- {
- fputs_unfiltered ("*stopped", raw_stdout);
- mi_out_put (uiout, raw_stdout);
- fputs_unfiltered ("\n", raw_stdout);
- fputs_unfiltered ("(gdb) \n", raw_stdout);
- gdb_flush (raw_stdout);
- }
- else if (target_can_async_p ())
- {
- add_continuation (mi_interpreter_exec_continuation, NULL);
- }
-}
-
enum mi_cmd_result
mi_cmd_interpreter_exec (char *command, char **argv, int argc)
{
@@ -241,7 +223,6 @@ mi_cmd_interpreter_exec (char *command, char **argv, int argc)
if (target_can_async_p () && target_executing)
{
fputs_unfiltered ("^running\n", raw_stdout);
- add_continuation (mi_interpreter_exec_continuation, NULL);
}
if (mi_error_message != NULL)
@@ -325,12 +306,27 @@ static void
mi_thread_exit (struct thread_info *t)
{
struct mi_interp *mi = top_level_interpreter_data ();
-
target_terminal_ours ();
fprintf_unfiltered (mi->event_channel, "thread-exited,id=\"%d\"", t->num);
gdb_flush (mi->event_channel);
}
+static void
+mi_on_normal_stop (struct bpstats *bs)
+{
+ /* Since this can be called when CLI command is executing,
+ using cli interpreter, be sure to use MI uiout for output,
+ not the current one. */
+ struct ui_out *uiout = interp_ui_out (top_level_interpreter ());
+ struct mi_interp *mi = top_level_interpreter_data ();
+
+ fputs_unfiltered ("*stopped", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ mi_out_rewind (uiout);
+ fputs_unfiltered ("\n", raw_stdout);
+ gdb_flush (raw_stdout);
+}
+
extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
void
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 4ae509e..6dc7609 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -103,10 +103,6 @@ static void mi_execute_cli_command (const char *cmd, int args_p,
const char *args);
static enum mi_cmd_result mi_execute_async_cli_command (char *cli_command,
char **argv, int argc);
-
-static void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg,
- int error_p);
-
static int register_changed_p (int regnum, struct regcache *,
struct regcache *);
static void get_register (int regnum, int format);
@@ -1087,15 +1083,11 @@ captured_mi_execute_command (struct ui_out *uiout, void *data)
fputs_unfiltered ("\n", raw_stdout);
}
else
+ /* The command does not want anything to be printed. In that
+ case, the command probably should not have written anything
+ to uiout, but in case it has written something, discard it. */
mi_out_rewind (uiout);
}
- else if (sync_execution)
- {
- /* Don't print the prompt. We are executing the target in
- synchronous mode. */
- args->action = EXECUTE_COMMAND_SUPPRESS_PROMPT;
- return;
- }
break;
case CLI_COMMAND:
@@ -1311,12 +1303,6 @@ mi_execute_async_cli_command (char *cli_command, char **argv, int argc)
fputs_unfiltered (current_token, raw_stdout);
fputs_unfiltered ("^running\n", raw_stdout);
- /* Ideally, we should be intalling continuation only when
- the target is already running. However, this will break right now,
- because continuation installed by the 'finish' command must be after
- the continuation that prints *stopped. This issue will be
- fixed soon. */
- add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
}
execute_command ( /*ui */ run, 0 /*from_tty */ );
@@ -1332,31 +1318,14 @@ mi_execute_async_cli_command (char *cli_command, char **argv, int argc)
/* Do this before doing any printing. It would appear that some
print code leaves garbage around in the buffer. */
do_cleanups (old_cleanups);
- /* If the target was doing the operation synchronously we fake
- the stopped message. */
- fputs_unfiltered ("*stopped", raw_stdout);
- mi_out_put (uiout, raw_stdout);
- mi_out_rewind (uiout);
if (do_timings)
print_diff_now (current_command_ts);
- fputs_unfiltered ("\n", raw_stdout);
return MI_CMD_QUIET;
}
return MI_CMD_DONE;
}
void
-mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg, int error_p)
-{
- /* Assume 'error' means that target is stopped, too. */
- fputs_unfiltered ("*stopped", raw_stdout);
- mi_out_put (uiout, raw_stdout);
- fputs_unfiltered ("\n", raw_stdout);
- fputs_unfiltered ("(gdb) \n", raw_stdout);
- gdb_flush (raw_stdout);
-}
-
-void
mi_load_progress (const char *section_name,
unsigned long sent_so_far,
unsigned long total_section,
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index d767305..d994d1f 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+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.
+ * gdb.mi/mi2-syn-frame.exp: Likewise.
+ * lib/mi-support.exp (default_mi_gdb_start): Call detect_async.
+ (async, detect_async): New.
+ (mi_expect_stop, mi_continue_to_line): Adjust expectation
+ depending on if we're running in sync or async mode.
+
2008-06-09 Tom Tromey <tromey@redhat.com>
* gdb.base/completion.exp: New tests for field name completion
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index f2f5b03..2798569 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -159,7 +159,7 @@ proc test_ignore_count {} {
mi_run_cmd
gdb_expect {
- -re ".*func=\"callme\".*args=\\\[\{name=\"i\",value=\"2\"\}\\\].*\r\n$mi_gdb_prompt$" {
+ -re ".*\\*stopped.*func=\"callme\".*args=\\\[\{name=\"i\",value=\"2\"\}\\\].*\r\n($mi_gdb_prompt)?$" {
pass "run to breakpoint with ignore count"
}
-re ".*$mi_gdb_prompt$" {
diff --git a/gdb/testsuite/gdb.mi/mi-syn-frame.exp b/gdb/testsuite/gdb.mi/mi-syn-frame.exp
index 2f2ca02..208678b 100644
--- a/gdb/testsuite/gdb.mi/mi-syn-frame.exp
+++ b/gdb/testsuite/gdb.mi/mi-syn-frame.exp
@@ -58,9 +58,7 @@ mi_gdb_test "403-exec-continue" \
"403\\^running" \
"testing exec continue"
-# Presently, the *stopped notification for this case does not include
-# any information. This can be considered a bug.
-mi_gdb_test "" "\\*stopped" "finished exec continue"
+mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
mi_gdb_test "404-stack-list-frames 0 0" \
"404\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"\}.*\\\]" \
@@ -88,7 +86,7 @@ mi_gdb_test "407-stack-list-frames" \
mi_gdb_test "408-exec-continue" "408\\^running"
-mi_gdb_test "" ".*\\*stopped.*" "finished exec continue"
+mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
mi_gdb_test "409-stack-list-frames 0 0" \
"409\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"\}.*\\\]" \
diff --git a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
index c447404..b69812f 100644
--- a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
+++ b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp
@@ -56,15 +56,11 @@ mi_gdb_test "402-stack-list-frames" "402\\^done,stack=\\\[frame=\{level=\"0\",ad
# Continue back to main()
#
-send_gdb "403-exec-continue\n"
-gdb_expect {
- -re "403\\^running\[\r\n\]+${my_mi_gdb_prompt}.*\\\*stopped\[\r\n\]+${my_mi_gdb_prompt}$" {
- pass "403-exec-continue"
- }
- timeout {
- fail "403-exec-continue"
- }
-}
+mi_gdb_test "403-exec-continue" \
+ "403\\^running" \
+ "testing exec continue"
+
+mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
mi_gdb_test "404-stack-list-frames 0 0" \
"404\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"\}.*\\\]" \
@@ -89,16 +85,9 @@ 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"
-send_gdb "408-exec-continue\n"
-gdb_expect {
- -re "408\\^running\[\r\n\]+${my_mi_gdb_prompt}.*\\\*stopped\[\r\n\]+${my_mi_gdb_prompt}$" {
- pass "408-exec-continue"
- }
- timeout {
- fail "408-exec-continue"
- }
-}
+mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue"
mi_gdb_test "409-stack-list-frames 0 0" \
"409\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\"\}.*\\\]" \
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 6a52c88..23f3f07 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -227,6 +227,8 @@ proc default_mi_gdb_start { args } {
}
}
+ detect_async
+
return 0;
}
@@ -911,6 +913,30 @@ proc mi_step { test } {
return [mi_step_to {.*} {.*} {.*} {.*} $test]
}
+set async "unknown"
+
+proc detect_async {} {
+ global async
+ global mi_gdb_prompt
+
+ if { $async == "unknown" } {
+ send_gdb "maint show linux-async\n"
+
+ gdb_expect {
+ -re ".*Controlling the GNU/Linux inferior in asynchronous mode is on...*$mi_gdb_prompt$" {
+ set async 1
+ }
+ -re ".*$mi_gdb_prompt$" {
+ set async 0
+ }
+ timeout {
+ set async 0
+ }
+ }
+ }
+ return $async
+}
+
# Wait for MI *stopped notification to appear.
# The REASON, FUNC, ARGS, FILE and LINE are regular expressions
# to match against whatever is output in *stopped. ARGS should
@@ -933,6 +959,7 @@ proc mi_expect_stop { reason func args file line extra test } {
global hex
global decimal
global fullname_syntax
+ global async
set after_stopped ""
set after_reason ""
@@ -944,10 +971,28 @@ proc mi_expect_stop { reason func args file line extra test } {
set after_stopped [lindex $extra 0]
}
+ if {$async} {
+ set prompt_re ""
+ } else {
+ set prompt_re "$mi_gdb_prompt"
+ }
+
+ if { $reason == "really-no-reason" } {
+ gdb_expect {
+ -re "\\*stopped\r\n$prompt_re$" {
+ pass "$test"
+ }
+ timeout {
+ fail "$test (unknown output after running)"
+ }
+ }
+ return
+ }
+
if { $reason == "exited-normally" } {
gdb_expect {
- -re "\\*stopped,reason=\"exited-normally\"\r\n$mi_gdb_prompt$" {
+ -re "\\*stopped,reason=\"exited-normally\"\r\n$prompt_re$" {
pass "$test"
}
-re ".*$mi_gdb_prompt$" {fail "continue to end (2)"}
@@ -973,17 +1018,17 @@ proc mi_expect_stop { reason func args file line extra test } {
set a $after_reason
- verbose -log "mi_expect_stop: expecting: .*\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\".*$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}$after_stopped\r\n$mi_gdb_prompt$"
+ verbose -log "mi_expect_stop: expecting: .*\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\".*$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}$after_stopped\r\n$prompt_re$"
gdb_expect {
- -re ".*\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\".*$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$mi_gdb_prompt$" {
+ -re ".*\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\".*$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$prompt_re$" {
pass "$test"
return $expect_out(2,string)
}
- -re ".*\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\[\\\[\{\].*\[\\\]\}\],file=\".*\",fullname=\"${fullname_syntax}.*\",line=\"\[0-9\]*\"\}.*\r\n$mi_gdb_prompt$" {
+ -re ".*\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\[\\\[\{\].*\[\\\]\}\],file=\".*\",fullname=\"${fullname_syntax}.*\",line=\"\[0-9\]*\"\}.*\r\n$prompt_re$" {
fail "$test (stopped at wrong place)"
return -1
}
- -re ".*\r\n${mi_gdb_prompt}$" {
+ -re ".*\r\n$mi_gdb_prompt$" {
fail "$test (unknown output after running)"
return -1
}
@@ -1388,9 +1433,16 @@ proc mi_continue_to_line {location test} {
proc mi_get_stop_line {test} {
global mi_gdb_prompt
+ global async
+
+ if {$async} {
+ set prompt_re ""
+ } else {
+ set prompt_re "$mi_gdb_prompt"
+ }
gdb_expect {
- -re ".*line=\"(.*)\".*\r\n$mi_gdb_prompt$" {
+ -re ".*line=\"(.*)\".*\r\n$prompt_re$" {
return $expect_out(1,string)
}
-re ".*$mi_gdb_prompt$" {