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.
This commit is contained in:
Stan Shebs 2011-11-02 23:44:21 +00:00
parent 39f4f51d8b
commit 3065dfb6b4
19 changed files with 349 additions and 6 deletions

View file

@ -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