From: Francis Deslauriers Date: Fri, 29 Jun 2018 20:03:37 +0000 (-0400) Subject: Implement lttng-save and lttng-load for userspace-probe X-Git-Tag: v2.11.0-rc1~69 X-Git-Url: https://git.liburcu.org/?a=commitdiff_plain;h=c1e83fb4cecbb43353e4e1d2092b0516b50a5c26;p=lttng-tools.git Implement lttng-save and lttng-load for userspace-probe Here are examples of both ELF function and SDT tracepoint XML descriptions: ``` userspace_probe_test_event_elf true USERSPACE_PROBE ELF /tmp/tmp.3fN5FYk6Zc/bin_elf_symlink test_function ``` ``` userspace_probe_test_event_sdt true USERSPACE_PROBE SDT /tmp/tmp.h4b4Itao8v/bin_sdt_symlink foobar tp1 ``` Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index 3e2627818..c03b17ea8 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -217,6 +217,9 @@ const char *get_kernel_instrumentation_string( 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; @@ -433,10 +436,13 @@ int save_kernel_kprobe_event(struct config_writer *writer, 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); @@ -445,41 +451,316 @@ int save_kernel_kprobe_event(struct config_writer *writer, 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) { @@ -534,6 +815,7 @@ int save_kernel_event(struct config_writer *writer, 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, @@ -558,6 +840,12 @@ int save_kernel_event(struct config_writer *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; diff --git a/src/common/config/config-session-abi.h b/src/common/config/config-session-abi.h index 4344186ae..950efa5f9 100644 --- a/src/common/config/config-session-abi.h +++ b/src/common/config/config-session-abi.h @@ -34,6 +34,16 @@ extern const char * const config_element_probe_attributes; 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; @@ -107,6 +117,7 @@ extern const char * const config_loglevel_type_single; 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; diff --git a/src/common/config/session-config.c b/src/common/config/session-config.c index 804b77818..5b5adbfc4 100644 --- a/src/common/config/session-config.c +++ b/src/common/config/session-config.c @@ -42,10 +42,13 @@ #include #include #include +#include #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; @@ -86,6 +89,18 @@ const char * const config_element_probe_attributes = "probe_attributes"; 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"; @@ -162,6 +177,7 @@ const char * const config_loglevel_type_single = "SINGLE"; 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"; @@ -919,10 +935,13 @@ int get_event_type(xmlChar *event_type) 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; @@ -1454,6 +1473,228 @@ end: 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) @@ -1752,7 +1993,7 @@ int process_event_node(xmlNodePtr event_node, struct lttng_handle *handle, goto end; } - if (!strcmp((const char *) node->name, + if (!strcmp((const char *) attribute_node->name, config_element_probe_attributes)) { xmlNodePtr probe_attribute_node; @@ -1768,7 +2009,8 @@ int process_event_node(xmlNodePtr event_node, struct lttng_handle *handle, 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); @@ -1797,6 +2039,51 @@ int process_event_node(xmlNodePtr event_node, struct lttng_handle *handle, 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; } } } diff --git a/src/common/config/session.xsd b/src/common/config/session.xsd index 18cb6679a..7781a5bda 100644 --- a/src/common/config/session.xsd +++ b/src/common/config/session.xsd @@ -85,6 +85,7 @@ by its signed 32-bit representation when converted to msec. + @@ -102,6 +103,31 @@ by its signed 32-bit representation when converted to msec. + + + + + + + + + + + + + + + + + + + + + + + + + @@ -112,6 +138,8 @@ by its signed 32-bit representation when converted to msec. + +