diff options
author | Stan Shebs <shebs@codesourcery.com> | 2011-11-20 23:59:49 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 2011-11-20 23:59:49 +0000 |
commit | f196051f5ee7f3aa3f417611a488ba773878a429 (patch) | |
tree | 25de238e78d9db1ad631611a10bcfd298b472a49 /gdb/gdbserver/tracepoint.c | |
parent | 9866a1803a670e48d8fedf0e33d0eb5141192318 (diff) | |
download | gdb-f196051f5ee7f3aa3f417611a488ba773878a429.zip gdb-f196051f5ee7f3aa3f417611a488ba773878a429.tar.gz gdb-f196051f5ee7f3aa3f417611a488ba773878a429.tar.bz2 |
* NEWS: Mention tracepoint additions.
* breakpoint.h (struct tracepoint): New field traceframe_usage.
* breakpoint.c (print_one_breakpoint_location): Identify
tracepoints as such when reporting hit counts, report
trace buffer usage.
(create_tracepoint_from_upload): Copy status info.
* tracepoint.h (struct trace_status): Rename error_desc to stop_desc,
add fields user_name, notes, start_time, stop_time.
(struct uploaded_tp): Add fields hit_count, traceframe_usage.
* tracepoint.c (trace_user): New global.
(trace_notes): New global.
(trace_stop_notes): New global.
(start_tracing): Add argument and trace note handling.
(stop_tracing): Ditto.
(trace_start_command): Add notes argument.
(trace_stop_command): Ditto.
(trace_status_command): Report additional status info.
(trace_status_mi): Similarly.
(trace_save): Update, record tracepoint status.
(set_disconnected_tracing): Call target method directly.
(send_disconnected_tracing_value): Remove.
(set_trace_user): New function.
(set_trace_notes): New function.
(set_trace_stop_notes): New function.
(parse_trace_status): Handle additional status.
(parse_tracepoint_status): New function.
(parse_tracepoint_definition): Call it.
(tfile_get_tracepoint_status): New function.
(init_tfile_ops): Use it.
(_initialize_tracepoint): Add new setshows.
* target.h (struct target_ops): New methods to_get_tracepoint_status
and to_set_trace_notes.
(target_get_tracepoint_status): New macro.
(target_set_trace_notes): New macro.
* target.c (update_current_target): Add new methods.
* remote.c (remote_get_tracepoint_status): New function.
(remote_set_trace_notes): New function.
(init_remote_ops): Add them.
* mi/mi-main.c (mi_cmd_trace_start): Add argument to call.
(mi_cmd_trace_stop): Ditto.
* tracepoint.c (struct tracepoint): New field traceframe_usage.
(tracing_start_time): New global.
(tracing_stop_time): New global.
(tracing_user_name): New global.
(tracing_notes): New global.
(tracing_stop_note): New global.
(cmd_qtstart): Set traceframe_usage, start_time.
(stop_tracing): Set stop_time.
(cmd_qtstatus): Report additional status.
(cmd_qtp): New function.
(handle_tracepoint_query): Call it.
(cmd_qtnotes): New function.
(handle_tracepoint_general_set): Call it.
(get_timestamp): Rename from tsv_get_timestamp.
* gdb.texinfo (Starting and Stopping Trace Experiments): Document
note-related options and variables.
(Tracepoint Packets): Document packet changes.
* gdb.trace/tstatus.exp: New.
* gdb.trace/actions.c: Include string.h.
Diffstat (limited to 'gdb/gdbserver/tracepoint.c')
-rw-r--r-- | gdb/gdbserver/tracepoint.c | 169 |
1 files changed, 164 insertions, 5 deletions
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index b00df05..e6a5bbc 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -632,6 +632,9 @@ struct tracepoint Note that while-stepping steps are not counted as "hits". */ long hit_count; + /* Cached sum of the sizes of traceframes created by this point. */ + long traceframe_usage; + CORE_ADDR compiled_cond; /* Link to the next tracepoint in the list. */ @@ -1144,6 +1147,27 @@ static const char *tracing_stop_reason = "tnotrun"; static int tracing_stop_tpnum; +/* 64-bit timestamps for the trace run's start and finish, expressed + in microseconds from the Unix epoch. */ + +LONGEST tracing_start_time; +LONGEST tracing_stop_time; + +/* The (optional) user-supplied name of the user that started the run. + This is an arbitrary string, and may be NULL. */ + +char *tracing_user_name; + +/* Optional user-supplied text describing the run. This is + an arbitrary string, and may be NULL. */ + +char *tracing_notes; + +/* Optional user-supplied text explaining a tstop command. This is an + arbitrary string, and may be NULL. */ + +char *tracing_stop_note; + #endif /* Functions local to this file. */ @@ -1266,6 +1290,8 @@ static void download_tracepoint (struct tracepoint *); static int install_fast_tracepoint (struct tracepoint *, char *errbuf); #endif +static LONGEST get_timestamp (void); + #if defined(__GNUC__) # define memory_barrier() asm volatile ("" : : : "memory") #else @@ -3027,6 +3053,7 @@ cmd_qtstart (char *packet) { /* Ensure all the hit counts start at zero. */ tpoint->hit_count = 0; + tpoint->traceframe_usage = 0; if (tpoint->type == trap_tracepoint) { @@ -3103,6 +3130,7 @@ cmd_qtstart (char *packet) trace_buffer_is_full = 0; expr_eval_result = expr_eval_no_error; error_tracepoint = NULL; + tracing_start_time = get_timestamp (); /* Tracing is now active, hits will now start being logged. */ tracing = 1; @@ -3172,6 +3200,7 @@ stop_tracing (void) fatal ("Error clearing tracing variable in lib"); } + tracing_stop_time = get_timestamp (); tracing_stop_reason = "t???"; tracing_stop_tpnum = 0; if (stopping_tracepoint) @@ -3352,6 +3381,26 @@ static void cmd_qtstatus (char *packet) { char *stop_reason_rsp = NULL; + char *buf1, *buf2, *buf3, *str; + int slen; + + /* Translate the plain text of the notes back into hex for + transmission. */ + + str = (tracing_user_name ? tracing_user_name : ""); + slen = strlen (str); + buf1 = (char *) alloca (slen * 2 + 1); + hexify (buf1, str, slen); + + str = (tracing_notes ? tracing_notes : ""); + slen = strlen (str); + buf2 = (char *) alloca (slen * 2 + 1); + hexify (buf2, str, slen); + + str = (tracing_stop_note ? tracing_stop_note : ""); + slen = strlen (str); + buf3 = (char *) alloca (slen * 2 + 1); + hexify (buf3, str, slen); trace_debug ("Returning trace status as %d, stop reason %s", tracing, tracing_stop_reason); @@ -3368,7 +3417,7 @@ cmd_qtstatus (char *packet) stop_reason_rsp = (char *) tracing_stop_reason; /* The user visible error string in terror needs to be hex encoded. - We leave it as plain string in `tracepoint_stop_reason' to ease + We leave it as plain string in `tracing_stop_reason' to ease debugging. */ if (strncmp (stop_reason_rsp, "terror:", strlen ("terror:")) == 0) { @@ -3384,19 +3433,58 @@ cmd_qtstatus (char *packet) convert_int_to_ascii ((gdb_byte *) result_name, p, strlen (result_name)); } + /* If this was a forced stop, include any stop note that was supplied. */ + if (strcmp (stop_reason_rsp, "tstop") == 0) + { + stop_reason_rsp = alloca (strlen ("tstop:") + strlen (buf3) + 1); + strcpy (stop_reason_rsp, "tstop:"); + strcat (stop_reason_rsp, buf3); + } + sprintf (packet, "T%d;" "%s:%x;" "tframes:%x;tcreated:%x;" "tfree:%x;tsize:%s;" "circular:%d;" - "disconn:%d", + "disconn:%d;" + "starttime:%llx;stoptime:%llx;" + "username:%s:;notes:%s:", tracing ? 1 : 0, stop_reason_rsp, tracing_stop_tpnum, traceframe_count, traceframes_created, free_space (), phex_nz (trace_buffer_hi - trace_buffer_lo, 0), circular_trace_buffer, - disconnected_tracing); + disconnected_tracing, + tracing_start_time, tracing_stop_time, + buf1, buf2); +} + +static void +cmd_qtp (char *own_buf) +{ + ULONGEST num, addr; + struct tracepoint *tpoint; + char *packet = own_buf; + + packet += strlen ("qTP:"); + + packet = unpack_varlen_hex (packet, &num); + ++packet; /* skip a colon */ + packet = unpack_varlen_hex (packet, &addr); + + /* See if we already have this tracepoint. */ + tpoint = find_tracepoint (num, addr); + + if (!tpoint) + { + trace_debug ("Tracepoint error: tracepoint %d at 0x%s not found", + (int) num, paddress (addr)); + write_enn (own_buf); + return; + } + + sprintf (own_buf, "V%lx:%lx", tpoint->hit_count, tpoint->traceframe_usage); } /* State variables to help return all the tracepoint bits. */ @@ -3710,6 +3798,63 @@ cmd_bigqtbuffer (char *own_buf) write_enn (own_buf); } +static void +cmd_qtnotes (char *own_buf) +{ + size_t nbytes; + char *saved, *user, *notes, *stopnote; + char *packet = own_buf; + + packet += strlen ("QTNotes:"); + + while (*packet) + { + if (strncmp ("user:", packet, strlen ("user:")) == 0) + { + packet += strlen ("user:"); + saved = packet; + packet = strchr (packet, ';'); + nbytes = (packet - saved) / 2; + user = xmalloc (nbytes + 1); + nbytes = unhexify (user, saved, nbytes); + user[nbytes] = '\0'; + ++packet; /* skip the semicolon */ + trace_debug ("User is '%s'", user); + tracing_user_name = user; + } + else if (strncmp ("notes:", packet, strlen ("notes:")) == 0) + { + packet += strlen ("notes:"); + saved = packet; + packet = strchr (packet, ';'); + nbytes = (packet - saved) / 2; + notes = xmalloc (nbytes + 1); + nbytes = unhexify (notes, saved, nbytes); + notes[nbytes] = '\0'; + ++packet; /* skip the semicolon */ + trace_debug ("Notes is '%s'", notes); + tracing_notes = notes; + } + else if (strncmp ("tstop:", packet, strlen ("tstop:")) == 0) + { + packet += strlen ("tstop:"); + saved = packet; + packet = strchr (packet, ';'); + nbytes = (packet - saved) / 2; + stopnote = xmalloc (nbytes + 1); + nbytes = unhexify (stopnote, saved, nbytes); + stopnote[nbytes] = '\0'; + ++packet; /* skip the semicolon */ + trace_debug ("tstop note is '%s'", stopnote); + tracing_stop_note = stopnote; + } + else + break; + } + + write_ok (own_buf); +} + int handle_tracepoint_general_set (char *packet) { @@ -3774,6 +3919,11 @@ handle_tracepoint_general_set (char *packet) cmd_bigqtbuffer (packet); return 1; } + else if (strncmp ("QTNotes:", packet, strlen ("QTNotes:")) == 0) + { + cmd_qtnotes (packet); + return 1; + } return 0; } @@ -3786,6 +3936,11 @@ handle_tracepoint_query (char *packet) cmd_qtstatus (packet); return 1; } + else if (strncmp ("qTP:", packet, strlen ("qTP:")) == 0) + { + cmd_qtp (packet); + return 1; + } else if (strcmp ("qTfP", packet) == 0) { cmd_qtfp (packet); @@ -8049,8 +8204,12 @@ initialize_tracepoint_ftlib (void) #endif /* IN_PROCESS_AGENT */ +/* Return a timestamp, expressed as microseconds of the usual Unix + time. (As the result is a 64-bit number, it will not overflow any + time soon.) */ + static LONGEST -tsv_get_timestamp (void) +get_timestamp (void) { struct timeval tv; @@ -8074,7 +8233,7 @@ initialize_tracepoint (void) variable numbered 1, it will be renumbered.) */ create_trace_state_variable (1, 0); set_trace_state_variable_name (1, "trace_timestamp"); - set_trace_state_variable_getter (1, tsv_get_timestamp); + set_trace_state_variable_getter (1, get_timestamp); #ifdef IN_PROCESS_AGENT { |