[PATCH 4/5] MI notification on trace started/stopped

Yao Qi
2014-01-24T09:43:22Z

Hi,
This patch adds the notifications of 'trace-started' and
'trace-stopped', which are emitted when trace is started or stopped by
command 'tstart' and 'tstop', so that when trace is started or stopped
in console, MI frontend can be notified.

The documentation patch was approved by Eli here
<http://sourceware.org/ml/gdb-patches/2013-02/msg00441.html>

V8:
Only calls observer_notify_trace_changed when GDB gets an async
remote notification, in order to keep events order correct.

gdb/doc:

* gdb.texinfo (GDB/MI Async Records): New MI notifications
'trace-changed'.
* observer.texi (GDB Observers): New observer 'trace-changed'.

gdb:

* mi/mi-cmds.c (mi_cmds): Adjust for commands 'trace-start'
and 'trace-stop'.
* mi/mi-interp.c: Declare mi_trace_changed.
(mi_interpreter_init): Install mi_trace_changed to observer.
(mi_trace_changed): New.
* mi/mi-main.h (struct mi_suppress_notification) <trace>:
New field.
* remote-notif-trace.c: Include "observer.h".
(remote_notif_trace_parse): Call
observer_notify_trace_changed.
* NEWS: Mention it.
---
gdb/NEWS | 5 +++++
gdb/doc/gdb.texinfo | 4 ++++
gdb/doc/observer.texi | 6 ++++++
gdb/mi/mi-cmds.c | 6 ++++--
gdb/mi/mi-interp.c | 22 ++++++++++++++++++++++
gdb/mi/mi-main.h | 2 ++
gdb/remote-notif-trace.c | 3 +++
7 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 6b1aacb..b8aaa2d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -42,6 +42,11 @@ qXfer:btrace:read's annex
The qXfer:btrace:read packet supports a new annex 'delta' to read
branch trace incrementally.

+* MI changes
+
+ ** The start and stop of trace are now notified using new async records
+ "=trace-started" and "=trace-stopped".
+
*** Changes in GDB 7.7

* Improved support for process record-replay and reverse debugging on
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 573bc83..d0e13b7 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -29736,6 +29736,10 @@ written in an inferior. The @var{id} is the identifier of the
thread group corresponding to the affected inferior. The optional
@code{type="code"} part is reported if the memory written to holds
executable code.
+
+@item =trace-started
+@itemx =trace-stopped
+Reports that trace was started or stopped.
@end table

@node GDB/MI Breakpoint Information
diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
index 61acbb2..fa8bbaa 100644
--- a/gdb/doc/observer.texi
+++ b/gdb/doc/observer.texi
@@ -253,6 +253,12 @@ The trace state variable @var{tsv} is deleted. If @var{tsv} is
The trace state value @var{tsv} is modified.
@end deftypefun

+@deftypefun void trace_changed (int @var{started})
+The status of trace in @value{GDBN} has changed. The trace is started
+if @var{started} is non-zero, and the trace is stopped if
+@var{started} is zero.
+@end deftypefun
+
@deftypefun void test_notification (int @var{somearg})
This observer is used for internal testing. Do not use.
See testsuite/gdb.gdb/observer.exp.
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 87a536f..81ecc46 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -158,9 +158,11 @@ static struct mi_cmd mi_cmds[] =
mi_cmd_trace_frame_collected),
DEF_MI_CMD_MI ("trace-list-variables", mi_cmd_trace_list_variables),
DEF_MI_CMD_MI ("trace-save", mi_cmd_trace_save),
- DEF_MI_CMD_MI ("trace-start", mi_cmd_trace_start),
+ DEF_MI_CMD_MI_1 ("trace-start", mi_cmd_trace_start,
+ &mi_suppress_notification.trace),
DEF_MI_CMD_MI ("trace-status", mi_cmd_trace_status),
- DEF_MI_CMD_MI ("trace-stop", mi_cmd_trace_stop),
+ DEF_MI_CMD_MI_1 ("trace-stop", mi_cmd_trace_stop,
+ &mi_suppress_notification.trace),
DEF_MI_CMD_MI ("var-assign", mi_cmd_var_assign),
DEF_MI_CMD_MI ("var-create", mi_cmd_var_create),
DEF_MI_CMD_MI ("var-delete", mi_cmd_var_delete),
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 25bf0a1..44e3f35 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -64,6 +64,7 @@ static void mi_inferior_appeared (struct inferior *inf);
static void mi_inferior_exit (struct inferior *inf);
static void mi_inferior_removed (struct inferior *inf);
static void mi_on_resume (ptid_t ptid);
+static void mi_trace_changed (int started);
static void mi_solib_loaded (struct so_list *solib);
static void mi_solib_unloaded (struct so_list *solib);
static void mi_about_to_proceed (void);
@@ -129,6 +130,7 @@ mi_interpreter_init (struct interp *interp, int top_level)
observer_attach_record_changed (mi_record_changed);
observer_attach_normal_stop (mi_on_normal_stop);
observer_attach_target_resumed (mi_on_resume);
+ observer_attach_trace_changed (mi_trace_changed);
observer_attach_solib_loaded (mi_solib_loaded);
observer_attach_solib_unloaded (mi_solib_unloaded);
observer_attach_about_to_proceed (mi_about_to_proceed);
@@ -582,6 +584,26 @@ mi_tsv_modified (const struct trace_state_variable *tsv)
gdb_flush (mi->event_channel);
}

+/* Emit notification on trace was started or stopped. */
+
+static void
+mi_trace_changed (int started)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+
+ if (mi_suppress_notification.trace)
+ return;
+
+ target_terminal_ours ();
+
+ if (started)
+ fprintf_unfiltered (mi->event_channel, "trace-started\n");
+ else
+ fprintf_unfiltered (mi->event_channel, "trace-stopped\n");
+
+ gdb_flush (mi->event_channel);
+}
+
/* Emit notification about a created breakpoint. */

static void
diff --git a/gdb/mi/mi-main.h b/gdb/mi/mi-main.h
index c32845d..343c8bb 100644
--- a/gdb/mi/mi-main.h
+++ b/gdb/mi/mi-main.h
@@ -43,6 +43,8 @@ struct mi_suppress_notification
int traceframe;
/* Memory changed notification suppressed? */
int memory;
+ /* Trace started/stopped notification suppressed? */
+ int trace;
};
extern struct mi_suppress_notification mi_suppress_notification;

diff --git a/gdb/remote-notif-trace.c b/gdb/remote-notif-trace.c
index 9ae1d33..75b6300 100644
--- a/gdb/remote-notif-trace.c
+++ b/gdb/remote-notif-trace.c
@@ -22,6 +22,7 @@
#include "remote.h"
#include "tracepoint.h"
#include "remote-notif.h"
+#include "observer.h"

static void
remote_notif_trace_parse (struct notif_client *self, char *buf,
@@ -34,6 +35,8 @@ remote_notif_trace_parse (struct notif_client *self, char *buf,
if (buf[7] != 'T')
error (_("Unknown trace status in trace notification."));
parse_trace_status (buf + 7 + 1, ts);
+
+ observer_notify_trace_changed (ts->running);
}
else
error (_("Unknown trace notification."));
--
1.7.7.6