SUBDIRS = include \
common \
ctfser \
+ fd-cache \
compat \
logging \
lib
doc/contributing-images/Makefile
doc/man/Makefile
doc/man/asciidoc-attrs.conf
+ fd-cache/Makefile
lib/Makefile
lib/prio_heap/Makefile
lib/plugin/Makefile
--- /dev/null
+AM_CPPFLAGS += -DINSTALL_LIBDIR=\"$(libdir)\"
+
+noinst_LTLIBRARIES = libbabeltrace-fd-cache.la
+
+libbabeltrace_fd_cache_la_SOURCES = \
+ fd-cache.c \
+ logging.c \
+ logging.h
--- /dev/null
+/*
+ * fd-cache.c
+ *
+ * Babeltrace - File descriptor cache
+ *
+ * Copyright 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * Author: Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FD-CACHE"
+#include "logging.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/fd-cache-internal.h>
+
+struct file_key {
+ uint64_t dev;
+ uint64_t ino;
+};
+
+struct fd_handle_internal {
+ struct bt_fd_cache_handle fd_handle;
+ uint64_t ref_count;
+ struct file_key *key;
+};
+
+static
+void fd_cache_handle_internal_destroy(
+ struct fd_handle_internal *internal_fd)
+{
+ if (!internal_fd) {
+ goto end;
+ }
+
+ if (internal_fd->fd_handle.fd >= 0) {
+ close(internal_fd->fd_handle.fd);
+ internal_fd->fd_handle.fd = -1;
+ }
+
+end:
+ g_free(internal_fd);
+}
+
+/*
+ * Using simple hash algorithm found on stackoverflow:
+ * https://stackoverflow.com/questions/664014/
+ */
+static inline
+uint64_t hash_uint64_t(uint64_t x) {
+ x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
+ x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
+ x = x ^ (x >> 31);
+ return x;
+}
+
+static
+guint file_key_hash(gconstpointer v)
+{
+ const struct file_key *fk = v;
+ return hash_uint64_t(fk->dev) ^ hash_uint64_t(fk->ino);
+}
+
+static
+gboolean file_key_equal(gconstpointer v1, gconstpointer v2)
+{
+ const struct file_key *fk1 = v1;
+ const struct file_key *fk2 = v2;
+
+ return (fk1->dev == fk2->dev) && (fk1->ino == fk2->ino);
+}
+
+static
+void file_key_destroy(gpointer data)
+{
+ struct file_key *fk = data;
+ g_free(fk);
+}
+
+BT_HIDDEN
+int bt_fd_cache_init(struct bt_fd_cache *fdc)
+{
+ int ret = 0;
+
+ fdc->cache = g_hash_table_new_full(file_key_hash, file_key_equal,
+ file_key_destroy, (GDestroyNotify) fd_cache_handle_internal_destroy);
+ if (!fdc->cache) {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+BT_HIDDEN
+void bt_fd_cache_fini(struct bt_fd_cache *fdc)
+{
+ BT_ASSERT(fdc->cache);
+ /*
+ * All handle should have been removed for the hashtable at this point.
+ */
+ BT_ASSERT(g_hash_table_size(fdc->cache) == 0);
+ g_hash_table_destroy(fdc->cache);
+
+ return;
+}
+
+BT_HIDDEN
+struct bt_fd_cache_handle *bt_fd_cache_get_handle(struct bt_fd_cache *fdc,
+ const char *path)
+{
+ struct fd_handle_internal *fd_internal = NULL;
+ struct stat statbuf;
+ struct file_key fk;
+ int ret;
+
+ ret = stat(path, &statbuf);
+ if (ret < 0) {
+ BT_LOGE_ERRNO("Failed to stat file", ": path=%s", path);
+ goto end;
+ }
+
+ /*
+ * Use the device number and inode number to uniquely identify a file.
+ * Even if the file as the same path, it may have been replaced so we
+ * must open a new FD for it. This replacement of file is more likely
+ * to happen with a lttng-live source component.
+ */
+ fk.dev = statbuf.st_dev;
+ fk.ino = statbuf.st_ino;
+
+ fd_internal = g_hash_table_lookup(fdc->cache, &fk);
+ if (!fd_internal) {
+ gboolean ret;
+ struct file_key *file_key;
+
+ int fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ BT_LOGE_ERRNO("Failed to open file", "path=%s", path);
+ goto error;
+ }
+
+ fd_internal = g_new0(struct fd_handle_internal, 1);
+ if (!fd_internal) {
+ BT_LOGE("Failed to allocate fd internal handle");
+ goto error;
+ }
+
+ file_key = g_new0(struct file_key, 1);
+ if (!fd_internal) {
+ BT_LOGE("Failed to allocate file key");
+ goto error;
+ }
+
+ *file_key = fk;
+
+ fd_internal->fd_handle.fd = fd;
+ fd_internal->ref_count = 0;
+ fd_internal->key = file_key;
+
+ /* Insert the newly created fd handle. */
+ ret = g_hash_table_insert(fdc->cache, fd_internal->key,
+ fd_internal);
+ BT_ASSERT(ret);
+ }
+
+ BT_ASSERT(fd_internal->ref_count >= 0);
+
+ fd_internal->ref_count++;
+ goto end;
+
+error:
+ fd_cache_handle_internal_destroy(fd_internal);
+ fd_internal = NULL;
+end:
+ return (struct bt_fd_cache_handle *) fd_internal;
+}
+
+BT_HIDDEN
+void bt_fd_cache_put_handle(struct bt_fd_cache *fdc,
+ struct bt_fd_cache_handle *handle)
+{
+ struct fd_handle_internal *fd_internal;
+
+ if (!handle) {
+ goto end;
+ }
+
+ fd_internal = (struct fd_handle_internal *) handle;
+
+ BT_ASSERT(fd_internal->ref_count > 0);
+
+ if (fd_internal->ref_count > 1) {
+ fd_internal->ref_count--;
+ } else {
+ gboolean ret;
+ int close_ret;
+
+ close_ret = close(fd_internal->fd_handle.fd);
+ if (close_ret == -1) {
+ BT_LOGW_ERRNO("Failed to close file descriptor",
+ ": fd=%d", fd_internal->fd_handle.fd);
+ }
+ ret = g_hash_table_remove(fdc->cache, fd_internal->key);
+ BT_ASSERT(ret);
+ }
+
+end:
+ return;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL bt_fd_cache_log_level
+#include <babeltrace/logging-internal.h>
+
+BT_LOG_INIT_LOG_LEVEL(bt_fd_cache_log_level, "BABELTRACE_FD_CACHE_LOG_LEVEL");
--- /dev/null
+#ifndef FD_CACHE_LOGGING_H
+#define FD_CACHE_LOGGING_H
+
+/*
+ * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL bt_fd_cache_log_level
+#include <babeltrace/logging-internal.h>
+
+BT_LOG_LEVEL_EXTERN_SYMBOL(bt_fd_cache_log_level);
+
+#endif /* FD_CACHE_LOGGING_H */
--- /dev/null
+#ifndef BABELTRACE_FD_CACHE_INTERNAL_H
+#define BABELTRACE_FD_CACHE_INTERNAL_H
+/*
+ * fd-cache-internal.h
+ *
+ * Babeltrace - File descriptor cache
+ *
+ * Copyright 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * Author: Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/babeltrace-internal.h>
+
+struct bt_fd_cache_handle {
+ int fd;
+};
+
+struct bt_fd_cache {
+ GHashTable *cache;
+};
+
+static inline
+int bt_fd_cache_handle_get_fd(struct bt_fd_cache_handle *handle)
+{
+ return handle->fd;
+}
+
+BT_HIDDEN
+int bt_fd_cache_init(struct bt_fd_cache *fdc);
+
+BT_HIDDEN
+void bt_fd_cache_fini(struct bt_fd_cache *fdc);
+
+BT_HIDDEN
+struct bt_fd_cache_handle *bt_fd_cache_get_handle(struct bt_fd_cache *fdc,
+ const char *path);
+
+BT_HIDDEN
+void bt_fd_cache_put_handle(struct bt_fd_cache *fdc,
+ struct bt_fd_cache_handle *handle);
+
+#endif /* BABELTRACE_FD_CACHE_INTERNAL_H */
SUBDIRS =
+
+babeltrace_plugin_lttng_utils_la_LIBADD =
+
if ENABLE_DEBUG_INFO
SUBDIRS += debug-info
+babeltrace_plugin_lttng_utils_la_LIBADD += \
+ debug-info/libdebug-info.la
endif
AM_CPPFLAGS += -I$(top_srcdir)/plugins
babeltrace_plugin_lttng_utils_la_SOURCES = \
plugin.c
-babeltrace_plugin_lttng_utils_la_LIBADD = \
- debug-info/libdebug-info.la
-
babeltrace_plugin_lttng_utils_la_LDFLAGS = \
$(LT_NO_UNDEFINED) \
-avoid-version -module \
AM_CPPFLAGS += -I$(top_srcdir)/plugins
noinst_LTLIBRARIES = libdebug-info.la
+
+libdebug_info_la_LIBADD = \
+ $(top_builddir)/fd-cache/libbabeltrace-fd-cache.la
+
libdebug_info_la_SOURCES = \
bin-info.c \
bin-info.h \
#define BT_LOG_TAG "PLUGIN-CTF-LTTNG-UTILS-DEBUG-INFO-FLT-BIN-INFO"
#include "logging.h"
+#include <dwarf.h>
+#include <errno.h>
#include <fcntl.h>
-#include <math.h>
+#include <inttypes.h>
#include <libgen.h>
+#include <math.h>
#include <stdio.h>
-#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <dwarf.h>
+
#include <glib.h>
-#include <errno.h>
-#include "dwarf.h"
+
#include "bin-info.h"
#include "crc32.h"
+#include "dwarf.h"
#include "utils.h"
/*
}
BT_HIDDEN
-struct bin_info *bin_info_create(const char *path, uint64_t low_addr,
- uint64_t memsz, bool is_pic, const char *debug_info_dir,
- const char *target_prefix)
+struct bin_info *bin_info_create(struct bt_fd_cache *fdc, const char *path,
+ uint64_t low_addr, uint64_t memsz, bool is_pic,
+ const char *debug_info_dir, const char *target_prefix)
{
struct bin_info *bin = NULL;
+ BT_ASSERT(fdc);
+
if (!path) {
goto error;
}
bin->build_id = NULL;
bin->build_id_len = 0;
bin->file_build_id_matches = false;
+ bin->fd_cache = fdc;
return bin;
elf_end(bin->elf_file);
- close(bin->elf_fd);
- close(bin->dwarf_fd);
+ bt_fd_cache_put_handle(bin->fd_cache, bin->elf_handle);
+ bt_fd_cache_put_handle(bin->fd_cache, bin->dwarf_handle);
g_free(bin);
}
static
int bin_info_set_elf_file(struct bin_info *bin)
{
- int elf_fd = -1;
+ struct bt_fd_cache_handle *elf_handle = NULL;
Elf *elf_file = NULL;
if (!bin) {
goto error;
}
- elf_fd = open(bin->elf_path, O_RDONLY);
- if (elf_fd < 0) {
- elf_fd = -errno;
- BT_LOGE("Failed to open %s\n", bin->elf_path);
+ elf_handle = bt_fd_cache_get_handle(bin->fd_cache, bin->elf_path);
+ if (!elf_handle) {
+ BT_LOGD("Failed to open %s", bin->elf_path);
goto error;
}
- elf_file = elf_begin(elf_fd, ELF_C_READ, NULL);
+ elf_file = elf_begin(bt_fd_cache_handle_get_fd(elf_handle),
+ ELF_C_READ, NULL);
if (!elf_file) {
- BT_LOGE("elf_begin failed: %s\n", elf_errmsg(-1));
+ BT_LOGE("elf_begin failed: %s", elf_errmsg(-1));
goto error;
}
if (elf_kind(elf_file) != ELF_K_ELF) {
- BT_LOGE("Error: %s is not an ELF object\n",
- bin->elf_path);
+ BT_LOGE("Error: %s is not an ELF object", bin->elf_path);
goto error;
}
- bin->elf_fd = elf_fd;
+ bin->elf_handle = elf_handle;
bin->elf_file = elf_file;
return 0;
error:
- if (elf_fd >= 0) {
- close(elf_fd);
- elf_fd = -1;
- }
+ bt_fd_cache_put_handle(bin->fd_cache, elf_handle);
elf_end(elf_file);
- return elf_fd;
+ return -1;
}
/**
static
int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path)
{
- int fd = -1, ret = 0;
+ int ret = 0;
+ struct bt_fd_cache_handle *dwarf_handle = NULL;
struct bt_dwarf_cu *cu = NULL;
Dwarf *dwarf_info = NULL;
goto error;
}
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- fd = -errno;
+ dwarf_handle = bt_fd_cache_get_handle(bin->fd_cache, path);
+ if (!dwarf_handle) {
goto error;
}
- dwarf_info = dwarf_begin(fd, DWARF_C_READ);
+ dwarf_info = dwarf_begin(bt_fd_cache_handle_get_fd(dwarf_handle),
+ DWARF_C_READ);
if (!dwarf_info) {
goto error;
}
goto error;
}
- bin->dwarf_fd = fd;
+ bin->dwarf_handle = dwarf_handle;
bin->dwarf_path = g_strdup(path);
if (!bin->dwarf_path) {
goto error;
return 0;
error:
- if (fd >= 0) {
- close(fd);
- fd = -1;
- }
+ bt_fd_cache_put_handle(bin->fd_cache, dwarf_handle);
dwarf_end(dwarf_info);
g_free(dwarf_info);
free(cu);
- return fd;
+ return -1;
}
/**
* 0 otherwise
*/
static
-int is_valid_debug_file(char *path, uint32_t crc)
+int is_valid_debug_file(struct bin_info *bin, char *path, uint32_t crc)
{
- int ret = 0, fd = -1;
+ int ret = 0;
+ struct bt_fd_cache_handle *debug_handle = NULL;
uint32_t _crc = 0;
if (!path) {
- goto end_noclose;
+ goto end;
}
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- goto end_noclose;
+ debug_handle = bt_fd_cache_get_handle(bin->fd_cache, path);
+ if (!debug_handle) {
+ goto end;
}
- ret = crc32(fd, &_crc);
+ ret = crc32(bt_fd_cache_handle_get_fd(debug_handle), &_crc);
if (ret) {
ret = 0;
goto end;
ret = (crc == _crc);
end:
- close(fd);
-end_noclose:
+ bt_fd_cache_put_handle(bin->fd_cache, debug_handle);
return ret;
}
/* First look in the executable's dir */
path = g_strconcat(bin_dir, bin->dbg_link_filename, NULL);
- if (is_valid_debug_file(path, bin->dbg_link_crc)) {
+ if (is_valid_debug_file(bin, path, bin->dbg_link_crc)) {
goto found;
}
g_free(path);
path = g_strconcat(bin_dir, DEBUG_SUBDIR, bin->dbg_link_filename, NULL);
- if (is_valid_debug_file(path, bin->dbg_link_crc)) {
+ if (is_valid_debug_file(bin, path, bin->dbg_link_crc)) {
goto found;
}
g_free(path);
path = g_strconcat(dbg_dir, bin_dir, bin->dbg_link_filename, NULL);
- if (is_valid_debug_file(path, bin->dbg_link_crc)) {
+ if (is_valid_debug_file(bin, path, bin->dbg_link_crc)) {
goto found;
}
if (!bin->dwarf_info && !bin->is_elf_only) {
ret = bin_info_set_dwarf_info(bin);
if (ret) {
- BT_LOGD_STR("Failed to set bin dwarf info, falling back to ELF lookup.");
+ BT_LOGD_STR("Failed to set bin dwarf info, falling "
+ "back to ELF lookup.");
/* Failed to set DWARF info, fallback to ELF. */
bin->is_elf_only = true;
}
#include <gelf.h>
#include <elfutils/libdw.h>
#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/fd-cache-internal.h>
#define DEFAULT_DEBUG_DIR "/usr/lib/debug"
#define DEBUG_SUBDIR ".debug/"
/* Optional debug link info. */
gchar *dbg_link_filename;
uint32_t dbg_link_crc;
- /* FDs to ELF and DWARF files. */
- int elf_fd;
- int dwarf_fd;
+ /* fd cache handles to ELF and DWARF files. */
+ struct bt_fd_cache_handle *elf_handle;
+ struct bt_fd_cache_handle *dwarf_handle;
/* Configuration. */
gchar *debug_info_dir;
/* Denotes whether the executable is position independent code. */
* DWARF info.
*/
bool is_elf_only:1;
+ /* Weak ref. Owned by the iterator. */
+ struct bt_fd_cache *fd_cache;
};
struct source_location {
* NULL on failure.
*/
BT_HIDDEN
-struct bin_info *bin_info_create(const char *path, uint64_t low_addr,
- uint64_t memsz, bool is_pic, const char *debug_info_dir,
- const char *target_prefix);
+struct bin_info *bin_info_create(struct bt_fd_cache *fdc, const char *path,
+ uint64_t low_addr, uint64_t memsz, bool is_pic,
+ const char *debug_info_dir, const char *target_prefix);
/**
* Destroy the given bin_info instance
#include <babeltrace/assert-internal.h>
#include <babeltrace/common-internal.h>
+#include <babeltrace/fd-cache-internal.h>
#include "bin-info.h"
#include "debug-info.h"
struct trace_ir_maps *ir_maps;
/* in_trace -> debug_info_mapping. */
GHashTable *debug_info_map;
+
+ struct bt_fd_cache fd_cache;
};
struct debug_info_source {
GQuark q_dl_open;
GQuark q_lib_load;
GQuark q_lib_unload;
+ struct bt_fd_cache *fd_cache; /* Weak ref. Owned by the iterator. */
};
static
return debug_info_src;
}
-BT_HIDDEN
+static
struct debug_info_source *debug_info_query(struct debug_info *debug_info,
int64_t vpid, uint64_t ip)
{
return dbg_info_src;
}
-BT_HIDDEN
+static
struct debug_info *debug_info_create(struct debug_info_component *comp,
- const bt_trace *trace)
+ const bt_trace *trace, struct bt_fd_cache *fdc)
{
int ret;
struct debug_info *debug_info;
+ BT_ASSERT(comp);
+ BT_ASSERT(trace);
+ BT_ASSERT(fdc);
+
debug_info = g_new0(struct debug_info, 1);
if (!debug_info) {
goto end;
}
debug_info->input_trace = trace;
+ debug_info->fd_cache = fdc;
end:
return debug_info;
return NULL;
}
-BT_HIDDEN
+static
void debug_info_destroy(struct debug_info *debug_info)
{
bt_trace_status status;
uint64_t is_pic_field_value;
event_get_payload_unsigned_integer_field_value(event,
- IS_PIC_FIELD_NAME, &is_pic_field_value);
+ IS_PIC_FIELD_NAME, &is_pic_field_value);
is_pic = is_pic_field_value == 1;
} else {
/*
VPID_FIELD_NAME, &vpid);
proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
- debug_info->vpid_to_proc_dbg_info_src, vpid);
+ debug_info->vpid_to_proc_dbg_info_src, vpid);
if (!proc_dbg_info_src) {
goto end;
}
*((uint64_t *) key) = baddr;
- bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info,
- key);
+ bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info, key);
if (bin) {
goto end;
}
- bin = bin_info_create(path, baddr, memsz, is_pic,
+ bin = bin_info_create(debug_info->fd_cache, path, baddr, memsz, is_pic,
debug_info->comp->arg_debug_dir,
debug_info->comp->arg_target_prefix);
if (!bin) {
goto end;
}
- g_hash_table_insert(proc_dbg_info_src->baddr_to_bin_info,
- key, bin);
+ g_hash_table_insert(proc_dbg_info_src->baddr_to_bin_info, key, bin);
/* Ownership passed to ht. */
key = NULL;
debug_info = g_hash_table_lookup(debug_it->debug_info_map, trace);
if (!debug_info) {
debug_info = debug_info_create(debug_it->debug_info_component,
- trace);
+ trace, &debug_it->fd_cache);
g_hash_table_insert(debug_it->debug_info_map, (gpointer) trace,
debug_info);
bt_trace_add_destruction_listener(trace,
bt_self_component_port_input_message_iterator *upstream_iterator;
struct debug_info_msg_iter *debug_info_msg_iter;
gchar *debug_info_field_name;
+ int ret;
/* Borrow the upstream input port. */
input_port = bt_self_component_filter_borrow_input_port_by_name(
goto end;
}
+ ret = bt_fd_cache_init(&debug_info_msg_iter->fd_cache);
+ if (ret) {
+ trace_ir_maps_destroy(debug_info_msg_iter->ir_maps);
+ g_hash_table_destroy(debug_info_msg_iter->debug_info_map);
+ g_free(debug_info_msg_iter);
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM;
+ goto end;
+ }
+
+
bt_self_message_iterator_set_data(self_msg_iter, debug_info_msg_iter);
debug_info_msg_iter->input_iterator = self_msg_iter;
trace_ir_maps_destroy(debug_info_msg_iter->ir_maps);
g_hash_table_destroy(debug_info_msg_iter->debug_info_map);
+ bt_fd_cache_fini(&debug_info_msg_iter->fd_cache);
+
g_free(debug_info_msg_iter);
}
if ENABLE_DEBUG_INFO
test_dwarf_LDADD = \
$(top_builddir)/plugins/lttng-utils/debug-info/libdebug-info.la \
+ $(top_builddir)/fd-cache/libbabeltrace-fd-cache.la \
$(top_builddir)/logging/libbabeltrace-logging.la \
$(top_builddir)/common/libbabeltrace-common.la \
$(ELFUTILS_LIBS) \
test_bin_info_LDADD = \
$(top_builddir)/plugins/lttng-utils/debug-info/libdebug-info.la \
+ $(top_builddir)/fd-cache/libbabeltrace-fd-cache.la \
$(top_builddir)/logging/libbabeltrace-logging.la \
$(top_builddir)/common/libbabeltrace-common.la \
$(ELFUTILS_LIBS) \
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
+#include <babeltrace/assert-internal.h>
#include <lttng-utils/debug-info/bin-info.h>
+
#include "tap/tap.h"
#define NR_TESTS 36
char *func_name = NULL;
struct bin_info *bin = NULL;
struct source_location *src_loc = NULL;
+ struct bt_fd_cache fdc;
uint8_t build_id[BUILD_ID_LEN] = {
0xcd, 0xd9, 0x8c, 0xdd, 0x87, 0xf7, 0xfe, 0x64, 0xc1, 0x3b,
0x6d, 0xaa, 0xd5, 0x53, 0x98, 0x7e, 0xaf, 0xd4, 0x0c, 0xbb
snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_BUILD_ID);
- bin = bin_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir, NULL);
+ ret = bt_fd_cache_init(&fdc);
+ BT_ASSERT(ret == 0);
+ bin = bin_info_create(&fdc, path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir, NULL);
ok(bin != NULL, "bin_info_create successful");
/* Test setting build_id */
}
bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
}
static
struct source_location *src_loc = NULL;
char *dbg_filename = "libhello_debug_link_so.debug";
uint32_t crc = 0xe55c2b98;
+ struct bt_fd_cache fdc;
diag("bin-info tests - separate DWARF via debug link");
snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_DEBUG_LINK);
- bin = bin_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir, NULL);
+ ret = bt_fd_cache_init(&fdc);
+ BT_ASSERT(ret == 0);
+ bin = bin_info_create(&fdc, path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir,
+ NULL);
ok(bin != NULL, "bin_info_create successful");
/* Test setting debug link */
}
bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
}
static
char *func_name = NULL;
struct bin_info *bin = NULL;
struct source_location *src_loc = NULL;
+ struct bt_fd_cache fdc;
diag("bin-info tests - ELF only");
snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_ELF);
- bin = bin_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir, NULL);
+ ret = bt_fd_cache_init(&fdc);
+ BT_ASSERT(ret == 0);
+ bin = bin_info_create(&fdc, path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir, NULL);
ok(bin != NULL, "bin_info_create successful");
/* Test function name lookup (with ELF) */
source_location_destroy(src_loc);
bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
}
static
char *func_name = NULL;
struct bin_info *bin = NULL;
struct source_location *src_loc = NULL;
+ struct bt_fd_cache fdc;
diag("bin-info tests - DWARF bundled with SO file");
+
snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME);
- bin = bin_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir, NULL);
+ ret = bt_fd_cache_init(&fdc);
+ BT_ASSERT(ret == 0);
+ bin = bin_info_create(&fdc, path, SO_LOW_ADDR, SO_MEMSZ, true, data_dir, NULL);
ok(bin != NULL, "bin_info_create successful");
/* Test bin_info_has_address */
"bin_info_lookup_source_location - fail on addr not found");
bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
}
int main(int argc, char **argv)