[ltrace-commits] 01/01: Making sure to not double-examine the same DWARF CU

Petr Machata pmachata-guest at moszumanska.debian.org
Wed May 21 14:53:06 UTC 2014


This is an automated email from the git hooks/post-receive script.

pmachata-guest pushed a commit to branch master
in repository ltrace.

commit c0915b4f4991b3d1b758c0f227e65ece74560f34
Author: Dima Kogan <dima at secretsauce.net>
Date:   Wed May 21 03:47:33 2014 -0700

    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)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/ltrace.git



More information about the ltrace-commits mailing list