Package: oprofile-common
Version: 0.9.2-3
Severity: normal
Tags: patch upstream

--- Please enter the report below this line. ---
opreport and oparchive use the function find_separate_debug_file() to
search for a separate debug file.  Given the paths dir_in (directory
name of the executable or SO), global_in (global debug directory,
"/usr/lib/debug") it looks for debug information in these directories,
in order:

1. $dir_in
2. $dir_in/.debug
3. $global_in/$dir_in

Now when the executable is in an archive, dir_in must include the
archive path in order for (1) and (2) to be correct, but that means (3)
will be wrong.

I fixed this by adding a separate parameter for the archive path and
makes the search list:

1. $archive_in/$dir_in
2. $archive_in/$dir_in/.debug
3. $archive_in/$global_in/$dir_in

Attaching a patch for this.

In oparchive, this also removes the _source_ archive path
(options::archive_path) from the destination for copying the separate
debug file.  I think this is correct and the inclusion of the source
archive path was another bug.

Ben.

--- System information. ---
Architecture: i386
Kernel:       Linux 2.6.18-4-686

Debian Release: 4.0
  500 testing         shadbolt 
  500 testing         mirror 
  100 unstable        mirror 

--- Package information. ---
Depends              (Version) | Installed
==============================-+-===========
oprofile-common                | 0.9.3~cvs20070106-4.1

only in patch2:
unchanged:
--- oprofile-0.9.2.orig/libutil++/op_bfd.cpp
+++ oprofile-0.9.2/libutil++/op_bfd.cpp
@@ -305,11 +305,11 @@
 		return debug_info.reset(true);
 
 	// check to see if there is an .debug file
-	string const global(archive_path + DEBUGDIR);
-	string const image_path = archive_path + filename;
-	string const dirname(image_path.substr(0, image_path.rfind('/')));
-
-	if (find_separate_debug_file(ibfd.abfd, dirname, global, debug_filename)) {
+	if (find_separate_debug_file(ibfd.abfd,
+				     archive_path,
+				     filename.substr(0, filename.rfind('/')),
+				     DEBUGDIR,
+				     debug_filename)) {
 		cverb << vbfd << "now loading: " << debug_filename << endl;
 		dbfd.abfd = open_bfd(debug_filename);
 		if (dbfd.has_debug_info())
only in patch2:
unchanged:
--- oprofile-0.9.2.orig/libutil++/bfd_support.h
+++ oprofile-0.9.2/libutil++/bfd_support.h
@@ -65,14 +65,15 @@
 /*
  * find_separate_debug_file - return true if a valid separate debug file found
  * @param ibfd binary file
+ * @param archive_in archive directory
  * @param dir_in directory holding the binary file
- * @param global_in
+ * @param global_in global directory for separate debug files
  * @param filename path to valid debug file
  *
  * Search order for debug file and use first one found:
- * 1) dir_in directory
- * 2) dir_in/.debug directory
- * 3) global_in/dir_in directory
+ * 1) archive_in/dir_in directory
+ * 2) archive_in/dir_in/.debug directory
+ * 3) archive_in/global_in/dir_in directory
  *
  * Newer binutils and Linux distributions (e.g. Fedora) allow the
  * creation of debug files that are separate from the binary. The
@@ -83,6 +84,7 @@
  */
 extern bool
 find_separate_debug_file(bfd * ibfd, 
+			 std::string const & archive_in,
                          std::string const & dir_in,
                          std::string const & global_in,
                          std::string & filename);
only in patch2:
unchanged:
--- oprofile-0.9.2.orig/libutil++/bfd_support.cpp
+++ oprofile-0.9.2/libutil++/bfd_support.cpp
@@ -273,9 +273,13 @@
 }
 
 
-bool find_separate_debug_file(bfd * ibfd, string const & dir_in,
-                              string const & global_in, string & filename)
+bool find_separate_debug_file(bfd * ibfd,
+			      string const & archive_in,
+			      string const & dir_in,
+                              string const & global_in,
+			      string & filename)
 {
+	string archive(archive_in);
 	string dir(dir_in);
 	string global(global_in);
 	string basename;
@@ -284,6 +288,9 @@
 	if (!get_debug_link_info(ibfd, basename, crc32))
 		return false;
 	
+	if (archive.size() > 0 && archive.at(archive.size() - 1) != '/')
+		archive += '/';
+	
 	if (dir.size() > 0 && dir.at(dir.size() - 1) != '/')
 		dir += '/';
 	
@@ -293,13 +300,13 @@
 	cverb << vbfd << "looking for debugging file " << basename 
 	      << " with crc32 = " << hex << crc32 << endl;
 	
-	string first_try(dir + basename);
-	string second_try(dir + ".debug/" + basename);
+	string first_try(archive + dir + basename);
+	string second_try(archive + dir + ".debug/" + basename);
 
 	if (dir.size() > 0 && dir[0] == '/')
 		dir = dir.substr(1);
 
-	string third_try(global + dir + basename);
+	string third_try(archive + global + dir + basename);
 	
 	if (separate_debug_file_exists(first_try, crc32)) 
 		filename = first_try; 
only in patch2:
unchanged:
--- oprofile-0.9.2.orig/pp/oparchive.cpp
+++ oprofile-0.9.2/pp/oparchive.cpp
@@ -90,12 +90,13 @@
 		 */
 		bfd * ibfd = open_bfd(exe_name);
 		if (ibfd) {
-			string global(options::archive_path + DEBUGDIR);
-			string dirname = op_dirname(options::archive_path + 
-						    exe_name);
+			string dirname = op_dirname(exe_name);
 			string debug_filename;
-			if (find_separate_debug_file(ibfd, dirname, global,
-				debug_filename)) {
+			if (find_separate_debug_file(ibfd,
+						     options::archive_path,
+						     dirname,
+						     DEBUGDIR,
+						     debug_filename)) {
 				/* found something copy it over */
 				string dest_debug = options::outdirectory +
 					dirname + "/" +

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to