From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1262 invoked by alias); 9 Mar 2013 03:49:24 -0000 Received: (qmail 1204 invoked by uid 22791); 9 Mar 2013 03:49:22 -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:12 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1UEAmV-0003eZ-A7 from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Fri, 08 Mar 2013 19:49:11 -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:49:11 -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:49:10 -0800 From: Yao Qi To: Subject: [PATCH v3 12/15] Write tracepoint definition in CTF and read. Date: Sat, 09 Mar 2013 03:49:00 -0000 Message-ID: <1362800844-27940-13-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/msg00405.txt.bz2 This patch teaches GDB to write uploaded tracepoints to CTF, and also read them out from CTF. gdb: 2013-03-08 Yao Qi * ctf.c (CTF_EVENT_ID_TP_DEF): New macro. ctf_write_header): Define event type "tp_def" in metadata. (ctf_write_uploaded_tp): Write tracepoint definition to CTF. (SET_ARRAY_FIELD, SET_STRING_FIELD): New macros. (ctf_read_tp): New. (ctf_open): Call ctf_read_tp. Adjust the event id checking. Call merge_uploaded_tracepoints. --- gdb/ctf.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 212 insertions(+), 6 deletions(-) diff --git a/gdb/ctf.c b/gdb/ctf.c index 934ba10..e46b183 100644 --- a/gdb/ctf.c +++ b/gdb/ctf.c @@ -39,7 +39,10 @@ 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. + Uploaded tracepoints. Event "tp_def" is defined in meta, which + is about all aspects of a uploaded tracepoint. Note that the + "sequence" (a CTF type, which is a dynamically-sized array.) is + used for "actions" "step_actions" and "cmd_strings". 4. Trace frames. Each trace frame is composed by several blocks of different types ('R', 'M', 'V'). One trace frame is saved in @@ -69,6 +72,7 @@ #define CTF_EVENT_ID_FRAME 3 #define CTF_EVENT_ID_STATUS 4 #define CTF_EVENT_ID_TSV_DEF 5 +#define CTF_EVENT_ID_TP_DEF 6 /* The state kept while writing the CTF datastream file. */ @@ -371,6 +375,34 @@ ctf_write_header (struct trace_file_writer *self) "\t};\n" "};\n", CTF_EVENT_ID_TSV_DEF); + ctf_save_write_metadata (&writer->tcs, "\n"); + ctf_save_write_metadata (&writer->tcs, + "event {\n\tname = \"tp_def\";\n" + "\tid = %u;\n\tfields := struct { \n" + "\t\tuint64_t addr;\n" + "\t\tuint64_t traceframe_usage;\n" + "\t\tint32_t number;\n" + "\t\tint32_t enabled;\n" + "\t\tint32_t step;\n" + "\t\tint32_t pass;\n" + "\t\tint32_t hit_count;\n" + "\t\tint32_t type;\n" + "\t\tchars cond;\n" + + "\t\tuint32_t action_num;\n" + "\t\tchars actions[action_num];\n" + + "\t\tuint32_t step_action_num;\n" + "\t\tchars step_actions[step_action_num];\n" + + "\t\tchars at_string;\n" + "\t\tchars cond_string;\n" + + "\t\tuint32_t cmd_num;\n" + "\t\tchars cmd_strings[cmd_num];\n" + "\t};\n" + "};\n", CTF_EVENT_ID_TP_DEF); + gdb_assert (writer->tcs.content_size == 0); gdb_assert (writer->tcs.packet_start == 0); @@ -482,8 +514,81 @@ static void ctf_write_uploaded_tp (struct trace_file_writer *self, struct uploaded_tp *tp) { - /* It is not supported yet to write uploaded tracepoints - into CTF trace data. */ + struct ctf_trace_file_writer *writer + = (struct ctf_trace_file_writer *) self; + int32_t int32; + int64_t int64; + uint32_t u32; + const gdb_byte zero = 0; + int a; + char *act; + + /* Event Id. */ + int32 = CTF_EVENT_ID_TP_DEF; + ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4); + + /* address */ + int64 = tp->addr; + ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8); + + /* traceframe_usage */ + int64 = tp->traceframe_usage; + ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8); + + /* number */ + ctf_save_write_int32 (&writer->tcs, tp->number); + + /* enabled */ + ctf_save_write_int32 (&writer->tcs, tp->enabled); + + /* step */ + ctf_save_write_int32 (&writer->tcs, tp->step); + + /* pass */ + ctf_save_write_int32 (&writer->tcs, tp->pass); + + /* hit_count */ + ctf_save_write_int32 (&writer->tcs, tp->hit_count); + + /* type */ + ctf_save_write_int32 (&writer->tcs, tp->type); + + /* condition */ + if (tp->cond != NULL) + ctf_save_write (&writer->tcs, tp->cond, strlen (tp->cond)); + ctf_save_write (&writer->tcs, &zero, 1); + + /* actions */ + u32 = VEC_length (char_ptr, tp->actions); + ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4); + for (a = 0; VEC_iterate (char_ptr, tp->actions, a, act); ++a) + ctf_save_write (&writer->tcs, act, strlen (act) + 1); + + + /* step_actions */ + u32 = VEC_length (char_ptr, tp->step_actions); + ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4); + for (a = 0; VEC_iterate (char_ptr, tp->step_actions, a, act); ++a) + ctf_save_write (&writer->tcs, act, strlen (act) + 1); + + /* at_string */ + if (tp->at_string != NULL) + ctf_save_write (&writer->tcs, tp->at_string, + strlen (tp->at_string)); + ctf_save_write (&writer->tcs, &zero, 1); + + /* cond_string */ + if (tp->cond_string != NULL) + ctf_save_write (&writer->tcs, tp->cond_string, + strlen (tp->cond_string)); + ctf_save_write (&writer->tcs, &zero, 1); + + /* cmd_strings */ + u32 = VEC_length (char_ptr, tp->cmd_strings); + ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4); + for (a = 0; VEC_iterate (char_ptr, tp->cmd_strings, a, act); ++a) + ctf_save_write (&writer->tcs, act, strlen (act) + 1); + } /* This is the implementation of trace_file_write_ops method @@ -906,6 +1011,96 @@ ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs) } +#define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY) \ + do \ + { \ + uint32_t u32, i; \ + const struct bt_definition *def; \ + \ + u32 = (uint32_t ) bt_ctf_get_uint64 (bt_ctf_get_field (EVENT, \ + SCOPE, \ + #NUM)); \ + def = bt_ctf_get_field (event, scope, #ARRAY); \ + for (i = 0; i < u32; i++) \ + { \ + const struct bt_definition *element \ + = bt_ctf_get_index (event, def, i); \ + \ + VEC_safe_push (char_ptr, VAR->ARRAY, \ + xstrdup (bt_ctf_get_string (element))); \ + } \ + } \ + while (0) + +#define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD) \ + do \ + { \ + const char *p = bt_ctf_get_string (bt_ctf_get_field (EVENT, \ + SCOPE, \ + #FIELD)); \ + \ + if (strlen (p) > 0) \ + VAR->FIELD = xstrdup (p); \ + else \ + VAR->FIELD = NULL; \ + } \ + while (0) + +/* Read the events "tp_def" one by one, extract its contents and fill + in the list UPLOADED_TPS. */ + +static void +ctf_read_tp (struct uploaded_tp **uploaded_tps) +{ + while (1) + { + struct bt_ctf_event *event; + const struct bt_definition *scope; + uint32_t u32; + int32_t int32; + uint64_t u64; + struct uploaded_tp *utp = NULL; + + event = bt_ctf_iter_read_event (ctf_iter); + scope = bt_ctf_get_top_level_scope (event, + BT_STREAM_EVENT_HEADER); + u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, + "id")); + if (u32 != CTF_EVENT_ID_TP_DEF) + break; + + scope = bt_ctf_get_top_level_scope (event, + BT_EVENT_FIELDS); + int32 = (int32_t ) bt_ctf_get_int64 (bt_ctf_get_field (event, + scope, + "number")); + u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, + "addr")); + utp = get_uploaded_tp (int32, u64, uploaded_tps); + + SET_INT32_FIELD (event, scope, utp, enabled); + SET_INT32_FIELD (event, scope, utp, step); + SET_INT32_FIELD (event, scope, utp, pass); + SET_INT32_FIELD (event, scope, utp, hit_count); + SET_INT32_FIELD (event, scope, utp, type); + + /* Read 'cmd_strings'. */ + SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings); + /* Read 'actions'. */ + SET_ARRAY_FIELD (event, scope, utp, action_num, actions); + /* Read 'step_actions'. */ + SET_ARRAY_FIELD (event, scope, utp, step_action_num, + step_actions); + + SET_STRING_FIELD(event, scope, utp, at_string); + SET_STRING_FIELD(event, scope, utp, cond_string); + + if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) + break; + } +} + + static void ctf_open (char *dirname, int from_tty) { @@ -913,6 +1108,7 @@ ctf_open (char *dirname, int from_tty) uint32_t event_id; const struct bt_definition *scope; struct uploaded_tsv *uploaded_tsvs = NULL; + struct uploaded_tp *uploaded_tps = NULL; target_preopen (from_tty); if (!dirname) @@ -937,10 +1133,19 @@ ctf_open (char *dirname, int from_tty) gdb_assert (bt_iter_next (bt_ctf_get_iter (ctf_iter)) >= 0); ctf_read_tsv (&uploaded_tsvs); + ctf_read_tp (&uploaded_tps); + 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); + /* EVENT can be NULL if we've already gone to the end of stream of + events. */ + if (event != NULL) + { + 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); @@ -949,6 +1154,7 @@ ctf_open (char *dirname, int from_tty) push_target (&ctf_ops); merge_uploaded_trace_state_variables (&uploaded_tsvs); + merge_uploaded_tracepoints (&uploaded_tps); } static void -- 1.7.7.6