aboutsummaryrefslogtreecommitdiff
path: root/gdb/tracepoint.c
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>2010-03-29 23:45:06 +0000
committerStan Shebs <shebs@codesourcery.com>2010-03-29 23:45:06 +0000
commit409873ef5c8a7aefdf9fe2fbb83e87ade071be27 (patch)
treee888cd070ef3be76fddeeba7fa0cdf3dba847d0a /gdb/tracepoint.c
parent2aab228b95db7a8ae3864297c9596a359893f1ec (diff)
downloadfsf-binutils-gdb-409873ef5c8a7aefdf9fe2fbb83e87ade071be27.zip
fsf-binutils-gdb-409873ef5c8a7aefdf9fe2fbb83e87ade071be27.tar.gz
fsf-binutils-gdb-409873ef5c8a7aefdf9fe2fbb83e87ade071be27.tar.bz2
2010-03-29 Stan Shebs <stan@codesourcery.com>
* tracepoint.h (struct uploaded_string): New struct. (struct uploaded_tp): New fields for source strings. * breakpoint.c (this_utp, next_cmd): New globals. (read_uploaded_action): New function. (create_tracepoint_from_upload): Fill in more parts of a tracepoint. * tracepoint.c (encode_source_string): New function. (trace_save): Write out source strings, fix error checks. (parse_tracepoint_definition): Add source string parsing. * remote.c (PACKET_TracepointSource): New packet type. (remote_download_command_source): New function. (remote_download_tracepoint): Download source pieces also. (_initialize_remote): Add packet config command. * gdb.texinfo (Tracepoint Packets): Describe QTDPsrc. (General Query Packets): Describe TracepointSource.
Diffstat (limited to 'gdb/tracepoint.c')
-rw-r--r--gdb/tracepoint.c100
1 files changed, 89 insertions, 11 deletions
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 44b8c2b..07e8541 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -2446,6 +2446,25 @@ trace_dump_command (char *args, int from_tty)
discard_cleanups (old_cleanups);
}
+/* Encode a piece of a tracepoint's source-level definition in a form
+ that is suitable for both protocol and saving in files. */
+/* This version does not do multiple encodes for long strings; it should
+ return an offset to the next piece to encode. FIXME */
+
+extern int
+encode_source_string (int tpnum, ULONGEST addr,
+ char *srctype, char *src, char *buf, int buf_size)
+{
+ if (80 + strlen (srctype) > buf_size)
+ error (_("Buffer too small for source encoding"));
+ sprintf (buf, "%x:%s:%s:%x:%x:",
+ tpnum, phex_nz (addr, sizeof (addr)), srctype, 0, (int) strlen (src));
+ if (strlen (buf) + strlen (src) * 2 >= buf_size)
+ error (_("Source string too long for buffer"));
+ bin2hex (src, buf + strlen (buf), 0);
+ return -1;
+}
+
extern int trace_regblock_size;
/* Save tracepoint data to file named FILENAME. If TARGET_DOES_SAVE is
@@ -2463,6 +2482,7 @@ trace_save (const char *filename, int target_does_save)
struct uploaded_tp *uploaded_tps = NULL, *utp;
struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
int a;
+ struct uploaded_string *cmd;
LONGEST gotten = 0;
ULONGEST offset = 0;
#define MAX_TRACE_UPLOAD 2000
@@ -2497,7 +2517,7 @@ trace_save (const char *filename, int target_does_save)
binary file, plus a hint as what this file is, and a version
number in case of future needs. */
written = fwrite ("\x7fTRACE0\n", 8, 1, fp);
- if (written < 8)
+ if (written < 1)
perror_with_name (pathname);
/* Write descriptive info. */
@@ -2578,6 +2598,24 @@ trace_save (const char *filename, int target_does_save)
fprintf (fp, "tp S%x:%s:%s\n",
utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
utp->step_actions[a]);
+ if (utp->at_string)
+ {
+ encode_source_string (utp->number, utp->addr,
+ "at", utp->at_string, buf, MAX_TRACE_UPLOAD);
+ fprintf (fp, "tp Z%s\n", buf);
+ }
+ if (utp->cond_string)
+ {
+ encode_source_string (utp->number, utp->addr,
+ "cond", utp->cond_string, buf, MAX_TRACE_UPLOAD);
+ fprintf (fp, "tp Z%s\n", buf);
+ }
+ for (cmd = utp->cmd_strings; cmd; cmd = cmd->next)
+ {
+ encode_source_string (utp->number, utp->addr, "cmd", cmd->str,
+ buf, MAX_TRACE_UPLOAD);
+ fprintf (fp, "tp Z%s\n", buf);
+ }
}
free_uploaded_tps (&uploaded_tps);
@@ -2597,14 +2635,14 @@ trace_save (const char *filename, int target_does_save)
if (gotten == 0)
break;
written = fwrite (buf, gotten, 1, fp);
- if (written < gotten)
+ if (written < 1)
perror_with_name (pathname);
offset += gotten;
}
- /* Mark the end of trace data. */
+ /* Mark the end of trace data. (We know that gotten is 0 at this point.) */
written = fwrite (&gotten, 4, 1, fp);
- if (written < 4)
+ if (written < 1)
perror_with_name (pathname);
do_cleanups (cleanup);
@@ -3266,18 +3304,18 @@ Status line: '%s'\n"), p, line);
}
}
-/* Given a line of text defining a tracepoint or tracepoint action, parse
- it into an "uploaded tracepoint". */
+/* Given a line of text defining a part of a tracepoint, parse it into
+ an "uploaded tracepoint". */
void
parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
{
char *p;
char piece;
- ULONGEST num, addr, step, pass, orig_size, xlen;
- int enabled, i;
+ ULONGEST num, addr, step, pass, orig_size, xlen, start;
+ int enabled, i, end;
enum bptype type;
- char *cond;
+ char *cond, *srctype, *src, *buf;
struct uploaded_tp *utp = NULL;
p = line;
@@ -3318,7 +3356,7 @@ parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
p += 2 * xlen;
}
else
- warning ("Unrecognized char '%c' in tracepoint definition, skipping rest", *p);
+ warning (_("Unrecognized char '%c' in tracepoint definition, skipping rest"), *p);
}
utp = get_uploaded_tp (num, addr, utpp);
utp->type = type;
@@ -3337,9 +3375,49 @@ parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
utp = get_uploaded_tp (num, addr, utpp);
utp->step_actions[utp->num_step_actions++] = xstrdup (p);
}
+ else if (piece == 'Z')
+ {
+ /* Parse a chunk of source form definition. */
+ utp = get_uploaded_tp (num, addr, utpp);
+ srctype = p;
+ p = strchr (p, ':');
+ p++; /* skip a colon */
+ p = unpack_varlen_hex (p, &start);
+ p++; /* skip a colon */
+ p = unpack_varlen_hex (p, &xlen);
+ p++; /* skip a colon */
+
+ buf = alloca (strlen (line));
+
+ end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
+ buf[end] = '\0';
+
+ if (strncmp (srctype, "at:", strlen ("at:")) == 0)
+ utp->at_string = xstrdup (buf);
+ else if (strncmp (srctype, "cond:", strlen ("cond:")) == 0)
+ utp->cond_string = xstrdup (buf);
+ else if (strncmp (srctype, "cmd:", strlen ("cmd:")) == 0)
+ {
+ /* FIXME consider using a vector? */
+ struct uploaded_string *last, *newlast;
+ newlast = (struct uploaded_string *) xmalloc (sizeof (struct uploaded_string));
+ newlast->str = xstrdup (buf);
+ newlast->next = NULL;
+ if (utp->cmd_strings)
+ {
+ for (last = utp->cmd_strings; last->next; last = last->next)
+ ;
+ last->next = newlast;
+ }
+ else
+ utp->cmd_strings = newlast;
+ }
+ }
else
{
- error ("Invalid tracepoint piece");
+ /* Don't error out, the target might be sending us optional
+ info that we don't care about. */
+ warning (_("Unrecognized tracepoint piece '%c', ignoring"), piece);
}
}