Add lttng_userspace_probe_location copy constructor
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Wed, 27 Jun 2018 20:22:58 +0000 (16:22 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 24 Aug 2018 19:52:24 +0000 (15:52 -0400)
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/lttng/userspace-probe-internal.h
include/lttng/userspace-probe.h
src/common/userspace-probe.c

index 3e8eecbcfc15723a07f406b5ba0db283f7e47644..9c580323c822be55cdcef4ff8eb7fe3321921eef 100644 (file)
@@ -111,4 +111,8 @@ int lttng_userspace_probe_location_flatten(
                const struct lttng_userspace_probe_location *location,
                struct lttng_dynamic_buffer *buffer);
 
+LTTNG_HIDDEN
+struct lttng_userspace_probe_location *lttng_userspace_probe_location_copy(
+               const struct lttng_userspace_probe_location *location);
+
 #endif /* LTTNG_USERSPACE_PROBE_INTERNAL_H */
index 0168ac2fd7382e903882a2dbd0fbaeaecdfe4012..4c92c36b2d0abc9956cf7f97b41acc9d86cdc760 100644 (file)
@@ -104,6 +104,13 @@ extern const char *lttng_userspace_probe_location_function_get_binary_path(
 extern const char *lttng_userspace_probe_location_function_get_function_name(
                const struct lttng_userspace_probe_location *location);
 
+/*
+ * Get the FD to the target binary file to the probe location of the function
+ * type.
+ */
+extern int lttng_userspace_probe_location_function_get_binary_fd(
+               const struct lttng_userspace_probe_location *location);
+
 /*
  * Get the lookup method of the given userspace probe location.
  * Returns NULL if the probe location type is unsupported.
index 106fdadf6e82990b19d2f103c5b128d131284648..78cf43b27e50d666a6b0cd2aeef3295bed497e7c 100644 (file)
@@ -207,6 +207,119 @@ end:
        return ret;
 }
 
+static struct lttng_userspace_probe_location_lookup_method *
+lttng_userspace_probe_location_lookup_method_function_elf_copy(
+               const struct lttng_userspace_probe_location_lookup_method *lookup_method)
+{
+       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_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF);
+
+       elf_method = zmalloc(sizeof(*elf_method));
+       if (!elf_method) {
+               PERROR("Error allocating ELF userspace probe lookup method");
+               goto error;
+       }
+
+       elf_method->parent.type = lookup_method->type;
+       parent = &elf_method->parent;
+
+       goto end;
+error:
+       parent = NULL;
+end:
+       return parent;
+}
+
+static struct lttng_userspace_probe_location *
+lttng_userspace_probe_location_function_copy(
+               const struct lttng_userspace_probe_location *location)
+{
+       enum lttng_userspace_probe_location_lookup_method_type lookup_type;
+       struct lttng_userspace_probe_location *new_location = NULL;
+       struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
+       char *binary_path = NULL;
+       char *function_name = NULL;
+       int fd;
+
+       assert(location);
+       assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION);
+
+        /* Duplicate probe location fields */
+       binary_path =
+               lttng_strndup(lttng_userspace_probe_location_function_get_binary_path(location),
+                               LTTNG_PATH_MAX);
+       if (!binary_path) {
+               goto error;
+       }
+
+       function_name =
+               lttng_strndup(lttng_userspace_probe_location_function_get_function_name(location),
+                               LTTNG_SYMBOL_NAME_LEN);
+       if (!function_name) {
+               PERROR("Error duplicating function name string");
+               goto error;
+       }
+
+       /* Duplicate the binary fd */
+       fd = dup(lttng_userspace_probe_location_function_get_binary_fd(location));
+       if (fd == -1) {
+               PERROR("Error duplicating file descriptor to binary");
+               goto error;
+       }
+
+       /*
+        * Duplicate probe location method fields
+        */
+       lookup_type = lttng_userspace_probe_location_lookup_method_get_type(
+                       location->lookup_method);
+       switch (lookup_type) {
+       case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
+               lookup_method =
+                       lttng_userspace_probe_location_lookup_method_function_elf_copy(
+                                       location->lookup_method);
+               if (!lookup_method) {
+                       goto close_fd;
+               }
+               break;
+       default:
+               /* Invalid probe location lookup method. */
+               goto close_fd;
+       }
+
+       /* Create the probe_location */
+       new_location = lttng_userspace_probe_location_function_create_no_check(
+                       binary_path, function_name, lookup_method, true);
+       if (!new_location) {
+               goto destroy_lookup_method;
+       }
+
+       /* Set the duplicated fd to the new probe_location */
+       if (lttng_userspace_probe_location_function_set_binary_fd(new_location, fd) < 0) {
+               goto destroy_probe_location;
+       }
+
+       goto end;
+
+destroy_probe_location:
+       lttng_userspace_probe_location_destroy(new_location);
+destroy_lookup_method:
+       lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
+close_fd:
+       if (close(fd) < 0) {
+               PERROR("Error closing duplicated file descriptor in error path");
+       }
+error:
+       free(function_name);
+       free(binary_path);
+       new_location = NULL;
+end:
+       return new_location;
+}
+
 const char *lttng_userspace_probe_location_function_get_binary_path(
                const struct lttng_userspace_probe_location *location)
 {
@@ -805,3 +918,31 @@ int lttng_userspace_probe_location_flatten(
 end:
        return ret;
 }
+
+LTTNG_HIDDEN
+struct lttng_userspace_probe_location *lttng_userspace_probe_location_copy(
+               const struct lttng_userspace_probe_location *location)
+{
+       struct lttng_userspace_probe_location *new_location = NULL;
+       enum lttng_userspace_probe_location_type type;
+
+       if (!location) {
+               goto err;
+       }
+
+       type = lttng_userspace_probe_location_get_type(location);
+       switch (type) {
+       case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
+               new_location =
+                       lttng_userspace_probe_location_function_copy(location);
+               if (!new_location) {
+                       goto err;
+               }
+               break;
+       default:
+               new_location = NULL;
+               goto err;
+       }
+err:
+       return new_location;
+}
This page took 0.042174 seconds and 5 git commands to generate.