static struct lttng_userspace_probe_location * lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path, const char *provider_name, const char *probe_name, struct lttng_userspace_probe_location_lookup_method *lookup_method, bool open_binary) { int binary_fd = -1; char *probe_name_copy = NULL; char *provider_name_copy = NULL; char *binary_path_copy = NULL; struct lttng_userspace_probe_location *ret = NULL; struct lttng_userspace_probe_location_tracepoint *location; if (open_binary) { binary_fd = open(binary_path, O_RDONLY); if (binary_fd < 0) { PERROR("open"); goto error; } } else { binary_fd = -1; } probe_name_copy = lttng_strndup(probe_name, LTTNG_SYMBOL_NAME_LEN); if (!probe_name_copy) { PERROR("lttng_strndup"); goto error; } provider_name_copy = lttng_strndup(provider_name, LTTNG_SYMBOL_NAME_LEN); if (!provider_name_copy) { PERROR("lttng_strndup"); goto error; } binary_path_copy = lttng_strndup(binary_path, LTTNG_PATH_MAX); if (!binary_path_copy) { PERROR("lttng_strndup"); goto error; } location = zmalloc(sizeof(*location)); if (!location) { PERROR("zmalloc"); goto error; } location->probe_name = probe_name_copy; location->provider_name = provider_name_copy; location->binary_path = binary_path_copy; location->binary_fd = binary_fd; ret = &location->parent; ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT; goto end; error: free(probe_name_copy); free(provider_name_copy); free(binary_path_copy); if (binary_fd >= 0) { if (close(binary_fd)) { PERROR("Error closing binary fd in error path"); } } end: return ret; }
static int lttng_userspace_probe_location_tracepoint_create_from_buffer( const struct lttng_buffer_view *buffer, struct lttng_userspace_probe_location **location) { struct lttng_userspace_probe_location_tracepoint_comm *location_tracepoint_comm; const char *probe_name_src, *provider_name_src, *binary_path_src; char *probe_name = NULL, *provider_name = NULL, *binary_path = NULL; int ret = 0; assert(buffer); assert(buffer->data); assert(location); location_tracepoint_comm = (struct lttng_userspace_probe_location_tracepoint_comm *) buffer->data; const size_t expected_size = sizeof(*location_tracepoint_comm) + location_tracepoint_comm->probe_name_len + location_tracepoint_comm->provider_name_len + location_tracepoint_comm->binary_path_len; if (buffer->size < expected_size) { ret = -LTTNG_ERR_INVALID; goto end; } probe_name_src = buffer->data + sizeof(*location_tracepoint_comm); provider_name_src = probe_name_src + location_tracepoint_comm->probe_name_len; binary_path_src = provider_name_src + location_tracepoint_comm->provider_name_len; if (probe_name_src[location_tracepoint_comm->probe_name_len - 1] != '\0') { ret = -LTTNG_ERR_INVALID; goto end; } if (provider_name_src[location_tracepoint_comm->provider_name_len - 1] != '\0') { ret = -LTTNG_ERR_INVALID; goto end; } if (binary_path_src[location_tracepoint_comm->binary_path_len - 1] != '\0') { ret = -LTTNG_ERR_INVALID; goto end; } probe_name = lttng_strndup(probe_name_src, LTTNG_SYMBOL_NAME_LEN); if (!probe_name) { PERROR("lttng_strndup"); goto end; } provider_name = lttng_strndup(provider_name_src, LTTNG_SYMBOL_NAME_LEN); if (!provider_name) { PERROR("lttng_strndup"); goto end; } binary_path = lttng_strndup(binary_path_src, LTTNG_SYMBOL_NAME_LEN); if (!binary_path) { PERROR("lttng_strndup"); goto end; } *location = lttng_userspace_probe_location_tracepoint_create_no_check( binary_path, provider_name, probe_name, NULL, false); if (!(*location)) { ret = -LTTNG_ERR_INVALID; goto end; } ret = (int) expected_size; end: free(probe_name); free(provider_name); free(binary_path); return ret; }
static struct lttng_userspace_probe_location * lttng_userspace_probe_location_function_create_no_check(const char *binary_path, const char *function_name, struct lttng_userspace_probe_location_lookup_method *lookup_method, bool open_binary) { int binary_fd = -1; char *function_name_copy = NULL, *binary_path_copy = NULL; struct lttng_userspace_probe_location *ret = NULL; struct lttng_userspace_probe_location_function *location; if (open_binary) { binary_fd = open(binary_path, O_RDONLY); if (binary_fd < 0) { PERROR("Error opening the binary"); goto error; } } else { binary_fd = -1; } function_name_copy = lttng_strndup(function_name, LTTNG_SYMBOL_NAME_LEN); if (!function_name_copy) { PERROR("Error duplicating the function name"); goto error; } binary_path_copy = lttng_strndup(binary_path, LTTNG_PATH_MAX); if (!binary_path_copy) { PERROR("Error duplicating the function name"); goto error; } location = zmalloc(sizeof(*location)); if (!location) { PERROR("Error allocating userspace probe location"); goto error; } location->function_name = function_name_copy; location->binary_path = binary_path_copy; location->binary_fd = binary_fd; location->instrumentation_type = LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY; ret = &location->parent; ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION; goto end; error: free(function_name_copy); free(binary_path_copy); if (binary_fd >= 0) { if (close(binary_fd)) { PERROR("Error closing binary fd in error path"); } } end: return ret; }
/* * Compare list of exclusions against an event name. * Return a list of legal exclusion names. * Produce an error or a warning about others (depending on the situation) */ static int check_exclusion_subsets(const char *event_name, const char *exclusions, int *exclusion_count_ptr, char ***exclusion_list_ptr) { const char *excluder_ptr; const char *event_ptr; const char *next_excluder; int excluder_length; int exclusion_count = 0; char **exclusion_list = NULL; int ret = CMD_SUCCESS; if (event_name[strlen(event_name) - 1] != '*') { ERR("Event %s: Excluders can only be used with wildcarded events", event_name); goto error; } next_excluder = exclusions; while (*next_excluder != 0) { event_ptr = event_name; excluder_ptr = next_excluder; excluder_length = strcspn(next_excluder, ","); /* Scan both the excluder and the event letter by letter */ while (1) { char e, x; e = *event_ptr; x = *excluder_ptr; if (x == '*') { /* Event is a subset of the excluder */ ERR("Event %s: %.*s excludes all events from %s", event_name, excluder_length, next_excluder, event_name); goto error; } if (e == '*') { char *string; char **new_exclusion_list; /* Excluder is a proper subset of event */ string = lttng_strndup(next_excluder, excluder_length); if (!string) { PERROR("lttng_strndup error"); goto error; } new_exclusion_list = realloc(exclusion_list, sizeof(char *) * (exclusion_count + 1)); if (!new_exclusion_list) { PERROR("realloc"); free(string); goto error; } exclusion_list = new_exclusion_list; exclusion_count++; exclusion_list[exclusion_count - 1] = string; break; } if (x != e) { /* Excluder and event sets have no common elements */ WARN("Event %s: %.*s does not exclude any events from %s", event_name, excluder_length, next_excluder, event_name); break; } excluder_ptr++; event_ptr++; } /* next excluder */ next_excluder += excluder_length; if (*next_excluder == ',') { next_excluder++; } } goto end; error: while (exclusion_count--) { free(exclusion_list[exclusion_count]); } if (exclusion_list != NULL) { free(exclusion_list); } exclusion_list = NULL; exclusion_count = 0; ret = CMD_ERROR; end: *exclusion_count_ptr = exclusion_count; *exclusion_list_ptr = exclusion_list; return ret; }