X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fuserspace-probe.c;h=f5ed86367066b3504dadab91d04810c4d69e441b;hp=609ffc1ac22874cb5d944a2ced6adcc0cf07e2b2;hb=1cbd136b2479ef142bfb339b13d3d25aa772dda5;hpb=3e6e0df2f8f9f23d252c2508b6d741916dfcc4b3 diff --git a/src/common/userspace-probe.c b/src/common/userspace-probe.c index 609ffc1ac..f5ed86367 100644 --- a/src/common/userspace-probe.c +++ b/src/common/userspace-probe.c @@ -6,12 +6,15 @@ */ #include "lttng/lttng-error.h" -#include #include +#include #include +#include +#include #include -#include +#include #include +#include #include #include #include @@ -29,6 +32,22 @@ int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle( struct lttng_userspace_probe_location *location, struct fd_handle *binary_fd_handle); +static +enum lttng_error_code lttng_userspace_probe_location_lookup_method_mi_serialize( + const struct lttng_userspace_probe_location_lookup_method + *method, + struct mi_writer *writer); + +static +enum lttng_error_code lttng_userspace_probe_location_tracepoint_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer); + +static +enum lttng_error_code lttng_userspace_probe_location_function_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer); + enum lttng_userspace_probe_location_lookup_method_type lttng_userspace_probe_location_lookup_method_get_type( const struct lttng_userspace_probe_location_lookup_method *lookup_method) @@ -96,12 +115,12 @@ void lttng_userspace_probe_location_function_destroy( { struct lttng_userspace_probe_location_function *location_function = NULL; - assert(location); + LTTNG_ASSERT(location); location_function = container_of(location, struct lttng_userspace_probe_location_function, parent); - assert(location_function); + LTTNG_ASSERT(location_function); free(location_function->function_name); free(location_function->binary_path); @@ -115,13 +134,13 @@ void lttng_userspace_probe_location_tracepoint_destroy( { struct lttng_userspace_probe_location_tracepoint *location_tracepoint = NULL; - assert(location); + LTTNG_ASSERT(location); location_tracepoint = container_of(location, struct lttng_userspace_probe_location_tracepoint, parent); - assert(location_tracepoint); + LTTNG_ASSERT(location_tracepoint); free(location_tracepoint->probe_name); free(location_tracepoint->provider_name); @@ -199,6 +218,25 @@ end: return is_equal; } +static unsigned long lttng_userspace_probe_location_function_hash( + const struct lttng_userspace_probe_location *location) +{ + unsigned long hash = hash_key_ulong( + (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION, + lttng_ht_seed); + struct lttng_userspace_probe_location_function *function_location = + container_of(location, typeof(*function_location), + parent); + + hash ^= hash_key_str(function_location->function_name, lttng_ht_seed); + hash ^= hash_key_str(function_location->binary_path, lttng_ht_seed); + /* + * No need to hash on the fd. Worst comes to worse, + * the equal function will discriminate. + */ + return hash; +} + static bool lttng_userspace_probe_location_function_is_equal( const struct lttng_userspace_probe_location *_a, const struct lttng_userspace_probe_location *_b) @@ -215,14 +253,14 @@ static bool lttng_userspace_probe_location_function_is_equal( goto end; } - assert(a->function_name); - assert(b->function_name); + LTTNG_ASSERT(a->function_name); + LTTNG_ASSERT(b->function_name); if (strcmp(a->function_name, b->function_name)) { goto end; } - assert(a->binary_path); - assert(b->binary_path); + LTTNG_ASSERT(a->binary_path); + LTTNG_ASSERT(b->binary_path); if (strcmp(a->binary_path, b->binary_path)) { goto end; } @@ -290,6 +328,7 @@ lttng_userspace_probe_location_function_create_no_check(const char *binary_path, ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION; ret->equal = lttng_userspace_probe_location_function_is_equal; + ret->hash = lttng_userspace_probe_location_function_hash; goto end; error: @@ -305,6 +344,25 @@ end: return ret; } +static unsigned long lttng_userspace_probe_location_tracepoint_hash( + const struct lttng_userspace_probe_location *location) +{ + unsigned long hash = hash_key_ulong( + (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT, + lttng_ht_seed); + struct lttng_userspace_probe_location_tracepoint *tp_location = + container_of(location, typeof(*tp_location), parent); + + hash ^= hash_key_str(tp_location->probe_name, lttng_ht_seed); + hash ^= hash_key_str(tp_location->provider_name, lttng_ht_seed); + hash ^= hash_key_str(tp_location->binary_path, lttng_ht_seed); + /* + * No need to hash on the fd. Worst comes to worse, + * the equal function will discriminate. + */ + return hash; +} + static bool lttng_userspace_probe_location_tracepoint_is_equal( const struct lttng_userspace_probe_location *_a, const struct lttng_userspace_probe_location *_b) @@ -317,20 +375,20 @@ static bool lttng_userspace_probe_location_tracepoint_is_equal( b = container_of(_b, struct lttng_userspace_probe_location_tracepoint, parent); - assert(a->probe_name); - assert(b->probe_name); + LTTNG_ASSERT(a->probe_name); + LTTNG_ASSERT(b->probe_name); if (strcmp(a->probe_name, b->probe_name)) { goto end; } - assert(a->provider_name); - assert(b->provider_name); + LTTNG_ASSERT(a->provider_name); + LTTNG_ASSERT(b->provider_name); if (strcmp(a->provider_name, b->provider_name)) { goto end; } - assert(a->binary_path); - assert(b->binary_path); + LTTNG_ASSERT(a->binary_path); + LTTNG_ASSERT(b->binary_path); if (strcmp(a->binary_path, b->binary_path)) { goto end; } @@ -406,6 +464,7 @@ lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_pat ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT; ret->equal = lttng_userspace_probe_location_tracepoint_is_equal; + ret->hash = lttng_userspace_probe_location_tracepoint_hash; goto end; error: @@ -484,8 +543,8 @@ lttng_userspace_probe_location_lookup_method_function_elf_copy( struct lttng_userspace_probe_location_lookup_method *parent = NULL; struct lttng_userspace_probe_location_lookup_method_elf *elf_method; - assert(lookup_method); - assert(lookup_method->type == + LTTNG_ASSERT(lookup_method); + LTTNG_ASSERT(lookup_method->type == LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF); elf_method = zmalloc(sizeof(*elf_method)); @@ -511,8 +570,8 @@ lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy( struct lttng_userspace_probe_location_lookup_method *parent = NULL; struct lttng_userspace_probe_location_lookup_method_sdt *sdt_method; - assert(lookup_method); - assert(lookup_method->type == + LTTNG_ASSERT(lookup_method); + LTTNG_ASSERT(lookup_method->type == LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT); sdt_method = zmalloc(sizeof(*sdt_method)); @@ -543,8 +602,8 @@ lttng_userspace_probe_location_function_copy( const char *function_name = NULL; struct lttng_userspace_probe_location_function *function_location; - assert(location); - assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION); + LTTNG_ASSERT(location); + LTTNG_ASSERT(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION); function_location = container_of( location, typeof(*function_location), parent); @@ -617,8 +676,8 @@ lttng_userspace_probe_location_tracepoint_copy( const char *provider_name = NULL; struct lttng_userspace_probe_location_tracepoint *tracepoint_location; - assert(location); - assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT); + LTTNG_ASSERT(location); + LTTNG_ASSERT(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT); tracepoint_location = container_of( location, typeof(*tracepoint_location), parent); @@ -908,7 +967,7 @@ lttng_userspace_probe_location_get_lookup_method( { struct lttng_userspace_probe_location_lookup_method *ret = NULL; - assert(location); + LTTNG_ASSERT(location); switch (location->type) { case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION: ret = lttng_userspace_probe_location_function_get_lookup_method( @@ -958,8 +1017,8 @@ int lttng_userspace_probe_location_function_serialize( struct lttng_userspace_probe_location_function *location_function; struct lttng_userspace_probe_location_function_comm location_function_comm; - assert(location); - assert(lttng_userspace_probe_location_get_type(location) == + LTTNG_ASSERT(location); + LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location) == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION); location_function = container_of(location, @@ -1035,8 +1094,8 @@ int lttng_userspace_probe_location_tracepoint_serialize( struct lttng_userspace_probe_location_tracepoint *location_tracepoint; struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm; - assert(location); - assert(lttng_userspace_probe_location_get_type(location) == + LTTNG_ASSERT(location); + LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location) == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT); location_tracepoint = container_of(location, @@ -1121,7 +1180,6 @@ end: return ret; } -LTTNG_HIDDEN int lttng_userspace_probe_location_serialize( const struct lttng_userspace_probe_location *location, struct lttng_payload *payload) @@ -1189,7 +1247,7 @@ int lttng_userspace_probe_location_function_create_from_payload( size_t expected_size; struct fd_handle *binary_fd_handle = lttng_payload_view_pop_fd_handle(view); - assert(location); + LTTNG_ASSERT(location); if (view->buffer.size < sizeof(*location_function_comm)) { ret = -LTTNG_ERR_INVALID; @@ -1272,7 +1330,7 @@ int lttng_userspace_probe_location_tracepoint_create_from_payload( size_t expected_size; struct fd_handle *binary_fd_handle = lttng_payload_view_pop_fd_handle(view); - assert(location); + LTTNG_ASSERT(location); if (!binary_fd_handle) { ret = -LTTNG_ERR_INVALID; @@ -1323,18 +1381,21 @@ int lttng_userspace_probe_location_tracepoint_create_from_payload( probe_name = lttng_strndup(probe_name_src, LTTNG_SYMBOL_NAME_LEN); if (!probe_name) { - PERROR("lttng_strndup"); + PERROR("Failed to allocate probe name"); + ret = -LTTNG_ERR_INVALID; goto end; } provider_name = lttng_strndup(provider_name_src, LTTNG_SYMBOL_NAME_LEN); if (!provider_name) { - PERROR("lttng_strndup"); + PERROR("Failed to allocate provider name"); + ret = -LTTNG_ERR_INVALID; goto end; } - binary_path = lttng_strndup(binary_path_src, LTTNG_SYMBOL_NAME_LEN); + binary_path = lttng_strndup(binary_path_src, LTTNG_PATH_MAX); if (!binary_path) { - PERROR("lttng_strndup"); + PERROR("Failed to allocate binary path"); + ret = -LTTNG_ERR_INVALID; goto end; } @@ -1370,8 +1431,8 @@ int lttng_userspace_probe_location_lookup_method_create_from_payload( struct lttng_userspace_probe_location_lookup_method_comm *lookup_comm; enum lttng_userspace_probe_location_lookup_method_type type; - assert(view); - assert(lookup_method); + LTTNG_ASSERT(view); + LTTNG_ASSERT(lookup_method); if (view->buffer.size < sizeof(*lookup_comm)) { ret = -LTTNG_ERR_INVALID; @@ -1411,7 +1472,6 @@ end: return ret; } -LTTNG_HIDDEN int lttng_userspace_probe_location_create_from_payload( struct lttng_payload_view *view, struct lttng_userspace_probe_location **location) @@ -1425,8 +1485,8 @@ int lttng_userspace_probe_location_create_from_payload( lttng_payload_view_from_view( view, 0, sizeof(*probe_location_comm)); - assert(view); - assert(location); + LTTNG_ASSERT(view); + LTTNG_ASSERT(location); lookup_method = NULL; @@ -1489,7 +1549,7 @@ int lttng_userspace_probe_location_create_from_payload( goto end; } - assert(lookup_method); + LTTNG_ASSERT(lookup_method); (*location)->lookup_method = lookup_method; lookup_method = NULL; ret += consumed; @@ -1505,8 +1565,8 @@ int lttng_userspace_probe_location_function_set_binary_fd_handle( int ret = 0; struct lttng_userspace_probe_location_function *function_location; - assert(location); - assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION); + LTTNG_ASSERT(location); + LTTNG_ASSERT(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION); function_location = container_of(location, struct lttng_userspace_probe_location_function, parent); @@ -1524,8 +1584,8 @@ int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle( int ret = 0; struct lttng_userspace_probe_location_tracepoint *tracepoint_location; - assert(location); - assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT); + LTTNG_ASSERT(location); + LTTNG_ASSERT(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT); tracepoint_location = container_of(location, struct lttng_userspace_probe_location_tracepoint, parent); @@ -1549,7 +1609,7 @@ int lttng_userspace_probe_location_function_flatten( int storage_needed = 0; int ret; - assert(location); + LTTNG_ASSERT(location); if (location->lookup_method && location->lookup_method->type != LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF) { @@ -1560,8 +1620,8 @@ int lttng_userspace_probe_location_function_flatten( probe_function = container_of(location, struct lttng_userspace_probe_location_function, parent); - assert(probe_function->function_name); - assert(probe_function->binary_path); + LTTNG_ASSERT(probe_function->function_name); + LTTNG_ASSERT(probe_function->binary_path); storage_needed += sizeof(struct lttng_userspace_probe_location_function); @@ -1575,7 +1635,7 @@ int lttng_userspace_probe_location_function_flatten( * the next structure in the buffer probably needs to be * aligned too (depending on the arch). */ - padding_needed = ALIGN_TO(storage_needed, sizeof(uint64_t)) - storage_needed; + padding_needed = lttng_align_ceil(storage_needed, sizeof(uint64_t)) - storage_needed; storage_needed += padding_needed; if (location->lookup_method) { @@ -1673,7 +1733,7 @@ int lttng_userspace_probe_location_tracepoint_flatten( char *flat_probe_start; int ret = 0; - assert(location); + LTTNG_ASSERT(location); /* Only SDT tracepoints are supported at the moment */ if (location->lookup_method && location->lookup_method->type != @@ -1684,9 +1744,9 @@ int lttng_userspace_probe_location_tracepoint_flatten( probe_tracepoint = container_of(location, struct lttng_userspace_probe_location_tracepoint, parent); - assert(probe_tracepoint->probe_name); - assert(probe_tracepoint->provider_name); - assert(probe_tracepoint->binary_path); + LTTNG_ASSERT(probe_tracepoint->probe_name); + LTTNG_ASSERT(probe_tracepoint->provider_name); + LTTNG_ASSERT(probe_tracepoint->binary_path); /* Compute the storage space needed to flatten the probe location */ storage_needed += sizeof(struct lttng_userspace_probe_location_tracepoint); @@ -1703,7 +1763,7 @@ int lttng_userspace_probe_location_tracepoint_flatten( * the next structure in the buffer probably needs to be * aligned too (depending on the arch). */ - padding_needed = ALIGN_TO(storage_needed, sizeof(uint64_t)) - storage_needed; + padding_needed = lttng_align_ceil(storage_needed, sizeof(uint64_t)) - storage_needed; storage_needed += padding_needed; if (location->lookup_method) { @@ -1799,7 +1859,6 @@ end: return ret; } -LTTNG_HIDDEN int lttng_userspace_probe_location_flatten( const struct lttng_userspace_probe_location *location, struct lttng_dynamic_buffer *buffer) @@ -1827,7 +1886,6 @@ end: return ret; } -LTTNG_HIDDEN struct lttng_userspace_probe_location *lttng_userspace_probe_location_copy( const struct lttng_userspace_probe_location *location) { @@ -1862,7 +1920,6 @@ err: return new_location; } -LTTNG_HIDDEN bool lttng_userspace_probe_location_lookup_method_is_equal( const struct lttng_userspace_probe_location_lookup_method *a, const struct lttng_userspace_probe_location_lookup_method *b) @@ -1887,7 +1944,6 @@ end: return is_equal; } -LTTNG_HIDDEN bool lttng_userspace_probe_location_is_equal( const struct lttng_userspace_probe_location *a, const struct lttng_userspace_probe_location *b) @@ -1916,3 +1972,289 @@ bool lttng_userspace_probe_location_is_equal( end: return is_equal; } + +unsigned long lttng_userspace_probe_location_hash( + const struct lttng_userspace_probe_location *location) +{ + return location->hash(location); +} + +enum lttng_error_code lttng_userspace_probe_location_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer) +{ + typedef enum lttng_error_code (*mi_fp)( + const struct lttng_userspace_probe_location *, + struct mi_writer *); + + int ret; + enum lttng_error_code ret_code; + mi_fp mi_function = NULL; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(writer); + + switch (lttng_userspace_probe_location_get_type(location)) { + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION: + mi_function = lttng_userspace_probe_location_function_mi_serialize; + break; + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT: + mi_function = lttng_userspace_probe_location_tracepoint_mi_serialize; + break; + default: + abort(); + break; + } + + /* Open userspace probe location element. */ + ret = mi_lttng_writer_open_element( + writer, mi_lttng_element_userspace_probe_location); + if (ret) { + goto mi_error; + } + + /* Underlying user space probe location. */ + ret_code = mi_function(location, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close userspace probe location element. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +} + +enum lttng_error_code lttng_userspace_probe_location_lookup_method_mi_serialize( + const struct lttng_userspace_probe_location_lookup_method + *method, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + const char *type_element_str; + + LTTNG_ASSERT(method); + LTTNG_ASSERT(writer); + + switch (lttng_userspace_probe_location_lookup_method_get_type(method)) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT: + type_element_str = + mi_lttng_element_userspace_probe_location_lookup_method_function_default; + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF: + type_element_str = + mi_lttng_element_userspace_probe_location_lookup_method_function_elf; + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT: + type_element_str = + mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt; + break; + default: + abort(); + break; + } + + /* Open userspace probe location lookup method element. */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_userspace_probe_location_lookup_method); + if (ret) { + goto mi_error; + } + + /* User space probe location lookup method empty element. */ + ret = mi_lttng_writer_open_element(writer, type_element_str); + if (ret) { + goto mi_error; + } + + /* Close userspace probe location lookup method element. */ + ret = mi_lttng_close_multi_element(writer, 2); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +} + +static enum lttng_error_code lttng_userspace_probe_location_tracepoint_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + const char *probe_name = NULL; + const char *provider_name = NULL; + const char *binary_path = NULL; + const struct lttng_userspace_probe_location_lookup_method + *lookup_method = NULL; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(writer); + + probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name( + location); + provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name( + location); + binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path( + location); + lookup_method = lttng_userspace_probe_location_tracepoint_get_lookup_method( + location); + + /* Open userspace probe location tracepoint element. */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_userspace_probe_location_tracepoint); + if (ret) { + goto mi_error; + } + + /* Probe name. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_tracepoint_probe_name, + probe_name); + if (ret) { + goto mi_error; + } + + /* Provider name. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_tracepoint_provider_name, + provider_name); + if (ret) { + goto mi_error; + } + + /* Binary path. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_binary_path, + binary_path); + if (ret) { + goto mi_error; + } + + /* The lookup method. */ + ret_code = lttng_userspace_probe_location_lookup_method_mi_serialize( + lookup_method, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close userspace probe location tracepoint. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +} + +static enum lttng_error_code lttng_userspace_probe_location_function_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + const char *function_name = NULL; + const char *binary_path = NULL; + const char *instrumentation_type_str = NULL; + enum lttng_userspace_probe_location_function_instrumentation_type + instrumentation_type; + const struct lttng_userspace_probe_location_lookup_method + *lookup_method = NULL; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(writer); + + function_name = lttng_userspace_probe_location_function_get_function_name( + location); + binary_path = lttng_userspace_probe_location_function_get_binary_path( + location); + instrumentation_type = + lttng_userspace_probe_location_function_get_instrumentation_type( + location); + lookup_method = lttng_userspace_probe_location_function_get_lookup_method( + location); + + switch (instrumentation_type) { + case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY: + instrumentation_type_str = + mi_lttng_userspace_probe_location_function_instrumentation_type_entry; + break; + default: + abort(); + break; + } + + /* Open userspace probe location function element. */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_userspace_probe_location_function); + if (ret) { + goto mi_error; + } + + /* Function name. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_function_name, + function_name); + if (ret) { + goto mi_error; + } + + /* Binary path. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_binary_path, + binary_path); + if (ret) { + goto mi_error; + } + + /* Instrumentation type. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_function_instrumentation_type, + instrumentation_type_str); + if (ret) { + goto mi_error; + } + + /* The lookup method. */ + ret_code = lttng_userspace_probe_location_lookup_method_mi_serialize( + lookup_method, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close userspace probe location function element. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +}