Index: NEWS =================================================================== RCS file: /cvs/src/src/gdb/NEWS,v retrieving revision 1.345 diff -p -r1.345 NEWS *** NEWS 6 Jan 2010 04:20:26 -0000 1.345 --- NEWS 6 Jan 2010 04:55:19 -0000 *************** Renesas RX rx *** 24,30 **** lists inferiors that are not running yet or that have exited already. See also "New commands" and "New options" below. ! * Trace state variables GDB tracepoints now include support for trace state variables, which are variables managed by the target agent during a tracing --- 24,34 ---- lists inferiors that are not running yet or that have exited already. See also "New commands" and "New options" below. ! * New tracing features ! ! GDB's tracepoint facility now includes several new features: ! ! ** Trace state variables GDB tracepoints now include support for trace state variables, which are variables managed by the target agent during a tracing *************** Renesas RX rx *** 37,43 **** command to create, and "info tvariables" to view; see "Trace State Variables" in the manual for more detail. ! * Fast tracepoints GDB now includes an option for defining fast tracepoints, which targets may implement more efficiently, such as by installing a jump --- 41,47 ---- command to create, and "info tvariables" to view; see "Trace State Variables" in the manual for more detail. ! ** Fast tracepoints GDB now includes an option for defining fast tracepoints, which targets may implement more efficiently, such as by installing a jump *************** Renesas RX rx *** 49,54 **** --- 53,66 ---- fast tracepoint, use the "ftrace" command, with syntax identical to the regular trace command. + ** Disconnected tracing + + It is now possible to detach GDB from the target while it is running + a trace experiment, then reconnect later to see how the experiment + is going. In addition, a new variable disconnected-tracing lets you + tell the target agent whether to continue running a trace if the + connection is lost unexpectedly. + * Changed commands disassemble *************** show default-collect *** 130,135 **** --- 142,153 ---- This is a useful way to ensure essential items are not overlooked, such as registers or a critical global variable. + set disconnected-tracing + show disconnected-tracing + If set to 1, the target is instructed to continue tracing if it + loses its connection to GDB. If 0, the target is to stop tracing + upon disconnection. + * New remote packets QTDV *************** QTDV *** 138,143 **** --- 156,167 ---- qTV Get the current value of a trace state variable. + QTDisconnected + Set desired tracing behavior upon disconnection. + + qTfP, qTsP + Get data about the tracepoints currently in use. + * Bug fixes Process record now works correctly with hardware watchpoints. Index: breakpoint.h =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.h,v retrieving revision 1.106 diff -p -r1.106 breakpoint.h *** breakpoint.h 6 Jan 2010 04:20:26 -0000 1.106 --- breakpoint.h 6 Jan 2010 04:55:19 -0000 *************** struct breakpoint *** 513,518 **** --- 513,521 ---- /* Chain of action lines to execute when this tracepoint is hit. */ struct action_line *actions; + + /* The number of the tracepoint on the target. */ + int number_on_target; }; typedef struct breakpoint *breakpoint_p; *************** extern void make_breakpoint_silent (stru *** 985,990 **** --- 988,995 ---- /* Return a tracepoint with the given number if found. */ extern struct breakpoint *get_tracepoint (int num); + extern struct breakpoint *get_tracepoint_by_number_on_target (int num); + /* Find a tracepoint by parsing a number in the supplied string. */ extern struct breakpoint *get_tracepoint_by_number (char **arg, int multi_p, int optional_p); Index: breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.447 diff -p -r1.447 breakpoint.c *** breakpoint.c 6 Jan 2010 04:20:26 -0000 1.447 --- breakpoint.c 6 Jan 2010 04:55:19 -0000 *************** ftrace_command (char *arg, int from_tty) *** 9847,9852 **** --- 9847,9873 ---- set_tracepoint_count (breakpoint_count); } + extern void create_tracepoint_from_upload (int num, enum bptype type, + ULONGEST addr); + + extern void + create_tracepoint_from_upload (int num, enum bptype type, ULONGEST addr) + { + char buf[100]; + struct breakpoint *tp; + + sprintf (buf, "*0x%s", paddress (get_current_arch (), addr)); + if (type == bp_fast_tracepoint) + ftrace_command (buf, 0); + else + trace_command (buf, 0); + + /* Record that this tracepoint is numbered differently on host and + target. */ + tp = get_tracepoint (tracepoint_count); + tp->number_on_target = num; + } + /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */ *************** get_tracepoint (int num) *** 9997,10002 **** --- 10018,10039 ---- return NULL; } + /* Find the tracepoint with the given target-side number (which may be + different from the tracepoint number after disconnecting and + reconnecting). */ + + struct breakpoint * + get_tracepoint_by_number_on_target (int num) + { + struct breakpoint *t; + + ALL_TRACEPOINTS (t) + if (t->number_on_target == num) + return t; + + return NULL; + } + /* Utility: parse a tracepoint number and look it up in the list. If MULTI_P is true, there might be a range of tracepoints in ARG. if OPTIONAL_P is true, then if the argument is missing, the most Index: infcmd.c =================================================================== RCS file: /cvs/src/src/gdb/infcmd.c,v retrieving revision 1.255 diff -p -r1.255 infcmd.c *** infcmd.c 1 Jan 2010 07:31:36 -0000 1.255 --- infcmd.c 6 Jan 2010 04:55:19 -0000 *************** *** 55,60 **** --- 55,62 ---- #include "valprint.h" #include "inline-frame.h" + extern void disconnect_or_stop_tracing (int from_tty); + /* Functions exported for general use, in inferior.h: */ void all_registers_info (char *, int); *************** detach_command (char *args, int from_tty *** 2505,2510 **** --- 2507,2514 ---- if (ptid_equal (inferior_ptid, null_ptid)) error (_("The program is not being run.")); + disconnect_or_stop_tracing (from_tty); + target_detach (args, from_tty); /* If the solist is global across inferiors, don't clear it when we Index: remote.c =================================================================== RCS file: /cvs/src/src/gdb/remote.c,v retrieving revision 1.377 diff -p -r1.377 remote.c *** remote.c 6 Jan 2010 04:20:26 -0000 1.377 --- remote.c 6 Jan 2010 04:55:19 -0000 *************** static void show_remote_protocol_packet_ *** 202,207 **** --- 202,210 ---- static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid); static ptid_t read_ptid (char *buf, char **obuf); + struct remote_state; + static void remote_get_tracing_state (struct remote_state *); + static void remote_query_supported (void); static void remote_check_symbols (struct objfile *objfile); *************** struct remote_state *** 301,306 **** --- 304,313 ---- /* True if the stub reports support for fast tracepoints. */ int fast_tracepoints; + /* True if the stub can continue running a trace while GDB is + disconnected. */ + int disconnected_tracing; + /* Nonzero if the user has pressed Ctrl-C, but the target hasn't responded to that. */ int ctrlc_pending_p; *************** remote_start_remote (struct ui_out *uiou *** 2922,2927 **** --- 2929,2941 ---- remote_check_symbols (symfile_objfile); } + /* Possibly the target has been engaged in a trace run started + previously; find out where things are at. */ + if (rs->disconnected_tracing) + { + remote_get_tracing_state (rs); + } + /* If breakpoints are global, insert them now. */ if (gdbarch_has_global_breakpoints (target_gdbarch) && breakpoints_always_inserted_mode ()) *************** remote_fast_tracepoint_feature (const st *** 3149,3154 **** --- 3163,3177 ---- rs->fast_tracepoints = (support == PACKET_ENABLE); } + static void + remote_disconnected_tracing_feature (const struct protocol_feature *feature, + enum packet_support support, + const char *value) + { + struct remote_state *rs = get_remote_state (); + rs->disconnected_tracing = (support == PACKET_ENABLE); + } + static struct protocol_feature remote_protocol_features[] = { { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 }, { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet, *************** static struct protocol_feature remote_pr *** 3179,3184 **** --- 3202,3209 ---- PACKET_ConditionalTracepoints }, { "FastTracepoints", PACKET_DISABLE, remote_fast_tracepoint_feature, PACKET_FastTracepoints }, + { "DisconnectedTracing", PACKET_DISABLE, remote_disconnected_tracing_feature, + -1 }, { "ReverseContinue", PACKET_DISABLE, remote_supported_packet, PACKET_bc }, { "ReverseStep", PACKET_DISABLE, remote_supported_packet, *************** remote_new_objfile (struct objfile *objf *** 9130,9135 **** --- 9155,9338 ---- remote_check_symbols (objfile); } + /* Struct to collect random info about tracepoints on the target. */ + + struct uploaded_tp { + int number; + enum bptype type; + ULONGEST addr; + int enabled; + int step; + int pass; + int orig_size; + char *cond; + int cond_len; + struct uploaded_tp *next; + }; + + struct uploaded_tp *uploaded_tps; + + struct uploaded_tp * + get_uploaded_tp (int num) + { + struct uploaded_tp *utp; + + for (utp = uploaded_tps; utp; utp = utp->next) + if (utp->number == num) + return utp; + utp = (struct uploaded_tp *) xmalloc (sizeof (struct uploaded_tp)); + utp->number = num; + utp->next = uploaded_tps; + uploaded_tps = utp; + return utp; + } + + /* Look for an existing tracepoint that seems similar enough to the + uploaded one. Enablement isn't checked, because the user can + toggle that freely, and may have done so in anticipation of the + next trace run. */ + + struct breakpoint * + find_matching_tracepoint (struct uploaded_tp *utp) + { + VEC(breakpoint_p) *tp_vec = all_tracepoints (); + int ix; + struct breakpoint *t; + + for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) + { + if (t->type == utp->type + && (t->loc && t->loc->address == utp->addr) + && t->step_count == utp->step + && t->pass_count == utp->pass + /* FIXME also test conditionals and actions */ + ) + return t; + } + return NULL; + } + + /* Find out everything we can about the trace run that was already + happening on the target. This includes both running/stopped, and + the tracepoints that were in use. */ + + static void + remote_get_tracing_state (struct remote_state *rs) + { + char *p; + ULONGEST num, addr, step, pass, orig_size, xlen; + int enabled, i; + enum bptype type; + char *cond; + struct uploaded_tp *utp; + struct breakpoint *t; + extern void get_trace_status (); + extern unsigned long trace_running_p; + + get_trace_status (); + if (trace_running_p) + printf_filtered (_("Trace is running on the target.\n")); + + putpkt ("qTfP"); + getpkt (&rs->buf, &rs->buf_size, 0); + p = rs->buf; + while (*p != '\0') + { + if (*p == 'T') + { + p++; + p = unpack_varlen_hex (p, &num); + p++; + p = unpack_varlen_hex (p, &addr); + p++; + enabled = (*p++ == 'E'); + p++; + p = unpack_varlen_hex (p, &step); + p++; + p = unpack_varlen_hex (p, &pass); + p++; + type = bp_tracepoint; + cond = NULL; + while (*p) + { + if (*p == 'F') + { + type = bp_fast_tracepoint; + p++; + p = unpack_varlen_hex (p, &orig_size); + } + else if (*p == 'X') + { + p++; + p = unpack_varlen_hex (p, &xlen); + p++; /* skip the comma */ + cond = (char *) xmalloc (xlen); + hex2bin (p, cond, xlen); + p += 2 * xlen; + } + else + /* Silently skip over anything else. */ + p++; + } + utp = get_uploaded_tp (num); + utp->type = type; + utp->addr = addr; + utp->enabled = enabled; + utp->step = step; + utp->pass = pass; + utp->cond = cond; + utp->cond_len = xlen; + } + else if (*p == 'A') + { + p++; + p = unpack_varlen_hex (p, &num); + p++; + p = unpack_varlen_hex (p, &addr); + p++; + utp = get_uploaded_tp (num); + /* FIXME save the action */ + } + else if (*p == 'S') + { + p++; + p = unpack_varlen_hex (p, &num); + p++; + p = unpack_varlen_hex (p, &addr); + p++; + utp = get_uploaded_tp (num); + /* FIXME save the action */ + } + else if (*p == 'l') + { + /* No more tracepoint info, get out of the loop. */ + break; + } + putpkt ("qTsP"); + getpkt (&rs->buf, &rs->buf_size, 0); + p = rs->buf; + } + /* Got all the tracepoint info, now look for matches among what we + already have in GDB. */ + for (utp = uploaded_tps; utp; utp = utp->next) + { + t = find_matching_tracepoint (utp); + if (t) + { + printf_filtered (_("Assuming tracepoint %d is same as target's tracepoint %d.\n"), + t->number, utp->number); + t->number_on_target = utp->number; + } + else + { + extern void create_tracepoint_from_upload (int num, ULONGEST addr); + create_tracepoint_from_upload (utp->number, utp->addr); + } + } + /* FIXME free all the space */ + uploaded_tps = NULL; + } + void _initialize_remote (void) { Index: tracepoint.c =================================================================== RCS file: /cvs/src/src/gdb/tracepoint.c,v retrieving revision 1.135 diff -p -r1.135 tracepoint.c *** tracepoint.c 6 Jan 2010 04:20:26 -0000 1.135 --- tracepoint.c 6 Jan 2010 04:55:19 -0000 *************** extern char *unpack_varlen_hex (char *bu *** 61,66 **** --- 61,68 ---- #include #endif + extern void stop_tracing (); + /* Maximum length of an agent aexpression. This accounts for the fact that packets are limited to 400 bytes (which includes everything -- including the checksum), and assumes *************** static struct cmd_list_element *tfindlis *** 144,149 **** --- 146,153 ---- /* List of expressions to collect by default at each tracepoint hit. */ static char *default_collect = ""; + static int disconnected_tracing; + static char *target_buf; static long target_buf_size; *************** static struct cleanup *make_cleanup_free *** 172,177 **** --- 176,183 ---- static void free_actions_list (char **actions_list); static void free_actions_list_cleanup_wrapper (void *); + extern void send_disconnected_tracing_value (int value); + extern void _initialize_tracepoint (void); /* Utility: returns true if "target remote" */ *************** remote_set_transparent_ranges (void) *** 1627,1633 **** to the target. If no errors, Tell target to start a new trace experiment. */ ! void download_tracepoint (struct breakpoint *t); static void trace_start_command (char *args, int from_tty) --- 1633,1639 ---- to the target. If no errors, Tell target to start a new trace experiment. */ ! int download_tracepoint (struct breakpoint *t); static void trace_start_command (char *args, int from_tty) *************** trace_start_command (char *args, int fro *** 1637,1642 **** --- 1643,1649 ---- int ix; struct breakpoint *t; struct trace_state_variable *tsv; + int any_downloaded = 0; dont_repeat (); /* Like "run", dangerous to repeat accidentally. */ *************** trace_start_command (char *args, int fro *** 1650,1659 **** tp_vec = all_tracepoints (); for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) { ! download_tracepoint (t); } VEC_free (breakpoint_p, tp_vec); /* Init any trace state variables that start with nonzero values. */ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) --- 1657,1675 ---- tp_vec = all_tracepoints (); for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) { ! t->number_on_target = 0; ! if (download_tracepoint (t)) ! { ! t->number_on_target = t->number; ! any_downloaded = 1; ! } } VEC_free (breakpoint_p, tp_vec); + /* No point in tracing without any tracepoints... */ + if (!any_downloaded) + error ("No tracepoints downloaded, not starting trace"); + /* Init any trace state variables that start with nonzero values. */ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) *************** trace_start_command (char *args, int fro *** 1686,1694 **** error (_("Trace can only be run on remote targets.")); } ! /* Send the definition of a single tracepoint to the target. */ ! void download_tracepoint (struct breakpoint *t) { CORE_ADDR tpaddr; --- 1702,1711 ---- error (_("Trace can only be run on remote targets.")); } ! /* Send the definition of a single tracepoint to the target. Return 1 ! if successful, 0 if not. */ ! int download_tracepoint (struct breakpoint *t) { CORE_ADDR tpaddr; *************** download_tracepoint (struct breakpoint * *** 1759,1765 **** error (_("Target does not support tracepoints.")); if (!t->actions && !*default_collect) ! return; encode_actions (t, &tdp_actions, &stepping_actions); old_chain = make_cleanup (free_actions_list_cleanup_wrapper, --- 1776,1782 ---- error (_("Target does not support tracepoints.")); if (!t->actions && !*default_collect) ! return 1; encode_actions (t, &tdp_actions, &stepping_actions); old_chain = make_cleanup (free_actions_list_cleanup_wrapper, *************** download_tracepoint (struct breakpoint * *** 1802,1807 **** --- 1819,1825 ---- } } do_cleanups (old_chain); + return 1; } /* tstop command */ *************** trace_stop_command (char *args, int from *** 1810,1820 **** { if (target_is_remote ()) { ! putpkt ("QTStop"); ! remote_get_noisy_reply (&target_buf, &target_buf_size); ! if (strcmp (target_buf, "OK")) ! error (_("Bogus reply from target: %s"), target_buf); ! trace_running_p = 0; if (deprecated_trace_start_stop_hook) deprecated_trace_start_stop_hook (0, from_tty); } --- 1828,1834 ---- { if (target_is_remote ()) { ! stop_tracing (); if (deprecated_trace_start_stop_hook) deprecated_trace_start_stop_hook (0, from_tty); } *************** trace_stop_command (char *args, int from *** 1822,1847 **** error (_("Trace can only be run on remote targets.")); } unsigned long trace_running_p; /* tstatus command */ static void trace_status_command (char *args, int from_tty) { if (target_is_remote ()) { ! putpkt ("qTStatus"); ! remote_get_noisy_reply (&target_buf, &target_buf_size); ! ! if (target_buf[0] != 'T' || ! (target_buf[1] != '0' && target_buf[1] != '1')) ! error (_("Bogus reply from target: %s"), target_buf); ! ! /* exported for use by the GUI */ ! trace_running_p = (target_buf[1] == '1'); if (trace_running_p) ! printf_filtered (_("Trace is running on the target.\n")); else printf_filtered (_("Trace is not running on the target.\n")); --- 1836,1883 ---- error (_("Trace can only be run on remote targets.")); } + void + stop_tracing () + { + putpkt ("QTStop"); + remote_get_noisy_reply (&target_buf, &target_buf_size); + if (strcmp (target_buf, "OK")) + error (_("Bogus reply from target: %s"), target_buf); + trace_running_p = 0; + } + unsigned long trace_running_p; + void + get_trace_status () + { + putpkt ("qTStatus"); + remote_get_noisy_reply (&target_buf, &target_buf_size); + + if (target_buf[0] != 'T' || + (target_buf[1] != '0' && target_buf[1] != '1')) + error (_("Bogus trace status reply from target: %s"), target_buf); + + /* exported for use by the GUI */ + trace_running_p = (target_buf[1] == '1'); + } + /* tstatus command */ static void trace_status_command (char *args, int from_tty) { if (target_is_remote ()) { ! get_trace_status (); if (trace_running_p) ! { ! 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 printf_filtered (_("Trace is not running on the target.\n")); *************** trace_status_command (char *args, int fr *** 1856,1861 **** --- 1892,1915 ---- error (_("Trace can only be run on remote targets.")); } + void + disconnect_or_stop_tracing (int from_tty) + { + if (trace_running_p && 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 (); + } + } + /* Worker function for the various flavors of the tfind command. */ static void finish_tfind_command (char **msg, *************** finish_tfind_command (char **msg, *** 1865,1870 **** --- 1919,1925 ---- int target_frameno = -1, target_tracept = -1; struct frame_id old_frame_id; char *reply; + struct breakpoint *tp; old_frame_id = get_frame_id (get_current_frame ()); *************** finish_tfind_command (char **msg, *** 1926,1935 **** error (_("Bogus reply from target: %s"), reply); } reinit_frame_cache (); registers_changed (); set_traceframe_num (target_frameno); ! set_tracepoint_num (target_tracept); if (target_frameno == -1) set_traceframe_context (NULL); else --- 1981,1992 ---- error (_("Bogus reply from target: %s"), reply); } + tp = get_tracepoint_by_number_on_target (target_tracept); + reinit_frame_cache (); registers_changed (); set_traceframe_num (target_frameno); ! set_tracepoint_num (tp ? tp->number : target_tracept); if (target_frameno == -1) set_traceframe_context (NULL); else *************** static void *** 2064,2069 **** --- 2121,2127 ---- trace_find_tracepoint_command (char *args, int from_tty) { int tdp; + struct breakpoint *tp; if (target_is_remote ()) { *************** trace_find_tracepoint_command (char *arg *** 2080,2085 **** --- 2138,2150 ---- else tdp = parse_and_eval_long (args); + /* If we have the tracepoint on hand, use the number that the + target knows about (which may be different if we disconnected + and reconnected). */ + tp = get_tracepoint (tdp); + if (tp) + tdp = tp->number_on_target; + sprintf (target_buf, "QTFrame:tdp:%x", tdp); finish_tfind_command (&target_buf, &target_buf_size, from_tty); } *************** trace_dump_command (char *args, int from *** 2550,2555 **** --- 2615,2646 ---- discard_cleanups (old_cleanups); } + /* Tell the target what to do with an ongoing tracing run if GDB + disconnects for some reason. */ + + void + send_disconnected_tracing_value (int value) + { + char buf[30]; + + /* No need to do anything special if target not active. */ + if (!target_is_remote ()) + return; + + sprintf (buf, "QTDisconnected:%x", value); + putpkt (buf); + remote_get_noisy_reply (&target_buf, &target_buf_size); + if (strcmp (target_buf, "OK")) + error (_("Target does not support this command.")); + } + + static void + set_disconnected_tracing (char *args, int from_tty, + struct cmd_list_element *c) + { + send_disconnected_tracing_value (disconnected_tracing); + } + /* Convert the memory pointed to by mem into hex, placing result in buf. * Return a pointer to the last char put in buf (null) * "stolen" from sparc-stub.c *************** get_traceframe_number (void) *** 2581,2587 **** return traceframe_number; } - /* module initialization */ void _initialize_tracepoint (void) --- 2672,2677 ---- *************** Show the list of expressions to collect *** 2747,2752 **** --- 2837,2854 ---- NULL, NULL, &setlist, &showlist); + add_setshow_boolean_cmd ("disconnected-tracing", no_class, + &disconnected_tracing, _("\ + Set whether tracing continues after GDB disconnects."), _("\ + Show whether tracing continues after GDB disconnects."), _("\ + Use this to continue a tracing run even if GDB disconnects\n\ + or detaches from the target. You can reconnect later and look at\n\ + trace data collected in the meantime."), + set_disconnected_tracing, + NULL, + &setlist, + &showlist); + target_buf_size = 2048; target_buf = xmalloc (target_buf_size); } Index: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.655 diff -p -r1.655 gdb.texinfo *** doc/gdb.texinfo 6 Jan 2010 04:20:27 -0000 1.655 --- doc/gdb.texinfo 6 Jan 2010 04:55:20 -0000 *************** Enter actions for tracepoint #1, one per *** 9781,9786 **** --- 9781,9827 ---- (@value{GDBP}) @b{tstop} @end smallexample + @cindex disconnected tracing + You can choose to continue running the trace experiment even if + @value{GDBN} disconnects from the target, voluntarily or + involuntarily. For commands such as @code{detach}, the debugger will + ask what you want to do with the trace. But for unexpected + terminations (@value{GDBN} crash, network outage), it would be + unfortunate to lose hard-won trace data, so the variable + @code{disconnected-tracing} lets you decide whether the trace should + continue running without @value{GDBN}. + + @table @code + @item set disconnected-tracing on + @itemx set disconnected-tracing off + @kindex set disconnected-tracing + Choose whether a tracing run should continue to run if @value{GDBN} + has disconnected from the target. Note that @code{detach} or + @code{quit} will ask you directly what to do about a running trace no + matter what this variable's setting, so the variable is mainly useful + for handling unexpected situations, such as loss of the network. + + @item show disconnected-tracing + @kindex show disconnected-tracing + Show the current choice for disconnected tracing. + + @end table + + When you reconnect to the target, the trace experiment may or may not + still be running; it might have filled the trace buffer in the + meantime, or stopped for one of the other reasons. If it is running, + it will continue after reconnection. + + Upon reconnection, the target will upload information about the + tracepoints in effect. @value{GDBN} will then compare that + information to the set of tracepoints currently defined, and attempt + to match them up, allowing for the possibility that the numbers may + have changed due to creation and deletion in the meantime. If one of + the target's tracepoints does not match any in @value{GDBN}, the + debugger will create a new tracepoint, so that you have a number with + which to specify that tracepoint. This matching-up process is + necessarily heuristic, and it may result in useless tracepoints being + created; you may simply delete them if they are of no use. @node Analyze Collected Data @section Using the Collected Data *************** encoded). @value{GDBN} will continue to *** 29721,29727 **** (if available), until the target ceases to request them. @end table ! @item QTDP @itemx QTFrame @xref{Tracepoint Packets}. --- 29762,29771 ---- (if available), until the target ceases to request them. @end table ! @item QTDisconnected ! @itemx QTDP ! @itemx QTDV ! @itemx QTfP @itemx QTFrame @xref{Tracepoint Packets}. *************** the command by a @samp{,}, not a @samp{: *** 29750,29760 **** conventions above. Please don't use this packet as a model for new packets.) ! @item QTStart @itemx QTStop @itemx QTinit @itemx QTro @itemx qTStatus @xref{Tracepoint Packets}. @item qXfer:@var{object}:read:@var{annex}:@var{offset},@var{length} --- 29794,29806 ---- conventions above. Please don't use this packet as a model for new packets.) ! @item QTsP ! @itemx QTStart @itemx QTStop @itemx QTinit @itemx QTro @itemx qTStatus + @itemx qTV @xref{Tracepoint Packets}. @item qXfer:@var{object}:read:@var{annex}:@var{offset},@var{length} *************** containing program code. Since these ar *** 30152,30157 **** --- 30198,30209 ---- still have the same contents they did when the tracepoint was hit, so there's no reason for the stub to refuse to provide their contents. + @item QTDisconnected:@var{value} + Set the choice to what to do with the tracing run when @value{GDBN} + disconnects from the target. A @var{value} of 1 directs the target to + continue the tracing run, while 0 tells the target to stop tracing if + @value{GDBN} is no longer in the picture. + @item qTStatus Ask the stub if there is a trace experiment running right now. *************** if the user is examining a trace frame i *** 30184,30189 **** --- 30236,30249 ---- was not collected. @end table + @item qTfP + @itemx qTsP + These packets request data about tracepoints that are being used by + the target. @value{GDBN} sends @code{qTfP} to get the first piece + of data, and multiple @code{qTsP} to get additional pieces. Replies + to these packets generally take the form of the @code{QTDP} packets + that define tracepoints. (FIXME add detailed syntax) + @end table @node Host I/O Packets Index: cli/cli-cmds.c =================================================================== RCS file: /cvs/src/src/gdb/cli/cli-cmds.c,v retrieving revision 1.95 diff -p -r1.95 cli-cmds.c *** cli/cli-cmds.c 1 Jan 2010 07:31:46 -0000 1.95 --- cli/cli-cmds.c 6 Jan 2010 04:55:20 -0000 *************** *** 37,42 **** --- 37,43 ---- #include "objfiles.h" #include "source.h" #include "disasm.h" + extern void disconnect_or_stop_tracing (int from_tty); #include "ui-out.h" *************** quit_command (char *args, int from_tty) *** 317,322 **** --- 318,326 ---- { if (!quit_confirm ()) error (_("Not confirmed.")); + + disconnect_or_stop_tracing (from_tty); + quit_force (args, from_tty); }