Fix: Make sure we have all the metadata streams before adding new traces
[babeltrace.git] / lib / bin-info.c
index 14b0dea3de1caf822844e1d80e456104fe7f4390..65f9051fb00efe087c24c1fe9f66696cf081ebd1 100644 (file)
@@ -41,6 +41,7 @@
 #include <babeltrace/crc32.h>
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/utils.h>
+#include <errno.h>
 
 /*
  * An address printed in hex is at most 20 bytes (16 for 64-bits +
@@ -188,7 +189,7 @@ error:
  *
  * @param bin  bin_info instance for which to set DWARF info
  * @param path Presumed location of the DWARF info
- * @returns    0 on success, -1 on failure
+ * @returns    0 on success, negative value on failure
  */
 static
 int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path)
@@ -203,6 +204,7 @@ int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path)
 
        fd = open(path, O_RDONLY);
        if (fd < 0) {
+               fd = -errno;
                goto error;
        }
 
@@ -236,12 +238,15 @@ int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path)
        return 0;
 
 error:
-       close(fd);
+       if (fd >= 0) {
+               close(fd);
+               fd = -1;
+       }
        dwarf_end(dwarf_info);
        g_free(dwarf_info);
        free(cu);
 
-       return -1;
+       return fd;
 }
 
 /**
@@ -266,8 +271,7 @@ int bin_info_set_dwarf_info_build_id(struct bin_info *bin)
 
        dbg_dir = opt_debug_info_dir ? : DEFAULT_DEBUG_DIR;
 
-       /* 2 characters per byte printed in hex, +1 for '/' and +1 for
-        * '\0' */
+       /* 2 characters per byte printed in hex, +1 for '/' and +1 for '\0' */
        build_id_file_len = (2 * bin->build_id_len) + 1 +
                        strlen(BUILD_ID_SUFFIX) + 1;
        build_id_file = malloc(build_id_file_len);
@@ -325,12 +329,12 @@ int is_valid_debug_file(char *path, uint32_t crc)
        uint32_t _crc = 0;
 
        if (!path) {
-               goto end;
+               goto end_noclose;
        }
 
        fd = open(path, O_RDONLY);
        if (fd < 0) {
-               goto end;
+               goto end_noclose;
        }
 
        ret = crc32(fd, &_crc);
@@ -343,6 +347,7 @@ int is_valid_debug_file(char *path, uint32_t crc)
 
 end:
        close(fd);
+end_noclose:
        return ret;
 }
 
@@ -437,7 +442,7 @@ found:
  * Initialize the DWARF info for a given executable.
  *
  * @param bin  bin_info instance
- * @returns    0 on success, -1 on failure
+ * @returns    0 on success, negative value on failure
  */
 static
 int bin_info_set_dwarf_info(struct bin_info *bin)
@@ -445,7 +450,8 @@ int bin_info_set_dwarf_info(struct bin_info *bin)
        int ret = 0;
 
        if (!bin) {
-               goto error;
+               ret = -1;
+               goto end;
        }
 
        /* First try to set the DWARF info from the ELF file */
@@ -468,8 +474,6 @@ int bin_info_set_dwarf_info(struct bin_info *bin)
                goto end;
        }
 
-error:
-       ret = -1;
 end:
        return ret;
 }
@@ -478,12 +482,12 @@ end:
  * Initialize the ELF file for a given executable.
  *
  * @param bin  bin_info instance
- * @returns    0 on success, -1 on failure
+ * @returns    0 on success, negative value on error.
  */
 static
 int bin_info_set_elf_file(struct bin_info *bin)
 {
-       int elf_fd;
+       int elf_fd = -1;
        Elf *elf_file = NULL;
 
        if (!bin) {
@@ -492,6 +496,7 @@ int bin_info_set_elf_file(struct bin_info *bin)
 
        elf_fd = open(bin->elf_path, O_RDONLY);
        if (elf_fd < 0) {
+               elf_fd = -errno;
                printf_verbose("Failed to open %s\n", bin->elf_path);
                goto error;
        }
@@ -513,12 +518,14 @@ int bin_info_set_elf_file(struct bin_info *bin)
        return 0;
 
 error:
-       close(elf_fd);
+       if (elf_fd >= 0) {
+               close(elf_fd);
+               elf_fd = -1;
+       }
        elf_end(elf_file);
-       return -1;
+       return elf_fd;
 }
 
-
 BT_HIDDEN
 void source_location_destroy(struct source_location *src_loc)
 {
@@ -529,6 +536,7 @@ void source_location_destroy(struct source_location *src_loc)
        free(src_loc->filename);
        g_free(src_loc);
 }
+
 /**
  * Append a string representation of an address offset to an existing
  * string.
@@ -759,7 +767,7 @@ int bin_info_lookup_elf_function_name(struct bin_info *bin, uint64_t addr,
 error:
        g_free(shdr);
        g_free(sym);
-       return -1;
+       return ret;
 }
 
 /**
@@ -823,11 +831,13 @@ int bin_info_lookup_cu_function_name(struct bt_dwarf_cu *cu, uint64_t addr,
 
                ret = dwarf_lowpc(die->dwarf_die, &low_addr);
                if (ret) {
+                       free(die_name);
                        goto error;
                }
 
                ret = bin_info_append_offset_str(die_name, low_addr, addr,
                                                func_name);
+               free(die_name);
                if (ret) {
                        goto error;
                }
@@ -912,6 +922,7 @@ int bin_info_lookup_function_name(struct bin_info *bin, uint64_t addr,
        if (!bin->dwarf_info && !bin->is_elf_only) {
                ret = bin_info_set_dwarf_info(bin);
                if (ret) {
+                       printf_verbose("Failed to set bin dwarf info, falling back to ELF lookup.\n");
                        /* Failed to set DWARF info, fallback to ELF. */
                        bin->is_elf_only = true;
                }
@@ -931,12 +942,10 @@ int bin_info_lookup_function_name(struct bin_info *bin, uint64_t addr,
 
        if (bin->is_elf_only) {
                ret = bin_info_lookup_elf_function_name(bin, addr, &_func_name);
+               printf_verbose("Failed to lookup function name (elf), error %i\n", ret);
        } else {
                ret = bin_info_lookup_dwarf_function_name(bin, addr, &_func_name);
-       }
-
-       if (ret || !_func_name) {
-               goto error;
+               printf_verbose("Failed to lookup function name (dwarf), error %i\n", ret);
        }
 
        *func_name = _func_name;
@@ -1028,7 +1037,7 @@ int bin_info_child_die_has_address(struct bt_dwarf_die *die, uint64_t addr, bool
                                goto error;
                        }
 
-                       if (contains) {
+                       if (_contains) {
                                goto end;
                        }
                }
This page took 0.02556 seconds and 4 git commands to generate.