|
// Test program found on: https://lists.lttng.org/pipermail/lttng-dev/2014-May/023058.html
|
|
// Compiled with: gcc segfault_libbabeltrace.c -lbabeltrace -lbabeltrace-ctf -o segfault_libbabeltrace -g
|
|
// Executed as: $ ./segfault_libbabeltrace test-trace/ust/uid/0/32-bit
|
|
// Result: Segmentation fault (core dumped)
|
|
// Line causing the segfault: Line 78: ret = bt_ctf_get_field_list(bt_event, field_def,
|
|
// Note: Same seg fault occurred with babeltrace-1.4.0
|
|
// Used gdb to find the line causing the crash:
|
|
// gdb --args ./segfault_libbabeltrace test-trace/ust/uid/0/32-bit
|
|
|
|
#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;
|
|
}
|