summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
8d9f9e9)
The common metadata decoder now accepts an optional configuration
structure. The offset (seconds and nanoseconds) to apply to all the
clock classes is found in there, as well as a new option which makes the
decoder strict. In strict mode, the decoder does not allow the decoded
metadata stream to be off semantically. For example, in strict mode,
clock classes named `monotonic` are not forced to be absolute when it is
detected that the stream was produced by an LTTng tracer.
It's not expected that the strict mode be something that any user would
want under normal conditions because the non-strict mode fixes errors
made by known tracers to make things work for the other components of
the graph. As such, there's no quick --strict option in the CLI's
`convert` command: the user can instantiate its own source.ctf.fs
component with --component for this and pass the options with --params:
babeltrace -c src.ctf.fs --path ~/my-traces/trace -p strict-metadata=yes
I'm also fixing the parameter names and types for the clock class
offsets, both in the CLI and in source.ctf.fs, so that all the project's
modules are in sync regarding this. The parameters are now
`clock-class-offset-s` and `clock-class-offset-ns`, and with the
`convert` command, they are set with resp. --clock-offset and
--clock-offset-ns. They used to be passed to the `run` command as string
values (using --key and --value), but now they are part of the
component's --params option so that they are recognized as constant
integer values (even if negative).
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
break;
case OPT_CLOCK_FORCE_CORRELATE:
append_implicit_component_param(
break;
case OPT_CLOCK_FORCE_CORRELATE:
append_implicit_component_param(
- &implicit_muxer_args, "assume-absolute-clock-classes", "yes");
+ &implicit_muxer_args,
+ "assume-absolute-clock-classes", "yes");
break;
case OPT_CLOCK_GMT:
append_implicit_component_param(
break;
case OPT_CLOCK_GMT:
append_implicit_component_param(
break;
case OPT_CLOCK_OFFSET:
base_implicit_ctf_input_args.exists = true;
break;
case OPT_CLOCK_OFFSET:
base_implicit_ctf_input_args.exists = true;
- ret = append_implicit_component_extra_param(
- &base_implicit_ctf_input_args, "clock-offset-cycles", arg);
+ append_implicit_component_param(
+ &implicit_muxer_args,
+ "clock-class-offset-s", arg);
base_implicit_ctf_input_args.exists = true;
ret = append_implicit_component_extra_param(
&base_implicit_ctf_input_args,
base_implicit_ctf_input_args.exists = true;
ret = append_implicit_component_extra_param(
&base_implicit_ctf_input_args,
- "clock-offset-ns", arg);
+ "clock-class-offset-ns", arg);
#include <babeltrace/ctf-ir/trace.h>
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/ctf-ir/trace.h>
#include <babeltrace/babeltrace-internal.h>
// the parameter name (of the reentrant 'yyparse' function)
// data is a pointer to a 'SParserParam' structure
//#define YYPARSE_PARAM scanner
// the parameter name (of the reentrant 'yyparse' function)
// data is a pointer to a 'SParserParam' structure
//#define YYPARSE_PARAM scanner
BT_HIDDEN
struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
BT_HIDDEN
struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
- int64_t clock_class_offset_ns, const char *name);
+ const struct ctf_metadata_decoder_config *config,
+ const char *name);
void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor);
void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor);
uint8_t uuid[16];
bool is_uuid_set;
int bo;
uint8_t uuid[16];
bool is_uuid_set;
int bo;
+ struct ctf_metadata_decoder_config config;
};
struct packet_header {
};
struct packet_header {
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
- int64_t clock_class_offset_ns, const char *name)
+ const struct ctf_metadata_decoder_config *config,
+ const char *name)
{
struct ctf_metadata_decoder *mdec =
g_new0(struct ctf_metadata_decoder, 1);
{
struct ctf_metadata_decoder *mdec =
g_new0(struct ctf_metadata_decoder, 1);
+ struct ctf_metadata_decoder_config default_config = {
+ .clock_class_offset_s = 0,
+ .clock_class_offset_ns = 0,
+ .strict = false,
+ };
+
+ if (!config) {
+ config = &default_config;
+ }
BT_LOGD("Creating CTF metadata decoder: "
BT_LOGD("Creating CTF metadata decoder: "
- "clock-class-offset-ns=%" PRId64 ", name=\"%s\"",
- clock_class_offset_ns, name);
+ "clock-class-offset-s=%" PRId64 ", "
+ "clock-class-offset-ns=%" PRId64 ", "
+ "strict=%d, name=\"%s\"",
+ config->clock_class_offset_s, config->clock_class_offset_ns,
+ config->strict, name);
if (!mdec) {
BT_LOGE_STR("Failed to allocate one CTF metadata decoder.");
goto end;
}
if (!mdec) {
BT_LOGE_STR("Failed to allocate one CTF metadata decoder.");
goto end;
}
- mdec->visitor = ctf_visitor_generate_ir_create(clock_class_offset_ns,
- name);
+ mdec->config = *config;
+ mdec->visitor = ctf_visitor_generate_ir_create(config, name);
if (!mdec->visitor) {
BT_LOGE("Failed to create a CTF IR metadata AST visitor: "
"mdec-addr=%p", mdec);
if (!mdec->visitor) {
BT_LOGE("Failed to create a CTF IR metadata AST visitor: "
"mdec-addr=%p", mdec);
- BT_LOGD("Created CTF metadata decoder: "
- "clock-class-offset-ns=%" PRId64 ", name=\"%s\", addr=%p",
- clock_class_offset_ns, name, mdec);
+ BT_LOGD("Creating CTF metadata decoder: "
+ "clock-class-offset-s=%" PRId64 ", "
+ "clock-class-offset-ns=%" PRId64 ", "
+ "strict=%d, name=\"%s\", addr=%p",
+ config->clock_class_offset_s, config->clock_class_offset_ns,
+ config->strict, name, mdec);
CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR = -4,
};
CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR = -4,
};
+/* Decoding configuration */
+struct ctf_metadata_decoder_config {
+ int64_t clock_class_offset_s;
+ int64_t clock_class_offset_ns;
+ bool strict;
+};
+
- * Creates a CTF metadata decoder. `clock_class_offset_ns` is an
- * offset to apply to the decoded clock classes's offsets. `name` is
- * this decoder's trace's name.
+ * Creates a CTF metadata decoder. `name` is this decoder's trace's
+ * name.
*
* Returns `NULL` on error.
*/
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
*
* Returns `NULL` on error.
*/
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
- int64_t clock_class_offset_ns, const char *name);
+ const struct ctf_metadata_decoder_config *config,
+ const char *name);
/*
* Destroys a CTF metadata decoder that you created with
/*
* Destroys a CTF metadata decoder that you created with
#include "scanner.h"
#include "parser.h"
#include "ast.h"
#include "scanner.h"
#include "parser.h"
#include "ast.h"
/* Bit value (left shift) */
#define _BV(_val) (1 << (_val))
/* Bit value (left shift) */
#define _BV(_val) (1 << (_val))
/* 1 if this is an LTTng trace */
bool is_lttng;
/* 1 if this is an LTTng trace */
bool is_lttng;
- /* Offset (ns) to apply to clock classes on creation */
- int64_t clock_class_offset_ns;
-
/* Eventual name suffix of the trace to set */
char *trace_name_suffix;
/* Eventual name suffix of the trace to set */
char *trace_name_suffix;
* int64_t -> struct bt_ctf_stream_class *
*/
GHashTable *stream_classes;
* int64_t -> struct bt_ctf_stream_class *
*/
GHashTable *stream_classes;
+
+ /* Config passed by the user */
+ struct ctf_metadata_decoder_config decoder_config;
*/
static
struct ctx *ctx_create(struct bt_ctf_trace *trace,
*/
static
struct ctx *ctx_create(struct bt_ctf_trace *trace,
- int64_t clock_class_offset_ns, const char *trace_name_suffix)
+ const struct ctf_metadata_decoder_config *decoder_config,
+ const char *trace_name_suffix)
{
struct ctx *ctx = NULL;
struct ctx_decl_scope *scope = NULL;
{
struct ctx *ctx = NULL;
struct ctx_decl_scope *scope = NULL;
+ assert(decoder_config);
+
ctx = g_new0(struct ctx, 1);
if (!ctx) {
BT_LOGE_STR("Failed to allocate one visitor context.");
ctx = g_new0(struct ctx, 1);
if (!ctx) {
BT_LOGE_STR("Failed to allocate one visitor context.");
ctx->current_scope = scope;
scope = NULL;
ctx->trace_bo = BT_CTF_BYTE_ORDER_NATIVE;
ctx->current_scope = scope;
scope = NULL;
ctx->trace_bo = BT_CTF_BYTE_ORDER_NATIVE;
- ctx->clock_class_offset_ns = clock_class_offset_ns;
+ ctx->decoder_config = *decoder_config;
- if (strcmp(left, "tracer_name") == 0) {
- if (strncmp(right, "lttng", 5) == 0) {
- BT_LOGI("Detected LTTng trace from `%s` environment value: "
- "tracer-name=\"%s\"",
- left, right);
- ctx->is_lttng = 1;
+ if (!ctx->decoder_config.strict) {
+ if (strcmp(left, "tracer_name") == 0) {
+ if (strncmp(right, "lttng", 5) == 0) {
+ BT_LOGI("Non-strict mode: detected LTTng trace from `%s` environment value: "
+ "tracer-name=\"%s\"",
+ left, right);
+ ctx->is_lttng = 1;
+ }
int ret;
uint64_t freq;
int64_t offset_cycles;
int ret;
uint64_t freq;
int64_t offset_cycles;
+ int64_t offset_to_apply;
freq = bt_ctf_clock_class_get_frequency(clock);
if (freq == -1ULL) {
freq = bt_ctf_clock_class_get_frequency(clock);
if (freq == -1ULL) {
- offset_cycles += cycles_from_ns(freq, ctx->clock_class_offset_ns);
+ offset_to_apply =
+ ctx->decoder_config.clock_class_offset_s * 1000000000LL +
+ ctx->decoder_config.clock_class_offset_ns;
+ offset_cycles += cycles_from_ns(freq, offset_to_apply);
ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles);
end:
ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles);
end:
BT_HIDDEN
struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
BT_HIDDEN
struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
- int64_t clock_class_offset_ns, const char *name)
+ const struct ctf_metadata_decoder_config *decoder_config,
+ const char *name)
{
int ret;
struct ctx *ctx = NULL;
{
int ret;
struct ctx *ctx = NULL;
}
/* Create visitor's context */
}
/* Create visitor's context */
- ctx = ctx_create(trace, clock_class_offset_ns, name);
+ ctx = ctx_create(trace, decoder_config, name);
if (!ctx) {
BT_LOGE_STR("Cannot create visitor's context.");
goto error;
if (!ctx) {
BT_LOGE_STR("Cannot create visitor's context.");
goto error;
BT_HIDDEN
struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
BT_HIDDEN
struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
- struct metadata_overrides *overrides)
+ struct ctf_fs_metadata_config *metadata_config)
{
struct ctf_fs_trace *ctf_fs_trace;
int ret;
{
struct ctf_fs_trace *ctf_fs_trace;
int ret;
- ret = ctf_fs_metadata_set_trace(ctf_fs_trace, overrides);
+ ret = ctf_fs_metadata_set_trace(ctf_fs_trace, metadata_config);
GList *trace_names = NULL;
GList *tp_node;
GList *tn_node;
GList *trace_names = NULL;
GList *tp_node;
GList *tn_node;
- struct metadata_overrides metadata_overrides = {
- .clock_offset_s = ctf_fs->options.clock_offset,
- .clock_offset_ns = ctf_fs->options.clock_offset_ns,
- };
norm_path = bt_common_normalize_path(path_param, NULL);
if (!norm_path) {
norm_path = bt_common_normalize_path(path_param, NULL);
if (!norm_path) {
GString *trace_name = tn_node->data;
ctf_fs_trace = ctf_fs_trace_create(trace_path->str,
GString *trace_name = tn_node->data;
ctf_fs_trace = ctf_fs_trace_create(trace_path->str,
- trace_name->str, &metadata_overrides);
+ trace_name->str, &ctf_fs->metadata_config);
if (!ctf_fs_trace) {
BT_LOGE("Cannot create trace for `%s`.",
trace_path->str);
if (!ctf_fs_trace) {
BT_LOGE("Cannot create trace for `%s`.",
trace_path->str);
ret = bt_value_string_get(value, &path_param);
assert(ret == 0);
BT_PUT(value);
ret = bt_value_string_get(value, &path_param);
assert(ret == 0);
BT_PUT(value);
- value = bt_value_map_get(params, "offset-s");
+ value = bt_value_map_get(params, "clock-class-offset-s");
+ if (!bt_value_is_integer(value)) {
+ BT_LOGE("clock-class-offset-s should be an integer");
+ goto error;
+ }
+ ret = bt_value_integer_get(value,
+ &ctf_fs->metadata_config.clock_class_offset_s);
+ assert(ret == 0);
+ BT_PUT(value);
+ }
+ value = bt_value_map_get(params, "clock-class-offset-ns");
+ if (value) {
if (!bt_value_is_integer(value)) {
if (!bt_value_is_integer(value)) {
- BT_LOGE("offset-s should be an integer");
+ BT_LOGE("clock-class-offset-ns should be an integer");
- ret = bt_value_integer_get(value, &offset);
+ ret = bt_value_integer_get(value,
+ &ctf_fs->metadata_config.clock_class_offset_ns);
- ctf_fs->options.clock_offset = offset;
- value = bt_value_map_get(params, "offset-ns");
+ value = bt_value_map_get(params, "strict-metadata");
- if (!bt_value_is_integer(value)) {
- BT_LOGE("offset-ns should be an integer");
+ if (!bt_value_is_bool(value)) {
+ BT_LOGE("strict-metadata should be a boolean");
- ret = bt_value_integer_get(value, &offset);
+ ret = bt_value_bool_get(value, &strict);
- ctf_fs->options.clock_offset_ns = offset;
+ ctf_fs->metadata_config.strict = !!strict;
-struct ctf_fs_component_options {
- int64_t clock_offset;
- int64_t clock_offset_ns;
-};
-
struct ctf_fs_component {
/* Weak, guaranteed to exist */
struct bt_private_component *priv_comp;
struct ctf_fs_component {
/* Weak, guaranteed to exist */
struct bt_private_component *priv_comp;
/* Array of struct ctf_fs_trace *, owned by this */
GPtrArray *traces;
/* Array of struct ctf_fs_trace *, owned by this */
GPtrArray *traces;
- struct ctf_fs_component_options options;
+ struct ctf_fs_metadata_config metadata_config;
BT_HIDDEN
struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
BT_HIDDEN
struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
- struct metadata_overrides *overrides);
+ struct ctf_fs_metadata_config *config);
BT_HIDDEN
void ctf_fs_trace_destroy(struct ctf_fs_trace *trace);
BT_HIDDEN
void ctf_fs_trace_destroy(struct ctf_fs_trace *trace);
#define BT_LOG_TAG "PLUGIN-CTF-FS-METADATA-SRC"
#include "logging.h"
#define BT_LOG_TAG "PLUGIN-CTF-FS-METADATA-SRC"
#include "logging.h"
-#define NSEC_PER_SEC 1000000000LL
-
BT_HIDDEN
FILE *ctf_fs_metadata_open_file(const char *trace_path)
{
BT_HIDDEN
FILE *ctf_fs_metadata_open_file(const char *trace_path)
{
}
int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace,
}
int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace,
- struct metadata_overrides *overrides)
+ struct ctf_fs_metadata_config *config)
{
int ret = 0;
struct ctf_fs_file *file = NULL;
struct ctf_metadata_decoder *metadata_decoder = NULL;
{
int ret = 0;
struct ctf_fs_file *file = NULL;
struct ctf_metadata_decoder *metadata_decoder = NULL;
- int64_t clock_offset_adjustment = 0;
+ struct ctf_metadata_decoder_config decoder_config = {
+ .clock_class_offset_s = config->clock_class_offset_s,
+ .clock_class_offset_ns = config->clock_class_offset_ns,
+ .strict = config->strict,
+ };
file = get_file(ctf_fs_trace->path->str);
if (!file) {
file = get_file(ctf_fs_trace->path->str);
if (!file) {
- if (overrides) {
- clock_offset_adjustment =
- overrides->clock_offset_s * NSEC_PER_SEC +
- overrides->clock_offset_ns;
- }
- metadata_decoder = ctf_metadata_decoder_create(clock_offset_adjustment,
+ metadata_decoder = ctf_metadata_decoder_create(&decoder_config,
ctf_fs_trace->name->str);
if (!metadata_decoder) {
BT_LOGE("Cannot create metadata decoder object");
ctf_fs_trace->name->str);
if (!metadata_decoder) {
BT_LOGE("Cannot create metadata decoder object");
struct ctf_fs_trace;
struct ctf_fs_metadata;
struct ctf_fs_trace;
struct ctf_fs_metadata;
-struct metadata_overrides {
- int64_t clock_offset_s;
- int64_t clock_offset_ns;
+struct ctf_fs_metadata_config {
+ int64_t clock_class_offset_s;
+ int64_t clock_class_offset_ns;
+ bool strict;
BT_HIDDEN
int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace,
BT_HIDDEN
int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace,
- struct metadata_overrides *overrides);
+ struct ctf_fs_metadata_config *config);
BT_HIDDEN
FILE *ctf_fs_metadata_open_file(const char *trace_path);
BT_HIDDEN
FILE *ctf_fs_metadata_open_file(const char *trace_path);
if (!match) {
goto error;
}
if (!match) {
goto error;
}
- metadata->decoder = ctf_metadata_decoder_create(0,
+ metadata->decoder = ctf_metadata_decoder_create(NULL,
match);
if (!metadata->decoder) {
goto error;
match);
if (!metadata->decoder) {
goto error;