aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/tracepoint.c
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>2011-11-02 23:44:21 +0000
committerStan Shebs <shebs@codesourcery.com>2011-11-02 23:44:21 +0000
commit3065dfb6b4e2e605b3601c5f71fa25de5dd4970e (patch)
treeac641720c021164a841a9c669e88e599134191e6 /gdb/gdbserver/tracepoint.c
parent39f4f51d8bf1d516a5cca652a1d9efe8f3ef9863 (diff)
downloadfsf-binutils-gdb-3065dfb6b4e2e605b3601c5f71fa25de5dd4970e.zip
fsf-binutils-gdb-3065dfb6b4e2e605b3601c5f71fa25de5dd4970e.tar.gz
fsf-binutils-gdb-3065dfb6b4e2e605b3601c5f71fa25de5dd4970e.tar.bz2
2011-11-02 Stan Shebs <stan@codesourcery.com>
String collection for tracepoints. * NEWS: Mention string collection. * common/ax.def (tracenz): New bytecode. * ax-gdb.h (trace_string_kludge): Declare. * ax-gdb.c: Include valprint.h and c-lang.h. (trace_string_kludge): New global. (gen_traced_pop): Add string case. (agent_command): Add string case. * tracepoint.h (decode_agent_options): Declare. * tracepoint.c: Include cli-utils.h. (decode_agent_options): New function. (validate_actionline): Call it. (encode_actions_1): Ditto. * target.h (struct target_ops): New method to_supports_string_tracing. (target_supports_string_tracing): New macro. * target.c (update_current_target): Add to_supports_string_tracing. * remote.c (struct remote_state): New field string_tracing. (remote_string_tracing_feature): New function. (remote_protocol_features): New feature tracenz. (remote_supports_string_tracing): New function. (init_remote_ops): Set to_supports_string_tracing. * tracepoint.c (agent_mem_read_string): New function. (eval_agent_expr): Call it for tracenz. * server.c (handle_query): Report support for tracenz. * gdb.texinfo (Tracepoint Action Lists): Document collect/s. (General Query Packets): Describe tracenz feature. * agentexpr.texi (Bytecode Descriptions): Describe tracenz. * gdb.trace/collection.c: Add code using strings. * gdb.trace/collection.exp: Add tests of string collection.
Diffstat (limited to 'gdb/gdbserver/tracepoint.c')
-rw-r--r--gdb/gdbserver/tracepoint.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index eaa54f5..139e30e 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -1209,6 +1209,9 @@ static enum eval_result_type eval_agent_expr (struct tracepoint_hit_ctx *ctx,
static int agent_mem_read (struct traceframe *tframe,
unsigned char *to, CORE_ADDR from, ULONGEST len);
+static int agent_mem_read_string (struct traceframe *tframe,
+ unsigned char *to, CORE_ADDR from,
+ ULONGEST len);
static int agent_tsv_read (struct traceframe *tframe, int n);
#ifndef IN_PROCESS_AGENT
@@ -4644,6 +4647,13 @@ eval_agent_expr (struct tracepoint_hit_ctx *ctx,
agent_tsv_read (tframe, arg);
break;
+ case gdb_agent_op_tracenz:
+ agent_mem_read_string (tframe, NULL, (CORE_ADDR) stack[--sp],
+ (ULONGEST) top);
+ if (--sp >= 0)
+ top = stack[sp];
+ break;
+
/* GDB never (currently) generates any of these ops. */
case gdb_agent_op_float:
case gdb_agent_op_ref_float:
@@ -4727,6 +4737,66 @@ agent_mem_read (struct traceframe *tframe,
return 0;
}
+static int
+agent_mem_read_string (struct traceframe *tframe,
+ unsigned char *to, CORE_ADDR from, ULONGEST len)
+{
+ unsigned char *buf, *mspace;
+ ULONGEST remaining = len;
+ unsigned short blocklen, i;
+
+ /* To save a bit of space, block lengths are 16-bit, so break large
+ requests into multiple blocks. Bordering on overkill for strings,
+ but it could happen that someone specifies a large max length. */
+ while (remaining > 0)
+ {
+ size_t sp;
+
+ blocklen = (remaining > 65535 ? 65535 : remaining);
+ /* We want working space to accumulate nonzero bytes, since
+ traceframes must have a predecided size (otherwise it gets
+ harder to wrap correctly for the circular case, etc). */
+ buf = (unsigned char *) xmalloc (blocklen + 1);
+ for (i = 0; i < blocklen; ++i)
+ {
+ /* Read the string one byte at a time, in case the string is
+ at the end of a valid memory area - we don't want a
+ correctly-terminated string to engender segvio
+ complaints. */
+ read_inferior_memory (from + i, buf + i, 1);
+
+ if (buf[i] == '\0')
+ {
+ blocklen = i + 1;
+ /* Make sure outer loop stops now too. */
+ remaining = blocklen;
+ break;
+ }
+ }
+ sp = 1 + sizeof (from) + sizeof (blocklen) + blocklen;
+ mspace = add_traceframe_block (tframe, sp);
+ if (mspace == NULL)
+ {
+ xfree (buf);
+ return 1;
+ }
+ /* Identify block as a memory block. */
+ *mspace = 'M';
+ ++mspace;
+ /* Record address and size. */
+ memcpy ((void *) mspace, (void *) &from, sizeof (from));
+ mspace += sizeof (from);
+ memcpy ((void *) mspace, (void *) &blocklen, sizeof (blocklen));
+ mspace += sizeof (blocklen);
+ /* Copy the string contents. */
+ memcpy ((void *) mspace, (void *) buf, blocklen);
+ remaining -= blocklen;
+ from += blocklen;
+ xfree (buf);
+ }
+ return 0;
+}
+
/* Record the value of a trace state variable. */
static int