From d5232406664fdc51640eeba8f0e49f26275921df Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Wed, 21 May 2014 03:47:33 -0700 Subject: [PATCH] Making sure to not double-examine the same DWARF CU --- dwarf_prototypes.c | 8 ++++---- library.c | 2 +- library.h | 2 +- output.c | 2 +- proc.c | 23 ++++++++++++++--------- proc.h | 6 ++++++ 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/dwarf_prototypes.c b/dwarf_prototypes.c index 4860e4d..6094658 100644 --- a/dwarf_prototypes.c +++ b/dwarf_prototypes.c @@ -979,7 +979,8 @@ static bool process_die_compileunit(struct protolib *plib, struct library *lib, return true; } -static void import(struct protolib *plib, struct library *lib, Dwfl *dwfl) +static void import(struct protolib *plib, struct library *lib, + Dwfl_Module *dwfl_module) { // A map from DIE addresses (Dwarf_Off) to type structures (struct // arg_type_info*). This is created and filled in at the start of each @@ -992,7 +993,7 @@ static void import(struct protolib *plib, struct library *lib, Dwfl *dwfl) Dwarf_Addr bias; Dwarf_Die *die = NULL; - while ((die = dwfl_nextcu(dwfl, die, &bias)) != NULL) { + while ((die = dwfl_module_nextcu(dwfl_module, die, &bias)) != NULL) { if (dwarf_tag(die) == DW_TAG_compile_unit) process_die_compileunit(plib, lib, &type_dieoffset_hash, die); @@ -1007,7 +1008,6 @@ static void import(struct protolib *plib, struct library *lib, Dwfl *dwfl) bool import_DWARF_prototypes(struct library *lib) { struct protolib *plib = lib->protolib; - Dwfl *dwfl = lib->dwfl; debug(DEBUG_FUNCTION, "Importing DWARF prototypes from '%s'", lib->soname); @@ -1026,7 +1026,7 @@ bool import_DWARF_prototypes(struct library *lib) } } - import(plib, lib, dwfl); + import(plib, lib, lib->dwfl_module); lib->protolib = plib; return true; diff --git a/library.c b/library.c index 13d8d45..3a22519 100644 --- a/library.c +++ b/library.c @@ -296,7 +296,7 @@ private_library_init(struct library *lib, enum library_type type) lib->type = type; #if defined(HAVE_LIBDW) - lib->dwfl = NULL; + lib->dwfl_module = NULL; #endif } diff --git a/library.h b/library.h index 82dc048..4d649e0 100644 --- a/library.h +++ b/library.h @@ -176,7 +176,7 @@ struct library { struct os_library_data os; #if defined(HAVE_LIBDW) - Dwfl *dwfl; + Dwfl_Module *dwfl_module; #endif }; diff --git a/output.c b/output.c index 8d378ea..10faee2 100644 --- a/output.c +++ b/output.c @@ -216,7 +216,7 @@ library_get_prototype(struct library *lib, const char *name) #if defined(HAVE_LIBDW) // DWARF data fills in the gaps in the .conf files, so I don't // check for lib->protolib==NULL here - if (lib->dwfl != NULL && + if (lib->dwfl_module != NULL && (filter_matches_library(options.plt_filter, lib ) || filter_matches_library(options.static_filter, lib ) || filter_matches_library(options.export_filter, lib ))) diff --git a/proc.c b/proc.c index 7c370a3..5385510 100644 --- a/proc.c +++ b/proc.c @@ -175,6 +175,7 @@ process_bare_init(struct process *proc, const char *filename, #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; @@ -894,6 +895,7 @@ proc_add_library(struct process *proc, struct library *lib) #if defined(HAVE_LIBDW) Dwfl *dwfl = NULL; + Dwfl_Module *dwfl_module = NULL; /* Setup module tracking for libdwfl unwinding. */ struct process *leader = proc->leader; @@ -913,24 +915,26 @@ proc_add_library(struct process *proc, struct library *lib) if (dwfl != NULL) { dwfl_report_begin_add(dwfl); - if (dwfl_report_elf(dwfl, lib->soname, - lib->pathname, -1, - (GElf_Addr) lib->base, - false) == NULL) + 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 (leader->dwfl == NULL) { + if (proc->should_attach_dwfl) { int r = dwfl_linux_proc_attach(dwfl, leader->pid, true); - if (r == 0) - leader->dwfl = dwfl; - else { + proc->should_attach_dwfl = 0; + if (r != 0) { const char *msg; dwfl_end(dwfl); if (r < 0) @@ -946,7 +950,8 @@ proc_add_library(struct process *proc, struct library *lib) } } - lib->dwfl = dwfl; + lib->dwfl_module = dwfl_module; + leader->dwfl = dwfl; #endif /* defined(HAVE_LIBDW) */ diff --git a/proc.h b/proc.h index 659c786..c1408be 100644 --- a/proc.h +++ b/proc.h @@ -121,6 +121,12 @@ struct process { #if defined(HAVE_LIBDW) /* Unwind info for leader, NULL for non-leader procs. */ Dwfl *dwfl; + + /* Whether we still need to attach the DWARF library to this process. We + * try only once, and never again, regardless of whether we succeeded or + * not. 0 = shouldn't attach */ + int should_attach_dwfl; + #endif /* defined(HAVE_LIBDW) */ #if defined(HAVE_LIBUNWIND) -- 2.7.4