From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1893 invoked by alias); 9 Mar 2013 03:49:37 -0000 Received: (qmail 1757 invoked by uid 22791); 9 Mar 2013 03:49:35 -0000 X-SWARE-Spam-Status: No, hits=-4.6 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 09 Mar 2013 03:49:24 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1UEAmF-0003cO-QU from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Fri, 08 Mar 2013 19:48:55 -0800 Received: from SVR-ORW-FEM-03.mgc.mentorg.com ([147.34.97.39]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Fri, 8 Mar 2013 19:48:55 -0800 Received: from qiyao.dyndns.dyndns.org (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.1.289.1; Fri, 8 Mar 2013 19:48:54 -0800 From: Yao Qi To: Subject: [PATCH v3 06/15] Write status to CTF and read. Date: Sat, 09 Mar 2013 03:49:00 -0000 Message-ID: <1362800844-27940-7-git-send-email-yao@codesourcery.com> In-Reply-To: <1362800844-27940-1-git-send-email-yao@codesourcery.com> References: <1362800844-27940-1-git-send-email-yao@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2013-03/txt/msg00400.txt.bz2 This patch teaches GDB to write trace status to CTF and also read trace status from CTF trace file. gdb: 2013-03-08 Yao Qi * ctf.c (CTF_EVENT_ID_STATUS, ctf_save_write_int32): New macros. (ctf_save_metadata_header): Define new type alias in metadata. (ctf_write_header): Start a new faked packet for trace status. (ctf_write_status): Write trace status to CTF. (ctf_write_definition_end): End the faked packet. (start_pos): New variable. (SET_INT32_FIELD): New macro. (ctf_read_status): New. (ctf_open): Skip the first faked packet and assert on some event types. (ctf_trace_find): Set the iterator to the beginning of packet including trace frames, instead of the first packet. (ctf_get_trace_status): New. (init_ctf_ops): Install ctf_get_trace_status to field 'to_get_trace_status'. --- gdb/ctf.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 120 insertions(+), 7 deletions(-) diff --git a/gdb/ctf.c b/gdb/ctf.c index ec35b17..7be9bb6 100644 --- a/gdb/ctf.c +++ b/gdb/ctf.c @@ -34,7 +34,8 @@ 1. The length (in bytes) of register cache. Event "register" will be defined in metadata, which includes the length. - 2. Trace status. Not implemented yet in CTF writer. + 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. @@ -65,6 +66,7 @@ #define CTF_EVENT_ID_TSV 1 #define CTF_EVENT_ID_MEMORY 2 #define CTF_EVENT_ID_FRAME 3 +#define CTF_EVENT_ID_STATUS 4 /* The state kept while writing the CTF datastream file. */ @@ -119,6 +121,12 @@ ctf_save_write (struct trace_write_handler *handler, #define ctf_save_write_uint32(HANDLER, U32) \ ctf_save_write (HANDLER, (gdb_byte *) &U32, 4) +/* Write a signed 32-bit integer to datastream file represented by + HANDLER. */ + +#define ctf_save_write_int32(HANDLER, INT32) \ + ctf_save_write (HANDLER, (gdb_byte *) &INT32, 4) + /* Set datastream file position. Update HANDLER->content_size if WHENCE is SEEK_CUR. */ @@ -217,6 +225,9 @@ ctf_save_metadata_header (struct trace_write_handler *handler) "typealias integer { size = 64; align = 64;" "signed = false; base = hex;}" " := uint64_t;\n"); + ctf_save_write_metadata (handler, + "typealias integer { size = 32; align = 32;" + "signed = true; } := int32_t;\n"); ctf_save_write_metadata (handler, "\n"); ctf_save_write_metadata (handler, metadata_fmt, @@ -343,6 +354,9 @@ ctf_write_header (struct trace_file_writer *self) gdb_assert (writer->tcs.content_size == 0); gdb_assert (writer->tcs.packet_start == 0); + + /* Create a new packet to contain this event. */ + self->ops->frame_ops->start (self, 0); } /* This is the implementation of trace_file_write_ops method @@ -373,8 +387,39 @@ static void ctf_write_status (struct trace_file_writer *self, struct trace_status *ts) { - /* It is not supported yet to write trace status into CTF trace - data. */ + struct ctf_trace_file_writer *writer + = (struct ctf_trace_file_writer *) self; + uint32_t id; + int32_t int32; + + ctf_save_write_metadata (&writer->tcs, "\n"); + ctf_save_write_metadata (&writer->tcs, + "event {\n\tname = \"status\";\n\tid = %u;\n" + "\tfields := struct { \n" + "\t\tint32_t stop_reason;\n" + "\t\tint32_t stopping_tracepoint;\n" + "\t\tint32_t traceframe_count;\n" + "\t\tint32_t traceframes_created;\n" + "\t\tint32_t buffer_free;\n" + "\t\tint32_t buffer_size;\n" + "\t\tint32_t disconnected_tracing;\n" + "\t\tint32_t circular_buffer;\n" + "\t};\n" + "};\n", + CTF_EVENT_ID_STATUS); + + id = CTF_EVENT_ID_STATUS; + /* Event Id. */ + ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4); + + ctf_save_write_int32 (&writer->tcs, ts->stop_reason); + ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint); + ctf_save_write_int32 (&writer->tcs, ts->traceframe_count); + ctf_save_write_int32 (&writer->tcs, ts->traceframes_created); + ctf_save_write_int32 (&writer->tcs, ts->buffer_free); + ctf_save_write_int32 (&writer->tcs, ts->buffer_size); + ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing); + ctf_save_write_int32 (&writer->tcs, ts->circular_buffer); } /* This is the implementation of trace_file_write_ops method @@ -405,7 +450,10 @@ ctf_write_uploaded_tp (struct trace_file_writer *self, static void ctf_write_definition_end (struct trace_file_writer *self) { - /* Nothing to do for CTF. */ + struct ctf_trace_file_writer *writer + = (struct ctf_trace_file_writer *) self; + + self->ops->frame_ops->end (self); } /* The minimal file size of data stream. It is required by @@ -661,6 +709,9 @@ ctf_trace_file_writer_new (void) /* The struct pointer for current CTF directory. */ static struct bt_context *ctx = NULL; static struct bt_ctf_iter *ctf_iter = NULL; +/* The position of the first packet containing trace frame. */ +struct bt_iter_pos *start_pos; + /* The name of CTF directory. */ static char *trace_dirname; @@ -747,15 +798,66 @@ ctf_open_dir (char *dirname) } +#define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD) \ + VAR->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field (EVENT, \ + SCOPE, \ + #FIELD)) + +/* EVENT is the "status" event and TS is filled in. */ + +static void +ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts) +{ + const struct bt_definition *scope + = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS); + + SET_INT32_FIELD (event, scope, ts, stop_reason); + SET_INT32_FIELD (event, scope, ts, stopping_tracepoint); + SET_INT32_FIELD (event, scope, ts, traceframe_count); + SET_INT32_FIELD (event, scope, ts, traceframes_created); + SET_INT32_FIELD (event, scope, ts, buffer_free); + SET_INT32_FIELD (event, scope, ts, buffer_size); + SET_INT32_FIELD (event, scope, ts, disconnected_tracing); + SET_INT32_FIELD (event, scope, ts, circular_buffer); +} + static void ctf_open (char *dirname, int from_tty) { + struct bt_ctf_event *event; + uint32_t event_id; + const struct bt_definition *scope; + target_preopen (from_tty); if (!dirname) error (_("No CTF directory specified.")); ctf_open_dir (dirname); + /* Skip the first packet which about the trace status. The first + event is "frame". */ + 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")); + gdb_assert (event_id == CTF_EVENT_ID_FRAME); + /* The second event is "status". */ + gdb_assert (bt_iter_next (bt_ctf_get_iter (ctf_iter)) >= 0); + 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")); + 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); + 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")); + gdb_assert (event_id == CTF_EVENT_ID_FRAME); + + start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); + gdb_assert (start_pos->type == BT_SEEK_RESTORE); + trace_dirname = xstrdup (dirname); push_target (&ctf_ops); } @@ -1176,9 +1278,8 @@ ctf_trace_find (enum trace_find_type type, int num, return -1; } - /* Set iterator back to the beginning. */ - pos.type = BT_SEEK_BEGIN; - bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), &pos); + /* Set iterator back to the start. */ + bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos); while (1) { @@ -1347,6 +1448,17 @@ ctf_traceframe_info (void) return info; } +/* The trace status for a file is that tracing can never be run. */ + +static int +ctf_get_trace_status (struct trace_status *ts) +{ + /* Other bits of trace status were collected as part of opening the + trace files, so nothing to do here. */ + + return -1; +} + static void init_ctf_ops (void) { @@ -1359,6 +1471,7 @@ Specify the filename of the CTF directory."; ctf_ops.to_fetch_registers = ctf_fetch_registers; ctf_ops.to_xfer_partial = ctf_xfer_partial; ctf_ops.to_files_info = ctf_files_info; + ctf_ops.to_get_trace_status = ctf_get_trace_status; ctf_ops.to_trace_find = ctf_trace_find; ctf_ops.to_get_trace_state_variable_value = ctf_get_trace_state_variable_value; -- 1.7.7.6