/*
* This file is part of ltrace.
- * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc.
* Copyright (C) 2010 Joe Damato
* Copyright (C) 1998,2009 Juan Cespedes
*
#include "options.h"
#include "proc.h"
#include "value_dict.h"
+#include "dwarf_prototypes.h"
#ifndef OS_HAVE_PROCESS_DATA
int
if (proc->unwind_as != NULL)
unw_destroy_addr_space(proc->unwind_as);
#endif /* defined(HAVE_LIBUNWIND) */
+
+#if defined(HAVE_LIBDW)
+ if (proc->dwfl != NULL)
+ dwfl_end(proc->dwfl);
+#endif /* defined(HAVE_LIBDW) */
}
static int
}
#endif /* defined(HAVE_LIBUNWIND) */
+#if defined(HAVE_LIBDW)
+ proc->dwfl = NULL; /* Initialize for leader only on first library. */
+ proc->should_attach_dwfl = 1; /* should try to attach the DWFL data */
+#endif /* defined(HAVE_LIBDW) */
+
return 0;
}
goto fail;
}
- if (proc->leader != proc)
- return 0;
- if (process_init_main(proc) < 0) {
+ if (proc->leader != proc) {
+ proc->e_machine = proc->leader->e_machine;
+ proc->e_class = proc->leader->e_class;
+ get_arch_dep(proc);
+ } else if (process_init_main(proc) < 0) {
process_bare_destroy(proc, 0);
goto fail;
}
debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d",
lib->soname, lib->base, lib->pathname, proc->pid);
+#if defined(HAVE_LIBDW)
+ Dwfl *dwfl = NULL;
+ Dwfl_Module *dwfl_module = NULL;
+
+ /* Setup module tracking for libdwfl unwinding. */
+ struct process *leader = proc->leader;
+ dwfl = leader->dwfl;
+ if (dwfl == NULL) {
+ static const Dwfl_Callbacks proc_callbacks = {
+ .find_elf = dwfl_linux_proc_find_elf,
+ .find_debuginfo = dwfl_standard_find_debuginfo
+ };
+ dwfl = dwfl_begin(&proc_callbacks);
+ if (dwfl == NULL)
+ fprintf(stderr,
+ "Couldn't initialize libdwfl unwinding "
+ "for process %d: %s\n", leader->pid,
+ dwfl_errmsg (-1));
+ }
+
+ if (dwfl != NULL) {
+ dwfl_report_begin_add(dwfl);
+ dwfl_module =
+ dwfl_report_elf(dwfl, lib->soname,
+ lib->pathname, -1,
+ (GElf_Addr) lib->base,
+ false);
+ if (dwfl_module == NULL)
+ fprintf(stderr,
+ "dwfl_report_elf %s@%p (%s) %d: %s\n",
+ lib->soname, lib->base, lib->pathname,
+ proc->pid, dwfl_errmsg (-1));
+
+ dwfl_report_end(dwfl, NULL, NULL);
+
+ if (options.bt_depth > 0) {
+ if (proc->should_attach_dwfl) {
+ int r = dwfl_linux_proc_attach(dwfl,
+ leader->pid,
+ true);
+ proc->should_attach_dwfl = 0;
+ if (r != 0) {
+ const char *msg;
+ dwfl_end(dwfl);
+ if (r < 0)
+ msg = dwfl_errmsg(-1);
+ else
+ msg = strerror(r);
+ fprintf(stderr, "Couldn't initialize "
+ "libdwfl (unwinding, prototype "
+ "import) for process %d: %s\n",
+ leader->pid, msg);
+ }
+ }
+ }
+ }
+
+ lib->dwfl_module = dwfl_module;
+ leader->dwfl = dwfl;
+
+#endif /* defined(HAVE_LIBDW) */
+
/* Insert breakpoints for all active (non-latent) symbols. */
struct library_symbol *libsym = NULL;
while ((libsym = library_each_symbol(lib, libsym,
return data->cb(data->proc, *bpp, data->cb_data);
}
-void *
-proc_each_breakpoint(struct process *proc, void *start,
+arch_addr_t *
+proc_each_breakpoint(struct process *proc, arch_addr_t *start,
enum callback_status (*cb)(struct process *proc,
struct breakpoint *bp,
void *data), void *data)