[PATCH v3 11/15] Write tsv definition in CTF and read

Yao Qi
2013-03-09T03:49:24Z

This patch teaches GDB to write uploaded tsv to CTF, and also read
them out from CTF.

gdb:

2013-03-08 Yao Qi <yao@codesourcery.com>

* ctf.c (CTF_EVENT_ID_TSV_DEF): New macro.
(ctf_save_metadata_header): Define new type alias in
metadata.
(ctf_write_header): Define new event type "tsv_def".
(ctf_write_uploaded_tsv): Write TSV to CTF.
(ctf_read_tsv): New.
(ctf_open): Call ctf_read_tsv and
merge_uploaded_trace_state_variables.
* tracepoint.c (get_uploaded_tsv): Remove 'static'.
* tracepoint.h (get_uploaded_tsv): Declare.
---
gdb/ctf.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++---
gdb/tracepoint.c | 2 +-
gdb/tracepoint.h | 2 +
3 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/gdb/ctf.c b/gdb/ctf.c
index 7be9bb6..934ba10 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -37,8 +37,9 @@
2. Trace status. Event "status" is defined in metadata, which
includes all aspects of trace status.

- 3. Uploaded trace variables and tracepoints. Not implemented yet
- in CTF writer.
+ 3. Uploaded trace variables. Event "tsv_def" is defined in metata,
+ which is about all aspects of a uploaded trace variable.
+ Uploaded tracepoints. Not implemented yet in CTF writer.

4. Trace frames. Each trace frame is composed by several blocks
of different types ('R', 'M', 'V'). One trace frame is saved in
@@ -67,6 +68,7 @@
#define CTF_EVENT_ID_MEMORY 2
#define CTF_EVENT_ID_FRAME 3
#define CTF_EVENT_ID_STATUS 4
+#define CTF_EVENT_ID_TSV_DEF 5

/* The state kept while writing the CTF datastream file. */

@@ -228,6 +230,12 @@ ctf_save_metadata_header (struct trace_write_handler *handler)
ctf_save_write_metadata (handler,
"typealias integer { size = 32; align = 32;"
"signed = true; } := int32_t;\n");
+ ctf_save_write_metadata (handler,
+ "typealias integer { size = 64; align = 64;"
+ "signed = true; } := int64_t;\n");
+ ctf_save_write_metadata (handler,
+ "typealias string { encoding = ascii;"
+ " } := chars;\n");
ctf_save_write_metadata (handler, "\n");

ctf_save_write_metadata (handler, metadata_fmt,
@@ -352,6 +360,17 @@ ctf_write_header (struct trace_file_writer *self)
"\t};\n"
"};\n", CTF_EVENT_ID_FRAME);

+ ctf_save_write_metadata (&writer->tcs, "\n");
+ ctf_save_write_metadata (&writer->tcs,
+ "event {\n\tname = \"tsv_def\";\n"
+ "\tid = %u;\n\tfields := struct { \n"
+ "\t\tint64_t initial_value;\n"
+ "\t\tint32_t number;\n"
+ "\t\tint32_t builtin;\n"
+ "\t\tchars name;\n"
+ "\t};\n"
+ "};\n", CTF_EVENT_ID_TSV_DEF);
+
gdb_assert (writer->tcs.content_size == 0);
gdb_assert (writer->tcs.packet_start == 0);

@@ -429,8 +448,31 @@ static void
ctf_write_uploaded_tsv (struct trace_file_writer *self,
struct uploaded_tsv *tsv)
{
- /* It is not supported yet to write uploaded trace variables
- into CTF trace data. */
+ struct ctf_trace_file_writer *writer
+ = (struct ctf_trace_file_writer *) self;
+ int32_t int32;
+ int64_t int64;
+ unsigned int len;
+ const gdb_byte zero = 0;
+
+ /* Event Id. */
+ int32 = CTF_EVENT_ID_TSV_DEF;
+ ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
+
+ /* initial_value */
+ int64 = tsv->initial_value;
+ ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
+
+ /* number */
+ ctf_save_write_int32 (&writer->tcs, tsv->number);
+
+ /* builtin */
+ ctf_save_write_int32 (&writer->tcs, tsv->builtin);
+
+ /* name */
+ if (tsv->name != NULL)
+ ctf_save_write (&writer->tcs, tsv->name, strlen (tsv->name));
+ ctf_save_write (&writer->tcs, &zero, 1);
}

/* This is the implementation of trace_file_write_ops method
@@ -821,12 +863,56 @@ ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts)
SET_INT32_FIELD (event, scope, ts, circular_buffer);
}

+/* Read the events "tsv_def" one by one, extract its contents and fill
+ in the list UPLOADED_TSVS. */
+
+static void
+ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
+{
+ while (1)
+ {
+ struct bt_ctf_event *event;
+ const struct bt_definition *scope;
+ const struct bt_definition *def;
+ uint32_t event_id;
+ struct uploaded_tsv *utsv = NULL;
+
+ event = bt_ctf_iter_read_event (ctf_iter);
+ scope = bt_ctf_get_top_level_scope (event,
+ BT_STREAM_EVENT_HEADER);
+ event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
+ "id"));
+ if (event_id != CTF_EVENT_ID_TSV_DEF)
+ break;
+
+ scope = bt_ctf_get_top_level_scope (event,
+ BT_EVENT_FIELDS);
+
+ def = bt_ctf_get_field (event, scope, "number");
+ utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def),
+ uploaded_tsvs);
+
+ def = bt_ctf_get_field (event, scope, "builtin");
+ utsv->builtin = (int32_t) bt_ctf_get_int64 (def);
+ def = bt_ctf_get_field (event, scope, "initial_value");
+ utsv->initial_value = bt_ctf_get_int64 (def);
+
+ def = bt_ctf_get_field (event, scope, "name");
+ utsv->name = xstrdup (bt_ctf_get_string (def));
+
+ if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
+ break;
+ }
+
+}
+
static void
ctf_open (char *dirname, int from_tty)
{
struct bt_ctf_event *event;
uint32_t event_id;
const struct bt_definition *scope;
+ struct uploaded_tsv *uploaded_tsvs = NULL;

target_preopen (from_tty);
if (!dirname)
@@ -848,8 +934,9 @@ ctf_open (char *dirname, int from_tty)
gdb_assert (event_id == CTF_EVENT_ID_STATUS);
ctf_read_status (event, current_trace_status ());

- /* The third event is "frame". A new packet. */
gdb_assert (bt_iter_next (bt_ctf_get_iter (ctf_iter)) >= 0);
+ ctf_read_tsv (&uploaded_tsvs);
+
event = bt_ctf_iter_read_event (ctf_iter);
scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
@@ -860,6 +947,8 @@ ctf_open (char *dirname, int from_tty)

trace_dirname = xstrdup (dirname);
push_target (&ctf_ops);
+
+ merge_uploaded_trace_state_variables (&uploaded_tsvs);
}

static void
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 850adb9..3656767 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -3798,7 +3798,7 @@ free_uploaded_tps (struct uploaded_tp **utpp)
/* Given a number and address, return an uploaded tracepoint with that
number, creating if necessary. */

-static struct uploaded_tsv *
+struct uploaded_tsv *
get_uploaded_tsv (int num, struct uploaded_tsv **utsvp)
{
struct uploaded_tsv *utsv;
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index 8762d1c..765f455 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -378,6 +378,8 @@ extern void parse_tsv_definition (char *line, struct uploaded_tsv **utsvp);

extern struct uploaded_tp *get_uploaded_tp (int num, ULONGEST addr,
struct uploaded_tp **utpp);
+extern struct uploaded_tsv *get_uploaded_tsv (int num,
+ struct uploaded_tsv **utsvp);
extern struct tracepoint *create_tracepoint_from_upload (struct uploaded_tp *utp);
extern void merge_uploaded_tracepoints (struct uploaded_tp **utpp);
extern void merge_uploaded_trace_state_variables (struct uploaded_tsv **utsvp);
--
1.7.7.6