This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: tracing broken if target doesn't do disconnected tracing
Pedro Alves wrote:
On Monday 05 April 2010 02:07:56, Stan Shebs wrote:
I'm thinking that this is in some ways like the circular trace buffer
flag, and could be reasonably made accessible via the trace_status
structure. Unless you're just dying to do this yourself :-) , I'll take
care of the two together.
Please, be my guest. :-)
Here's my suggested changes, and of course it implies some target-side
changes as well. Turns out that I generated some confusion for myself
by auto-generating tstop commands, which I realized when I was unable to
write a code comment that justified it. :-)
So the new behavior is that GDB always simply drops the connection. If
the target can do disconnected tracing, it just keeps going. If it
can't, or the query answer instructs it to not keep tracing, it stops,
and records the stop reason as "tdisconnection"; you'll then see that
when you reconnect to the target and do a tstatus. Since tstatus
reports the target's state consistently now, you'll also see that in a
trace file. Ditto for circularity of trace buffer.
If this behavior seems reasonable, I'll add appropriate bits to the
manual and repost/commit.
As for multi-process, I can see reasons to make these kinds of flags
either per-process or global to the target, so didn't try to guess at
the final decision here. :-)
2010-04-06 Stan Shebs <stan@codesourcery.com>
Pedro Alves <pedro@codesourcery.com>
* tracepoint.h (struct trace_status): New fields disconnected_tracing
and circular_buffer.
* tracepoint.c (trace_status_command): Display target's status for
disconnected tracing and circular buffer.
(disconnect_or_stop_tracing): Add query for non-disconnected-tracing
case, remove the stop_tracing call.
(tfile_open): Clear disconnected and circular buffer status.
(trace_save): Save disconnected and circular buffer status.
(parse_trace_status): Parse disconnected and circular buffer status,
also recognize disconnected as a stop reason.
* remote.c (remote_set_disconnected_tracing): Only set
QTDisconnected if the remote end supports disconnected tracing.
Warn otherwise, if trying to enable disconnected tracing.
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.399
diff -p -r1.399 remote.c
*** remote.c 2 Apr 2010 01:18:34 -0000 1.399
--- remote.c 7 Apr 2010 01:16:33 -0000
*************** remote_set_disconnected_tracing (int val
*** 9776,9786 ****
{
struct remote_state *rs = get_remote_state ();
! sprintf (rs->buf, "QTDisconnected:%x", val);
! putpkt (rs->buf);
! remote_get_noisy_reply (&target_buf, &target_buf_size);
! if (strcmp (target_buf, "OK"))
! error (_("Target does not support this command."));
}
static int
--- 9776,9791 ----
{
struct remote_state *rs = get_remote_state ();
! if (rs->disconnected_tracing)
! {
! sprintf (rs->buf, "QTDisconnected:%x", val);
! putpkt (rs->buf);
! remote_get_noisy_reply (&target_buf, &target_buf_size);
! if (strcmp (target_buf, "OK"))
! error (_("Target does not support this command."));
! }
! else if (val)
! warning (_("Target does not support disconnected tracing."));
}
static int
Index: tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.c,v
retrieving revision 1.173
diff -p -r1.173 tracepoint.c
*** tracepoint.c 6 Apr 2010 17:47:40 -0000 1.173
--- tracepoint.c 7 Apr 2010 01:16:33 -0000
*************** trace_status_command (char *args, int fr
*** 1626,1635 ****
else if (ts->running)
{
printf_filtered (_("Trace is running on the target.\n"));
- if (disconnected_tracing)
- printf_filtered (_("Trace will continue if GDB disconnects.\n"));
- else
- printf_filtered (_("Trace will stop if GDB disconnects.\n"));
}
else
{
--- 1626,1631 ----
*************** trace_status_command (char *args, int fr
*** 1699,1704 ****
--- 1695,1708 ----
ts->buffer_free);
}
+ if (ts->disconnected_tracing)
+ printf_filtered (_("Trace will continue if GDB disconnects.\n"));
+ else
+ printf_filtered (_("Trace will stop if GDB disconnects.\n"));
+
+ if (ts->circular_buffer)
+ printf_filtered (_("Trace buffer is circular.\n"));
+
/* Now report on what we're doing with tfind. */
if (traceframe_number >= 0)
printf_filtered (_("Looking at trace frame %d, tracepoint %d.\n"),
*************** trace_status_mi (int on_stop)
*** 1801,1806 ****
--- 1805,1813 ----
ui_out_field_int (uiout, "buffer-free", (int) ts->buffer_free);
}
+ /* This function handles the details of what to do about an ongoing
+ tracing run if the user has asked to detach or otherwise disconnect
+ from the target. */
void
disconnect_or_stop_tracing (int from_tty)
*************** disconnect_or_stop_tracing (int from_tty
*** 1812,1829 ****
if (target_get_trace_status (current_trace_status ()) < 0)
current_trace_status ()->running = 0;
if (current_trace_status ()->running && from_tty)
{
! int cont = query (_("Trace is running. Continue tracing after detach? "));
! /* Note that we send the query result without affecting the
! user's setting of disconnected_tracing, so that the answer is
! a one-time-only. */
! send_disconnected_tracing_value (cont);
!
! /* Also ensure that we do the equivalent of a tstop command if
! tracing is not to continue after the detach. */
! if (!cont)
! stop_tracing ();
}
/* Also we want to be out of tfind mode, otherwise things can get
--- 1819,1844 ----
if (target_get_trace_status (current_trace_status ()) < 0)
current_trace_status ()->running = 0;
+ /* If running interactively, offer the user options for what to do
+ with the run. Scripts are just going to disconnect and let the
+ target deal with it, according to how it's been instructed
+ previously via disconnected-tracing. */
if (current_trace_status ()->running && from_tty)
{
! if (current_trace_status ()->disconnected_tracing)
! {
! int cont = query (_("Trace is running. Continue tracing after detach? "));
!
! /* Note that we send the query result without affecting the
! user's setting of disconnected_tracing, so that the answer is
! a one-time-only. */
! send_disconnected_tracing_value (cont);
! }
! else
! {
! if (!query (_("Trace is running but will stop on detach; detach anyway? ")))
! error (_("Not confirmed."));
! }
}
/* Also we want to be out of tfind mode, otherwise things can get
*************** trace_save (const char *filename, int ta
*** 2599,2604 ****
--- 2614,2623 ----
fprintf (fp, ";tfree:%x", ts->buffer_free);
if (ts->buffer_size >= 0)
fprintf (fp, ";tsize:%x", ts->buffer_size);
+ if (ts->disconnected_tracing)
+ fprintf (fp, ";disconn:%x", ts->disconnected_tracing);
+ if (ts->circular_buffer)
+ fprintf (fp, ";circular:%x", ts->circular_buffer);
fprintf (fp, "\n");
/* Note that we want to upload tracepoints and save those, rather
*************** tfile_open (char *filename, int from_tty
*** 3167,3172 ****
--- 3186,3193 ----
ts->stop_reason = trace_stop_reason_unknown;
ts->traceframe_count = -1;
ts->buffer_free = 0;
+ ts->disconnected_tracing = 0;
+ ts->circular_buffer = 0;
/* Read through a section of newline-terminated lines that
define things like tracepoints. */
*************** parse_trace_status (char *line, struct t
*** 3282,3287 ****
--- 3303,3310 ----
ts->traceframes_created = -1;
ts->buffer_free = -1;
ts->buffer_size = -1;
+ ts->disconnected_tracing = 0;
+ ts->circular_buffer = 0;
while (*p++)
{
*************** Status line: '%s'\n"), p, line);
*** 3310,3315 ****
--- 3333,3343 ----
p = unpack_varlen_hex (++p1, &val);
ts->stop_reason = tstop_command;
}
+ else if (strncmp (p, stop_reason_names[trace_disconnected], p1 - p) == 0)
+ {
+ p = unpack_varlen_hex (++p1, &val);
+ ts->stop_reason = trace_disconnected;
+ }
else if (strncmp (p, stop_reason_names[tracepoint_error], p1 - p) == 0)
{
p2 = strchr (++p1, ':');
*************** Status line: '%s'\n"), p, line);
*** 3348,3353 ****
--- 3376,3391 ----
p = unpack_varlen_hex (++p1, &val);
ts->buffer_size = val;
}
+ else if (strncmp (p, "disconn", p1 - p) == 0)
+ {
+ p = unpack_varlen_hex (++p1, &val);
+ ts->disconnected_tracing = val;
+ }
+ else if (strncmp (p, "circular", p1 - p) == 0)
+ {
+ p = unpack_varlen_hex (++p1, &val);
+ ts->circular_buffer = val;
+ }
else
{
/* Silently skip unknown optional info. */
Index: tracepoint.h
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.h,v
retrieving revision 1.34
diff -p -r1.34 tracepoint.h
*** tracepoint.h 6 Apr 2010 17:47:40 -0000 1.34
--- tracepoint.h 7 Apr 2010 01:16:33 -0000
*************** struct trace_status
*** 106,111 ****
--- 106,121 ----
/* Unused bytes left in the target's trace buffer. */
int buffer_free;
+
+ /* 1 if the target will continue tracing after disconnection, else
+ 0. If the target does not report a value, assume 0. */
+
+ int disconnected_tracing;
+
+ /* 1 if the target is using a circular trace buffer, else 0. If the
+ target does not report a value, assume 0. */
+
+ int circular_buffer;
};
struct trace_status *current_trace_status (void);