X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fuserspace-probe.c;h=8c6adaca620b62d6fb7a47a94cbf67bffb051d7f;hp=e764d137b9f3b8c8c7b973a1a3787c84986ccc9e;hb=2aa28610e2bff8b40ad2810cbf0c7ea3b79e106d;hpb=d7ee7196fb236c616cc64de0486cf8d659e235a2 diff --git a/src/common/userspace-probe.c b/src/common/userspace-probe.c index e764d137b..8c6adaca6 100644 --- a/src/common/userspace-probe.c +++ b/src/common/userspace-probe.c @@ -1,27 +1,20 @@ /* - * Copyright (C) 2017 - Jérémie Galarneau + * Copyright (C) 2017 Jérémie Galarneau * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License, version 2.1 only, - * as published by the Free Software Foundation. + * SPDX-License-Identifier: LGPL-2.1-only * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include +#include #include #include -#include #include #include #include +#include +#include +#include enum lttng_userspace_probe_location_lookup_method_type lttng_userspace_probe_location_lookup_method_get_type( @@ -154,6 +147,86 @@ void lttng_userspace_probe_location_destroy( } } +/* Compare two file descriptors based on their inode and device numbers. */ +static bool fd_is_equal(int a, int b) +{ + int ret; + bool is_equal = false; + struct stat a_stat, b_stat; + + if (a < 0 && b >= 0) { + goto end; + } + + if (b < 0 && a >= 0) { + goto end; + } + + if (a < 0 && b < 0) { + if (a == -1 && b == -1) { + is_equal = true; + goto end; + } + + /* Invalid state, abort. */ + abort(); + } + + /* Both are valid file descriptors. */ + ret = fstat(a, &a_stat); + if (ret) { + PERROR("Failed to fstat userspace probe location binary fd %d", + a); + goto end; + } + + ret = fstat(b, &b_stat); + if (ret) { + PERROR("Failed to fstat userspace probe location binary fd %d", + b); + goto end; + } + + is_equal = (a_stat.st_ino == b_stat.st_ino) && + (a_stat.st_dev == b_stat.st_dev); + +end: + return is_equal; +} + +static bool lttng_userspace_probe_location_function_is_equal( + const struct lttng_userspace_probe_location *_a, + const struct lttng_userspace_probe_location *_b) +{ + bool is_equal = false; + struct lttng_userspace_probe_location_function *a, *b; + + a = container_of(_a, struct lttng_userspace_probe_location_function, + parent); + b = container_of(_b, struct lttng_userspace_probe_location_function, + parent); + + if (a->instrumentation_type != b->instrumentation_type) { + goto end; + } + + assert(a->function_name); + assert(b->function_name); + if (strcmp(a->function_name, b->function_name)) { + goto end; + } + + assert(a->binary_path); + assert(b->binary_path); + if (strcmp(a->binary_path, b->binary_path)) { + goto end; + } + + is_equal = fd_is_equal(a->binary_fd, b->binary_fd); +end: + return is_equal; +} + static struct lttng_userspace_probe_location * lttng_userspace_probe_location_function_create_no_check(const char *binary_path, const char *function_name, @@ -202,6 +275,7 @@ lttng_userspace_probe_location_function_create_no_check(const char *binary_path, ret = &location->parent; ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION; + ret->equal = lttng_userspace_probe_location_function_is_equal; goto end; error: @@ -216,6 +290,42 @@ end: return ret; } +static bool lttng_userspace_probe_location_tracepoint_is_equal( + const struct lttng_userspace_probe_location *_a, + const struct lttng_userspace_probe_location *_b) +{ + bool is_equal = false; + struct lttng_userspace_probe_location_tracepoint *a, *b; + + a = container_of(_a, struct lttng_userspace_probe_location_tracepoint, + parent); + b = container_of(_b, struct lttng_userspace_probe_location_tracepoint, + parent); + + assert(a->probe_name); + assert(b->probe_name); + if (strcmp(a->probe_name, b->probe_name)) { + goto end; + } + + assert(a->provider_name); + assert(b->provider_name); + if (strcmp(a->provider_name, b->provider_name)) { + goto end; + } + + assert(a->binary_path); + assert(b->binary_path); + if (strcmp(a->binary_path, b->binary_path)) { + goto end; + } + + is_equal = fd_is_equal(a->binary_fd, b->binary_fd); + +end: + return is_equal; +} + 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, @@ -271,11 +381,13 @@ lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_pat ret = &location->parent; ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT; + ret->equal = lttng_userspace_probe_location_tracepoint_is_equal; 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"); @@ -1105,12 +1217,14 @@ int lttng_userspace_probe_location_function_create_from_buffer( function_name = lttng_strndup(function_name_src, LTTNG_SYMBOL_NAME_LEN); if (!function_name) { PERROR("lttng_strndup"); + ret = -LTTNG_ERR_NOMEM; goto end; } binary_path = lttng_strndup(binary_path_src, LTTNG_PATH_MAX); if (!binary_path) { PERROR("lttng_strndup"); + ret = -LTTNG_ERR_NOMEM; goto end; } @@ -1720,3 +1834,58 @@ struct lttng_userspace_probe_location *lttng_userspace_probe_location_copy( 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) +{ + bool is_equal = false; + + if (!a || !b) { + goto end; + } + + if (a == b) { + is_equal = true; + goto end; + } + + if (a->type != b->type) { + goto end; + } + + is_equal = true; +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) +{ + bool is_equal = false; + + if (!a || !b) { + goto end; + } + + if (a == b) { + is_equal = true; + goto end; + } + + if (!lttng_userspace_probe_location_lookup_method_is_equal( + a->lookup_method, b->lookup_method)) { + goto end; + } + + if (a->type != b->type) { + goto end; + } + + is_equal = a->equal ? a->equal(a, b) : true; +end: + return is_equal; +}