[lttng-dev] Reading CTF trace using Babeltrace API
Jérémie Galarneau
jeremie.galarneau at efficios.com
Tue Oct 8 14:52:38 EDT 2013
On Mon, Oct 7, 2013 at 11:54 AM, Salman Rafiq
<salman.rafiq at esk.fraunhofer.de> wrote:
> Hi Jérémie,
>
> Thanks for your prompt reply.
>
>
> Just to add a little to your answer:
>
> In order to get the event "id" field, we need to call another function as well.
> Since the "id" field is declared as an enumerated data type (uint16_t for large header and uint5_t for compact).
> For example, to read the event id, it works only by calling bt_ctf_get_enum_int(id_field), otherwise it returns 0.
>
Absolutely. I was testing this on a sample trace that didn't have the
same event_header declaration. But for traces currently generated by
the tracers, this is correct. Thanks for clarifying.
> Slight modification to the code sample did the job:
>
> while ((ctf_event = bt_ctf_iter_read_event(iter))) {
>
> const struct bt_definition *stream_event_header_scope =
> bt_ctf_get_top_level_scope(
> ctf_event, BT_STREAM_EVENT_HEADER);
> const struct bt_definition *id_field =
> bt_ctf_get_field(
> ctf_event, stream_event_header_scope, "id");
>
> printf("id = %" PRIu64 "\n", bt_ctf_get_uint64(bt_ctf_get_enum_int(id_field))); // change here!!!
>
>
>
> But I am getting strange behavior only for the "sched_switch" event.
> Each time I read it, it returns 31 in case the header is compact (31 events max) and 65535 when the header is large instead of the correct value.
>
> For all other "id's" of the event, it returns correct value :-s
>
> I am unable to figure out the reason. Please let me know, if you have any information in this regard.
The problem is that the "id" fields in both struct
event_header_compact and event_header_large acts as a variant's tag
enumeration.
For instance, if we take a look at the event_header_compact structure,
struct event_header_compact {
enum : uint5_t { compact = 0 ... 30, extended = 31 } id;
variant <id> {
struct {
uint27_clock_monotonic_t timestamp;
} compact;
struct {
uint32_t id;
uint64_clock_monotonic_t timestamp;
} extended;
} v;
} align(8);
The "enum id" field will indicate the event's id if it has a value of
[0, 30]. It also indicates that the "compact" structure is selected in
the variant that follows. If id == 31, the "extended" structure is
selected, which means that you should retrieve the "id" field's value
from that structure.
Since code is worth a thousand words, here's a more complete code
sample to read the id fields.
while ((ctf_event = bt_ctf_iter_read_event(iter))) {
uint64_t event_id = 0;
const struct bt_definition *stream_event_header_scope =
bt_ctf_get_top_level_scope(
ctf_event, BT_STREAM_EVENT_HEADER);
const struct bt_definition *id_definition =
bt_ctf_get_field(ctf_event, stream_event_header_scope,
"id");
const struct bt_definition *v_definition =
bt_ctf_get_field(ctf_event, stream_event_header_scope,
"v");
/* "id may be an enum, get the underlying integer if it's the case */
if (id_definition &&
bt_ctf_field_type(bt_ctf_get_decl_from_def(id_definition)) ==
CTF_TYPE_ENUM) {
id_definition = bt_ctf_get_enum_int(id_definition);
}
/* Check if there is a "v" field and if it contains an "id" field */
if (v_definition &&
bt_ctf_field_type(bt_ctf_get_decl_from_def(v_definition)) ==
CTF_TYPE_STRUCT) {
struct bt_definition const * const *list = NULL;
unsigned int count = 0;
unsigned int i;
ret = bt_ctf_get_field_list(ctf_event, v_definition,
&list, &count);
if (ret) {
goto end;
}
for (i = 0; i < count; i++) {
const char *name = bt_ctf_field_name(list[i]);
if (strcmp("id", name) == 0) {
id_definition = list[i];
break;
}
}
}
if (id_definition &&
bt_ctf_field_type(bt_ctf_get_decl_from_def(id_definition)) ==
CTF_TYPE_INTEGER) {
event_id = bt_ctf_get_uint64(id_definition);
}
printf("id = %" PRIu64 "\n", event_id);
}
Regards,
Jérémie
> Thanks a lot!
>
> Regards,
> Salman
>
> --
> Salman Rafiq
> Geschäftsfeld Industrial Communication
> Fraunhofer-Institut für Eingebettete Systeme und Kommunikationstechnik ESK
>
> Hansastraße 32 | 80686 München
> Telefon, Fax: +49 89 547088-356 | +49 89 547088-221
> E-Mail: salman.rafiq at esk.fraunhofer.de
>
> Internet:
> http://www.esk.fraunhofer.de
> http://www.twitter.com/FraunhoferESK
>
>
> -----Original Message-----
> From: jeremie.galarneau at gmail.com [mailto:jeremie.galarneau at gmail.com] On Behalf Of Jérémie Galarneau
> Sent: Mittwoch, 2. Oktober 2013 20:25
> To: Salman Rafiq
> Cc: jdesfossez at efficios.com; lttng-dev at lists.lttng.org; Mathieu Desnoyers
> Subject: Re: Reading CTF trace using Babeltrace API
>
> On Wed, Oct 2, 2013 at 12:55 PM, Salman Rafiq <salman.rafiq at esk.fraunhofer.de> wrote:
>> Dear LTTngers,
>>
>> I would like to ask few questions related to the API's for reading CTF traces.
>>
>> 1. Is there any way to read CTF metadata independently, like we have certain API's to read the events.
>>
>
> Not from the public API, unfortunately.
>
>> 2. There are certain scopes defined in ctf/events.h like:
>> BT_TRACE_PACKET_HEADER = 0,
>> BT_STREAM_PACKET_CONTEXT = 1,
>> BT_STREAM_EVENT_HEADER = 2,
>> BT_STREAM_EVENT_CONTEXT = 3,
>> BT_EVENT_CONTEXT = 4,
>> BT_EVENT_FIELDS = 5,
>>
>> I could not figure out the way to ready the fields 'id' and 'stream_id', for a particular event while iterating through the trace.
>> Though I can ready the event name using an API and fields using BT_EVENT_FIELDS as a scope.
>> For e.g. consider the
>>
>> event {
>> name = sched_migrate_task;
>> id = 1;
>> stream_id = 0;
>> fields := struct {
>> integer { size = 8; align = 8; signed = 1; encoding = UTF8; base = 10; } _comm[16];
>> integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _tid;
>> integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _prio;
>> integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _orig_cpu;
>> integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _dest_cpu;
>> };
>> };
>>
>
> The "id" field is part of the BT_STREAM_EVENT_HEADER scope, while the "stream_id" field is part of the BT_TRACE_PACKET_HEADER scope.
>
> The code below is adapted from converter/babeltrace.c's
> convert_trace() loop to print both values.
>
> while ((ctf_event = bt_ctf_iter_read_event(iter))) {
>
> const struct bt_definition *stream_event_header_scope =
> bt_ctf_get_top_level_scope(
> ctf_event, BT_STREAM_EVENT_HEADER);
> const struct bt_definition *id_field =
> bt_ctf_get_field(
> ctf_event, stream_event_header_scope, "id");
>
> printf("id = %" PRIu64 "\n", bt_ctf_get_uint64(id_field));
>
> const struct bt_definition *packet_header_scope =
> bt_ctf_get_top_level_scope(
> ctf_event, BT_TRACE_PACKET_HEADER);
> const struct bt_definition *stream_id_field =
> bt_ctf_get_field(
> ctf_event, packet_header_scope, "stream_id");
>
> printf("stream_id = %" PRIu64 "\n", bt_ctf_get_uint64(
> stream_id_field)); [...] }
>
> Regards,
> Jérémie
>
>>
>> Any help or suggestion related to this issue will be really appreciated.
>> Thanks!
>>
>> Regards,
>> Salman
>>
>> --
>> Salman Rafiq
>> Geschäftsfeld Industrial Communication Fraunhofer-Institut für
>> Eingebettete Systeme und Kommunikationstechnik ESK
>>
>> Hansastraße 32 | 80686 München
>> Telefon, Fax: +49 89 547088-356 | +49 89 547088-221
>> E-Mail: salman.rafiq at esk.fraunhofer.de
>>
>> Internet:
>> http://www.esk.fraunhofer.de
>> http://www.twitter.com/FraunhoferESK
>>
>
>
>
> --
> Jérémie Galarneau
> EfficiOS Inc.
> http://www.efficios.com
--
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list