summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDima Kogan <dima@secretsauce.net>2014-05-21 03:47:33 -0700
committerChanho Park <chanho61.park@samsung.com>2014-08-22 20:38:26 +0900
commitd5232406664fdc51640eeba8f0e49f26275921df (patch)
treedae013446ba070970bfac8e9c32c1576979411f2
parente29618826afbca88e505ade97763ffed04b073c3 (diff)
downloadltrace-d5232406664fdc51640eeba8f0e49f26275921df.tar.gz
ltrace-d5232406664fdc51640eeba8f0e49f26275921df.tar.bz2
ltrace-d5232406664fdc51640eeba8f0e49f26275921df.zip
Making sure to not double-examine the same DWARF CU
-rw-r--r--dwarf_prototypes.c8
-rw-r--r--library.c2
-rw-r--r--library.h2
-rw-r--r--output.c2
-rw-r--r--proc.c23
-rw-r--r--proc.h6
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)