case LTTNG_KERNEL_KPROBE:
instrumentation_string = config_event_type_kprobe;
break;
+ case LTTNG_KERNEL_UPROBE:
+ instrumentation_string = config_event_type_userspace_probe;
+ break;
case LTTNG_KERNEL_FUNCTION:
instrumentation_string = config_event_type_function;
break;
case LTTNG_KERNEL_KRETPROBE:
addr = event->event->u.kretprobe.addr;
offset = event->event->u.kretprobe.offset;
- symbol_name = event->event->u.kretprobe.symbol_name;
+ symbol_name = addr ? NULL : event->event->u.kretprobe.symbol_name;
break;
default:
assert(1);
+ ERR("Unsupported kernel instrumentation type.");
+ ret = LTTNG_ERR_INVALID;
+ goto end;
}
ret = config_writer_open_element(writer, config_element_probe_attributes);
goto end;
}
- if (symbol_name) {
+ if (addr) {
+ ret = config_writer_write_element_unsigned_int( writer,
+ config_element_address, addr);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ } else if (symbol_name) {
ret = config_writer_write_element_string(writer,
config_element_symbol_name, symbol_name);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ /* If the offset is non-zero, write it.*/
+ if (offset) {
+ ret = config_writer_write_element_unsigned_int(writer,
+ config_element_offset, offset);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ }
+ } else {
+ /*
+ * This really should not happen as we are either setting the
+ * address or the symbol above.
+ */
+ ERR("Invalid probe/function description.");
+ ret = LTTNG_ERR_INVALID;
+ goto end;
}
- if (addr) {
- ret = config_writer_write_element_unsigned_int( writer,
- config_element_address, addr);
+
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+end:
+ return ret;
+}
+
+/*
+ * Save the userspace probe tracepoint event associated with the event to the
+ * config writer.
+ */
+static
+int save_kernel_userspace_probe_tracepoint_event(struct config_writer *writer,
+ struct ltt_kernel_event *event)
+{
+ int ret = 0;
+ const char *probe_name, *provider_name, *binary_path;
+ struct lttng_userspace_probe_location *userspace_probe_location;
+ struct lttng_userspace_probe_location_lookup_method *lookup_method;
+ enum lttng_userspace_probe_location_lookup_method_type lookup_type;
+
+ /* Get userspace probe location from the event. */
+ userspace_probe_location = event->userspace_probe_location;
+ if (!userspace_probe_location) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* Get lookup method and lookup method type. */
+ lookup_method = lttng_userspace_probe_location_get_lookup_method(userspace_probe_location);
+ if (!lookup_method) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method);
+
+ /* Get the binary path, probe name and provider name. */
+ binary_path =
+ lttng_userspace_probe_location_tracepoint_get_binary_path(
+ userspace_probe_location);
+ if (!binary_path) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ probe_name =
+ lttng_userspace_probe_location_tracepoint_get_probe_name(
+ userspace_probe_location);
+ if (!probe_name) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ provider_name =
+ lttng_userspace_probe_location_tracepoint_get_provider_name(
+ userspace_probe_location);
+ if (!provider_name) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* Open a userspace probe tracepoint attribute. */
+ ret = config_writer_open_element(writer, config_element_userspace_probe_tracepoint_attributes);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ switch (lookup_type) {
+ case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_lookup,
+ config_element_userspace_probe_lookup_tracepoint_sdt);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ break;
+ default:
+ ERR("Unsupported kernel userspace probe tracepoint lookup method.");
+ ret = LTTNG_ERR_INVALID;
+ goto end;
}
- if (offset) {
- ret = config_writer_write_element_unsigned_int(writer,
- config_element_offset, offset);
+ /* Write the binary path, provider name and the probe name. */
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_location_binary_path,
+ binary_path);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_tracepoint_location_provider_name,
+ provider_name);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_tracepoint_location_probe_name,
+ probe_name);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* Close the userspace probe tracepoint attribute. */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+/*
+ * Save the userspace probe function event associated with the event to the
+ * config writer.
+ */
+static
+int save_kernel_userspace_probe_function_event(struct config_writer *writer,
+ struct ltt_kernel_event *event)
+{
+ int ret = 0;
+ const char *function_name, *binary_path;
+ struct lttng_userspace_probe_location *userspace_probe_location;
+ struct lttng_userspace_probe_location_lookup_method *lookup_method;
+ enum lttng_userspace_probe_location_lookup_method_type lookup_type;
+
+ /* Get userspace probe location from the event. */
+ userspace_probe_location = event->userspace_probe_location;
+ if (!userspace_probe_location) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* Get lookup method and lookup method type. */
+ lookup_method = lttng_userspace_probe_location_get_lookup_method(
+ userspace_probe_location);
+ if (!lookup_method) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* Get the binary path and the function name. */
+ binary_path =
+ lttng_userspace_probe_location_function_get_binary_path(
+ userspace_probe_location);
+ if (!binary_path) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ function_name =
+ lttng_userspace_probe_location_function_get_function_name(
+ userspace_probe_location);
+ if (!function_name) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* Open a userspace probe function attribute. */
+ ret = config_writer_open_element(writer,
+ config_element_userspace_probe_function_attributes);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method);
+ switch (lookup_type) {
+ case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_lookup,
+ config_element_userspace_probe_lookup_function_elf);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ break;
+ case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT:
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_lookup,
+ config_element_userspace_probe_lookup_function_default);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ break;
+ default:
+ ERR("Unsupported kernel userspace probe function lookup method.");
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ /* Write the binary path and the function name. */
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_location_binary_path,
+ binary_path);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = config_writer_write_element_string(writer,
+ config_element_userspace_probe_function_location_function_name,
+ function_name);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
}
+ /* Close the userspace probe function attribute. */
ret = config_writer_close_element(writer);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+end:
+ return ret;
+}
+
+static
+int save_kernel_userspace_probe_event(struct config_writer *writer,
+ struct ltt_kernel_event *event)
+{
+ int ret;
+ struct lttng_userspace_probe_location *userspace_probe_location;
+
+ /* Get userspace probe location from the event. */
+ userspace_probe_location = event->userspace_probe_location;
+ if (!userspace_probe_location) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ switch(lttng_userspace_probe_location_get_type(userspace_probe_location)) {
+ case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
+ {
+ ret = save_kernel_userspace_probe_function_event(writer, event);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ break;
+ }
+ case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
+ {
+ ret = save_kernel_userspace_probe_tracepoint_event(writer, event);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ break;
+ }
+ case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN:
+ default:
+ ERR("Unsupported kernel userspace probe location type.");
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
end:
return ret;
}
+
+static
int save_kernel_event(struct config_writer *writer,
struct ltt_kernel_event *event)
{
if (event->event->instrumentation == LTTNG_KERNEL_FUNCTION ||
event->event->instrumentation == LTTNG_KERNEL_KPROBE ||
+ event->event->instrumentation == LTTNG_KERNEL_UPROBE ||
event->event->instrumentation == LTTNG_KERNEL_KRETPROBE) {
ret = config_writer_open_element(writer,
goto end;
}
break;
+ case LTTNG_KERNEL_UPROBE:
+ ret = save_kernel_userspace_probe_event(writer, event);
+ if (ret) {
+ goto end;
+ }
+ break;
default:
ERR("Unsupported kernel instrumentation type.");
ret = LTTNG_ERR_INVALID;
extern const char * const config_element_symbol_name;
extern const char * const config_element_address;
extern const char * const config_element_offset;
+extern const char * const config_element_userspace_probe_lookup;
+extern const char * const config_element_userspace_probe_lookup_function_default;
+extern const char * const config_element_userspace_probe_lookup_function_elf;
+extern const char * const config_element_userspace_probe_lookup_tracepoint_sdt;
+extern const char * const config_element_userspace_probe_location_binary_path;
+extern const char * const config_element_userspace_probe_function_attributes;
+extern const char * const config_element_userspace_probe_function_location_function_name;
+extern const char * const config_element_userspace_probe_tracepoint_attributes;
+extern const char * const config_element_userspace_probe_tracepoint_location_provider_name;
+extern const char * const config_element_userspace_probe_tracepoint_location_probe_name;
extern const char * const config_element_name;
extern const char * const config_element_enabled;
extern const char * const config_element_overwrite_mode;
extern const char * const config_event_type_all;
extern const char * const config_event_type_tracepoint;
extern const char * const config_event_type_probe;
+extern const char * const config_event_type_userspace_probe;
extern const char * const config_event_type_function;
extern const char * const config_event_type_function_entry;
extern const char * const config_event_type_noop;
#include <lttng/lttng.h>
#include <lttng/snapshot.h>
#include <lttng/rotation.h>
+#include <lttng/userspace-probe.h>
#include "session-config.h"
#include "config-internal.h"
+#define CONFIG_USERSPACE_PROBE_LOOKUP_METHOD_NAME_MAX_LEN 7
+
struct handler_filter_args {
const char* section;
config_entry_handler_cb handler;
const char * const config_element_symbol_name = "symbol_name";
const char * const config_element_address = "address";
const char * const config_element_offset = "offset";
+
+const char * const config_element_userspace_probe_lookup = "lookup_method";
+const char * const config_element_userspace_probe_lookup_function_default = "DEFAULT";
+const char * const config_element_userspace_probe_lookup_function_elf = "ELF";
+const char * const config_element_userspace_probe_lookup_tracepoint_sdt = "SDT";
+const char * const config_element_userspace_probe_location_binary_path = "binary_path";
+const char * const config_element_userspace_probe_function_attributes = "userspace_probe_function_attributes";
+const char * const config_element_userspace_probe_function_location_function_name = "function_name";
+const char * const config_element_userspace_probe_tracepoint_attributes = "userspace_probe_tracepoint_attributes";
+const char * const config_element_userspace_probe_tracepoint_location_provider_name = "provider_name";
+const char * const config_element_userspace_probe_tracepoint_location_probe_name = "probe_name";
+
const char * const config_element_name = "name";
const char * const config_element_enabled = "enabled";
const char * const config_element_overwrite_mode = "overwrite_mode";
const char * const config_event_type_all = "ALL";
const char * const config_event_type_tracepoint = "TRACEPOINT";
const char * const config_event_type_probe = "PROBE";
+const char * const config_event_type_userspace_probe = "USERSPACE_PROBE";
const char * const config_event_type_function = "FUNCTION";
const char * const config_event_type_function_entry = "FUNCTION_ENTRY";
const char * const config_event_type_noop = "NOOP";
ret = LTTNG_EVENT_TRACEPOINT;
} else if (!strcmp((char *) event_type, config_event_type_probe)) {
ret = LTTNG_EVENT_PROBE;
+ } else if (!strcmp((char *) event_type,
+ config_event_type_userspace_probe)) {
+ ret = LTTNG_EVENT_USERSPACE_PROBE;
} else if (!strcmp((char *) event_type, config_event_type_function)) {
ret = LTTNG_EVENT_FUNCTION;
} else if (!strcmp((char *) event_type,
- config_event_type_function_entry)) {
+ config_event_type_function_entry)) {
ret = LTTNG_EVENT_FUNCTION_ENTRY;
} else if (!strcmp((char *) event_type, config_event_type_noop)) {
ret = LTTNG_EVENT_NOOP;
free(output.data_uri);
return ret;
}
+
+static
+struct lttng_userspace_probe_location *
+process_userspace_probe_function_attribute_node(
+ xmlNodePtr attribute_node)
+{
+ xmlChar *content;
+ xmlNodePtr function_attribute_node;
+ char *function_name = NULL, *binary_path = NULL, *lookup_method_name;
+ struct lttng_userspace_probe_location *location = NULL;
+ struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
+
+ /*
+ * Process userspace probe location function attributes. The order of
+ * the fields are not guaranteed so we need to iterate over all fields
+ * and check at the end if everything we need for this location type is
+ * there.
+ */
+ for (function_attribute_node =
+ xmlFirstElementChild(attribute_node);
+ function_attribute_node;
+ function_attribute_node = xmlNextElementSibling(
+ function_attribute_node)) {
+ /* Handle function name, binary path and lookup method. */
+ if (!strcmp((const char *) function_attribute_node->name,
+ config_element_userspace_probe_function_location_function_name)) {
+ content = xmlNodeGetContent(function_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ function_name = lttng_strndup((char *) content, LTTNG_SYMBOL_NAME_LEN);
+ free(content);
+ if (!function_name) {
+ PERROR("Error duplicating function name");
+ goto error;
+ }
+ } else if (!strcmp((const char *) function_attribute_node->name,
+ config_element_userspace_probe_location_binary_path)) {
+ content = xmlNodeGetContent(function_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ binary_path = lttng_strndup((char *) content, LTTNG_PATH_MAX);
+ free(content);
+ if (!binary_path) {
+ PERROR("Error duplicating binary path");
+ goto error;
+ }
+ } else if (!strcmp((const char *) function_attribute_node->name,
+ config_element_userspace_probe_lookup)) {
+ content = xmlNodeGetContent(function_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ lookup_method_name = lttng_strndup((char *) content,
+ CONFIG_USERSPACE_PROBE_LOOKUP_METHOD_NAME_MAX_LEN);
+ free(content);
+ if (!lookup_method_name) {
+ PERROR("Error duplicating lookup method name");
+ goto error;
+ }
+
+ /*
+ * function_default lookup method defaults to
+ * function_elf lookup method at the moment.
+ */
+ if (!strcmp(lookup_method_name, config_element_userspace_probe_lookup_function_elf)
+ || !strcmp(lookup_method_name, config_element_userspace_probe_lookup_function_default)) {
+ lookup_method = lttng_userspace_probe_location_lookup_method_function_elf_create();
+ if (!lookup_method) {
+ PERROR("Error creating function default/ELF lookup method");
+ free(lookup_method_name);
+ goto error;
+ }
+ } else {
+ WARN("Unknown function lookup method.");
+ free(lookup_method_name);
+ goto error;
+ }
+ } else {
+ goto error;
+ }
+
+ /* Check if all the necessary fields were found. */
+ if (binary_path && function_name && lookup_method) {
+ location =
+ lttng_userspace_probe_location_function_create(
+ binary_path, function_name,
+ lookup_method);
+ goto end;
+ }
+ }
+error:
+ free(binary_path);
+ free(function_name);
+ if (lookup_method) {
+ lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
+ }
+end:
+ return location;
+}
+
+static
+struct lttng_userspace_probe_location *
+process_userspace_probe_tracepoint_attribute_node(
+ xmlNodePtr attribute_node)
+{
+ xmlChar *content;
+ xmlNodePtr tracepoint_attribute_node;
+ char *lookup_method_name = NULL;
+ char *probe_name = NULL, *provider_name = NULL, *binary_path = NULL;
+ struct lttng_userspace_probe_location *location = NULL;
+ struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
+
+ /*
+ * Process userspace probe location tracepoint attributes. The order of
+ * the fields are not guaranteed so we need to iterate over all fields
+ * and check at the end if everything we need for this location type is
+ * there.
+ */
+ for (tracepoint_attribute_node =
+ xmlFirstElementChild(attribute_node); tracepoint_attribute_node;
+ tracepoint_attribute_node = xmlNextElementSibling(
+ tracepoint_attribute_node)) {
+ if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_tracepoint_location_probe_name)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ probe_name = lttng_strndup((char*) content, LTTNG_SYMBOL_NAME_LEN);
+ free(content);
+ if (!probe_name) {
+ PERROR("Error duplicating probe name");
+ goto error;
+ }
+ } else if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_tracepoint_location_provider_name)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ provider_name = lttng_strndup((char*) content, LTTNG_SYMBOL_NAME_LEN);
+ free(content);
+ if (!provider_name) {
+ PERROR("Error duplicating provider name");
+ goto error;
+ }
+ } else if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_location_binary_path)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ binary_path = lttng_strndup((char*) content, LTTNG_PATH_MAX);
+
+ free(content);
+
+ if (!binary_path) {
+ PERROR("Error duplicating binary path");
+ goto error;
+ }
+ } else if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_lookup)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ lookup_method_name = lttng_strndup((char *) content,
+ CONFIG_USERSPACE_PROBE_LOOKUP_METHOD_NAME_MAX_LEN);
+ free(content);
+
+ if (!lookup_method_name) {
+ PERROR("Error duplicating lookup method name");
+ goto error;
+ }
+
+ if (!strcmp(lookup_method_name,
+ config_element_userspace_probe_lookup_tracepoint_sdt)) {
+ lookup_method =
+ lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
+ if (!lookup_method) {
+ PERROR("Error creating tracepoint SDT lookup method");
+ free(lookup_method_name);
+ goto error;
+ }
+ } else {
+ WARN("Unknown tracepoint lookup method.");
+ goto error;
+ }
+ } else {
+ WARN("Unknown tracepoint attribute.");
+ goto error;
+ }
+
+ /* Check if all the necessary fields were found. */
+ if (binary_path && provider_name && probe_name && lookup_method) {
+ location =
+ lttng_userspace_probe_location_tracepoint_create(
+ binary_path, provider_name,
+ probe_name, lookup_method);
+ goto end;
+ }
+ }
+error:
+ free(binary_path);
+ free(probe_name);
+ free(provider_name);
+ if (lookup_method) {
+ lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
+ }
+end:
+ return location;
+}
+
static
int process_probe_attribute_node(xmlNodePtr probe_attribute_node,
struct lttng_event_probe_attr *attr)
goto end;
}
- if (!strcmp((const char *) node->name,
+ if (!strcmp((const char *) attribute_node->name,
config_element_probe_attributes)) {
xmlNodePtr probe_attribute_node;
goto end;
}
}
- } else {
+ } else if (!strcmp((const char *) attribute_node->name,
+ config_element_function_attributes)) {
size_t sym_len;
xmlChar *content;
xmlNodePtr symbol_node = xmlFirstElementChild(attribute_node);
goto end;
}
free(content);
+ } else if (!strcmp((const char *) attribute_node->name,
+ config_element_userspace_probe_tracepoint_attributes)) {
+ struct lttng_userspace_probe_location *location;
+
+ location = process_userspace_probe_tracepoint_attribute_node(attribute_node);
+ if (!location) {
+ WARN("Error processing userspace probe tracepoint attribute");
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+ ret = lttng_event_set_userspace_probe_location(
+ event, location);
+ if (ret) {
+ WARN("Error setting userspace probe location field");
+ lttng_userspace_probe_location_destroy(
+ location);
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+ } else if (!strcmp((const char *) attribute_node->name,
+ config_element_userspace_probe_function_attributes)) {
+ struct lttng_userspace_probe_location *location;
+
+ location =
+ process_userspace_probe_function_attribute_node(
+ attribute_node);
+ if (!location) {
+ WARN("Error processing userspace probe function attribute");
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ ret = lttng_event_set_userspace_probe_location(
+ event, location);
+ if (ret) {
+ WARN("Error setting userspace probe location field");
+ lttng_userspace_probe_location_destroy(
+ location);
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+ } else {
+ /* Unknown event attribute. */
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
}
}
}
<xs:enumeration value="ALL"/>
<xs:enumeration value="TRACEPOINT"/>
<xs:enumeration value="PROBE"/>
+ <xs:enumeration value="USERSPACE_PROBE"/>
<xs:enumeration value="FUNCTION"/>
<xs:enumeration value="FUNCTION_ENTRY"/>
<xs:enumeration value="NOOP"/>
</xs:all>
</xs:complexType>
+<xs:simpleType name="userspace_probe_lookup_method">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="DEFAULT"/>
+ <xs:enumeration value="ELF"/>
+ <xs:enumeration value="SDT"/>
+ </xs:restriction>
+</xs:simpleType>
+
+<xs:complexType name="event_userspace_probe_function_attributes_type">
+ <xs:all>
+ <xs:element name="lookup_method" type="userspace_probe_lookup_method"/>
+ <xs:element name="binary_path" type="xs:string"/>
+ <xs:element name="function_name" type="xs:string"/>
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="event_userspace_probe_tracepoint_attributes_type">
+ <xs:all>
+ <xs:element name="lookup_method" type="userspace_probe_lookup_method"/>
+ <xs:element name="binary_path" type="xs:string"/>
+ <xs:element name="probe_name" type="xs:string"/>
+ <xs:element name="provider_name" type="xs:string"/>
+ </xs:all>
+</xs:complexType>
+
<xs:complexType name="event_ftrace_attributes_type">
<xs:all>
<xs:element name="symbol_name" type="name_type"/>
<xs:choice>
<xs:element name="probe_attributes" type="event_probe_attributes_type"/>
<xs:element name="function_attributes" type="event_ftrace_attributes_type"/>
+ <xs:element name="userspace_probe_function_attributes" type="event_userspace_probe_function_attributes_type"/>
+ <xs:element name="userspace_probe_tracepoint_attributes" type="event_userspace_probe_tracepoint_attributes_type"/>
</xs:choice>
</xs:complexType>