[lttng-dev] libbabeltrace: getting CTF sequence length?
Philippe Proulx
eeppeliteloop at gmail.com
Tue May 20 23:03:42 EDT 2014
On Tue, May 20, 2014 at 4:50 PM, Jérémie Galarneau
<jeremie.galarneau at efficios.com> wrote:
> On Tue, May 20, 2014 at 4:37 PM, Philippe Proulx
> <eeppeliteloop at gmail.com> wrote:
>> Hello,
>>
>> I'm using libbabeltrace in C++. I would like to know if there's an
>> equivalent of bt_ctf_get_array_len() for sequences. I tried using
>> bt_ctf_get_field_list() but the reported count was 10, whereas the
>> sequence length was really 6 (as shown by the babeltrace tool),
>> leading to a segfault when accessing the 7th element.
>>
>> Looking at the Python binding, I see that this is used:
>>
>> container_of(field, struct definition_sequence, p);
>>
>> followed by bt_sequence_len(). However, struct definition_sequence,
>> bt_sequence_len() (and bt_sequence_index()) are not available in
>> the API.
>>
>> So what would be your way to read sequence items? Do you have
>> an example using strictly what's available in /usr/include/babeltrace?
>>
>
> bt_ctf_get_field_list can be used to get the number of elements, along
> with a pointer to the elements (via the output parameters).
>
Jérémie,
consider this test I just wrote:
#include <stdlib.h>
#include <stdio.h>
#include <babeltrace/babeltrace.h>
#include <babeltrace/ctf/events.h>
#include <babeltrace/ctf/iterator.h>
int main(int argc, char* argv[])
{
struct bt_context* bt_context;
struct bt_ctf_iter* bt_ctf_iter;
const char* trace_path = argv[1];
struct bt_iter_pos begin_pos;
struct bt_ctf_event* bt_event;
const struct bt_definition* fields_def;
const struct bt_declaration* fields_decl;
const struct bt_definition* field_def;
const struct bt_declaration* field_decl;
unsigned int fields_count, seq_items_count;
struct bt_definition const* const* fields_list;
struct bt_definition const* const* seq_items_list;
int ret;
unsigned int x, y;
unsigned int pos = 1;
int err = 0;
bt_context = bt_context_create();
bt_context_add_trace(bt_context, trace_path, "ctf",
NULL, NULL, NULL);
begin_pos.type = BT_SEEK_BEGIN;
begin_pos.u.seek_time = 0;
bt_ctf_iter = bt_ctf_iter_create(bt_context, &begin_pos, NULL);
while (bt_event = bt_ctf_iter_read_event(bt_ctf_iter)) {
fields_def = bt_ctf_get_top_level_scope(bt_event, BT_EVENT_FIELDS);
if (!fields_def) {
goto next_event;
}
fields_decl = bt_ctf_get_decl_from_def(fields_def);
if (bt_ctf_field_type(fields_decl) != CTF_TYPE_STRUCT) {
goto next_event;
}
ret = bt_ctf_get_field_list(bt_event, fields_def, &fields_list,
&fields_count);
if (ret < 0) {
goto next_event;
}
for (x = 0; x < fields_count; ++x) {
field_def = fields_list[x];
if (!field_def) {
printf("field element error\n");
goto end;
}
field_decl = bt_ctf_get_decl_from_def(field_def);
if (bt_ctf_field_type(field_decl) == CTF_TYPE_SEQUENCE) {
ret = bt_ctf_get_field_list(bt_event, field_def,
&seq_items_list,
&seq_items_count);
if (ret < 0) {
/* I guess this means a count of 0? because
* it does happen.
*/
goto next_event;
}
for (y = 0; y < seq_items_count; ++y) {
if (!seq_items_list[y]) {
printf("error using seq_items_list[y]\n");
err = 1;
}
if (!bt_ctf_get_index(bt_event, field_def, y)) {
printf("error using bt_ctf_get_index()\n");
err = 1;
}
if (err) {
printf(" event: %s\n",
bt_ctf_event_name(bt_event));
printf(" position: %u\n", pos);
printf(" field: %s\n",
bt_ctf_field_name(field_def));
printf(" count: %u\n", seq_items_count);
goto end;
}
}
}
}
next_event:
if (bt_iter_next(bt_ctf_get_iter(bt_ctf_iter)) < 0) {
break;
}
++pos;
}
end:
bt_ctf_iter_destroy(bt_ctf_iter);
bt_context_put(bt_context);
return 0;
}
Running it with this trace <http://0x3b.org/bbt/bbt.tgz>, I get this:
error using bt_ctf_get_index()
event: scsi_dispatch_cmd_start
position: 46627
field: cmnd
count: 10
So... the count is 10, and there's stuff in seq_items_list[6] to
seq_items_list[9]
which is not NULL, yet bt_ctf_get_index() complains at element 6 (not written
in the results here, but I know it).
Why is the count 10 if only 6 elements are good? The babeltrace tool knows this
too:
$ babeltrace -i ctf kernel 2>/dev/null | sed -n 46627p
[21:40:00.281269992] (+0.000003741) eeppdesk
scsi_dispatch_cmd_start: { cpu_id = 0 }, { host_no = 10, channel = 0,
id = 0, lun = 0, opcode = 0, cmd_len = 6, data_sglen = 0, prot_sglen =
0, prot_op = 0, _cmnd_length = 6, cmnd = [ [0] = 0x0, [1] = 0x0, [2] =
0x0, [3] = 0x0, [4] = 0x0, [5] = 0x0 ] }
See, cmd_len is 6 and we see 6 elements in the cmnd field.
My question is still: where do I get this 6 from?
Thanks,
Phil
> Regards,
> Jérémie
>
>> I'm using the latest Git master on Arch Linux.
>>
>> Thank you!
>>
>> Philippe Proulx
>>
>> _______________________________________________
>> lttng-dev mailing list
>> lttng-dev at lists.lttng.org
>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>
>
>
> --
> Jérémie Galarneau
> EfficiOS Inc.
> http://www.efficios.com
More information about the lttng-dev
mailing list