X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=proc.c;h=f08f94785cc51d45954ff0ce490f47114bb2f13c;hb=ccd9f24a3eb74dbc884c21859b1aaa141834528d;hp=11755b0c7bc9f1a0ed5da4eafddd70b0d1dff36d;hpb=517f5529d7008eba87b8b2fee5ec9ec0a5075f6e;p=platform%2Fupstream%2Fltrace.git diff --git a/proc.c b/proc.c index 11755b0..f08f947 100644 --- a/proc.c +++ b/proc.c @@ -1,6 +1,6 @@ /* * 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 * @@ -29,11 +29,6 @@ #include #include -#if defined(HAVE_LIBUNWIND) -#include -#include -#endif /* defined(HAVE_LIBUNWIND) */ - #include "backend.h" #include "breakpoint.h" #include "debug.h" @@ -41,6 +36,7 @@ #include "options.h" #include "proc.h" #include "value_dict.h" +#include "dwarf_prototypes.h" #ifndef OS_HAVE_PROCESS_DATA int @@ -111,6 +107,11 @@ destroy_unwind(struct process *proc) 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 @@ -172,6 +173,10 @@ process_bare_init(struct process *proc, const char *filename, } #endif /* defined(HAVE_LIBUNWIND) */ +#if defined(HAVE_LIBDW) + proc->dwfl = NULL; /* Initialize for leader only on first library. */ +#endif /* defined(HAVE_LIBDW) */ + return 0; } @@ -220,9 +225,11 @@ process_init(struct process *proc, const char *filename, pid_t pid) 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; } @@ -885,6 +892,64 @@ proc_add_library(struct process *proc, struct library *lib) 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; + + /* 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); + if (dwfl_report_elf(dwfl, lib->soname, + lib->pathname, -1, + (GElf_Addr) lib->base, + false) == 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 (leader->dwfl == NULL) { + int r = dwfl_linux_proc_attach(dwfl, + leader->pid, + true); + if (r == 0) + leader->dwfl = dwfl; + else { + const char *msg; + dwfl_end(dwfl); + if (r < 0) + msg = dwfl_errmsg(-1); + else + msg = strerror(r); + fprintf(stderr, "Couldn't initialize " + "libdwfl (for unwinding, prototype import) for " + "process %d: %s\n", + leader->pid, msg); + } + } + } + } + + lib->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, @@ -1005,8 +1070,8 @@ each_breakpoint_cb(arch_addr_t *key, struct breakpoint **bpp, void *d) 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)