From: John L. <mov...@us...> - 2005-04-06 21:07:47
|
Update of /cvsroot/oprofile/oprofile/libutil++ In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13478/libutil++ Modified Files: Makefile.am op_bfd.cpp op_bfd.h Added Files: cached_value.h Log Message: some re-jigging of debug stuff --- NEW FILE: cached_value.h --- /** * @file cached_value.h * Hold a cached value. * * @remark Copyright 2005 OProfile authors * @remark Read the file COPYING * * @author John Levon */ #ifndef CACHED_VALUE_H #define CACHED_VALUE_H #include "op_exception.h" /** * Hold a single value, returning a cached value if there is one. */ template <class T> class cached_value { public: cached_value() : set(false) {} typedef T value_type; /// return the cached value value_type const get() const { if (!set) throw op_fatal_error("cached value not set"); return value; } /// return true if a value is cached bool cached() const { return set; } /// set the contained value value_type const reset(value_type const & val) { value = val; set = true; return value; } private: /// the cached value value_type value; /// is the value valid? bool set; }; #endif /* !CACHED_VALUE_H */ Index: Makefile.am =================================================================== RCS file: /cvsroot/oprofile/oprofile/libutil++/Makefile.am,v retrieving revision 1.16 retrieving revision 1.17 diff -u -p -d -r1.16 -r1.17 --- Makefile.am 16 Jan 2004 17:48:54 -0000 1.16 +++ Makefile.am 6 Apr 2005 21:07:06 -0000 1.17 @@ -30,4 +30,5 @@ libutil___a_SOURCES = \ child_reader.h \ unique_storage.h \ utility.h \ + cached_value.h \ comma_list.h Index: op_bfd.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libutil++/op_bfd.cpp,v retrieving revision 1.60 retrieving revision 1.61 diff -u -p -d -r1.60 -r1.61 --- op_bfd.cpp 4 Apr 2005 20:18:04 -0000 1.60 +++ op_bfd.cpp 6 Apr 2005 21:07:06 -0000 1.61 @@ -149,7 +149,7 @@ separate_debug_file_exists(string const { unsigned long file_crc = 0; // The size of 8*1024 element for the buffer is arbitrary. - char buffer[8*1024]; + char buffer[2*1024]; ifstream file(name.c_str()); if (!file) @@ -277,18 +277,17 @@ op_bfd_symbol::op_bfd_symbol(bfd_vma vma } -op_bfd::op_bfd(string const & archive_path, string const & fname, +op_bfd::op_bfd(string const & archive, string const & fname, string_filter const & symbol_filter, bool & ok) : filename(fname), + archive_path(archive), file_size(-1), ibfd(0), dbfd(0), text_offset(0), - debug_info(false), prev_total_symcount(0) { - string image_path = archive_path + filename; int fd; struct stat st; // after creating all symbol it's convenient for user code to access @@ -297,6 +296,10 @@ op_bfd::op_bfd(string const & archive_pa symbols_found_t symbols; asection const * sect; + string const image_path = archive_path + filename; + + cverb << vbfd << "op_bfd ctor for " << image_path << endl; + // if there's a problem already, don't try to open it if (!ok) goto out_fail; @@ -309,7 +312,7 @@ op_bfd::op_bfd(string const & archive_pa } if (fstat(fd, &st)) { - cverb << vbfd << "stat failed for " << filename << endl; + cverb << vbfd << "stat failed for " << image_path << endl; ok = false; goto out_fail; } @@ -335,39 +338,6 @@ op_bfd::op_bfd(string const & archive_pa } } - for (sect = ibfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_DEBUGGING) { - debug_info = true; - break; - } - } - - // if no debugging section check to see if there is an .debug file - if (!debug_info) { - string global(archive_path + DEBUGDIR); - string dirname(image_path.substr(0, image_path.rfind('/'))); - if (find_separate_debug_file (ibfd, dirname, global, - debug_filename)) { - cverb << vbfd - << "now loading: " << debug_filename << endl; - dbfd = open_bfd(debug_filename); - if (dbfd) { - for (sect = dbfd->sections; sect; - sect = sect->next) { - if (sect->flags & SEC_DEBUGGING) { - debug_info = true; - break; - } - } - } else { - // .debug is optional, so will not fail if - // problem opening file. - cverb << vbfd << "unable to open: " - << debug_filename << endl; - } - } - } - get_symbols(symbols); out: @@ -602,6 +572,12 @@ void op_bfd::get_symbols(op_bfd::symbols if (bfd_get_file_flags(ibfd) & HAS_SYMS) size_binary = bfd_get_symtab_upper_bound(ibfd); + // On separate debug file systems, the main bfd has no symbols, + // so even for non -g reports, we want to process the dbfd. + // This hurts us pretty badly (the CRC), but we really don't + // have much choice at the moment. + has_debug_info(); + if (dbfd && (bfd_get_file_flags(dbfd) & HAS_SYMS)) size_debug += bfd_get_symtab_upper_bound(dbfd); @@ -611,7 +587,7 @@ void op_bfd::get_symbols(op_bfd::symbols if (size < 1) return; - bfd_syms.reset(new asymbol*[size]); + bfd_syms.reset(new asymbol *[size]); if (size_binary > 0) get_symbols_from_file(ibfd, 0, symbols, false); @@ -696,12 +672,48 @@ bfd_vma op_bfd::offset_to_pc(bfd_vma off } +bool op_bfd::has_debug_info() const +{ + if (debug_info.cached()) + return debug_info.get(); + + asection const * sect; + + for (sect = ibfd->sections; sect; sect = sect->next) { + if (sect->flags & SEC_DEBUGGING) + 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, dirname, global, debug_filename)) { + cverb << vbfd << "now loading: " << debug_filename << endl; + dbfd = open_bfd(debug_filename); + if (dbfd) { + for (sect = dbfd->sections; sect; sect = sect->next) { + if (sect->flags & SEC_DEBUGGING) + return debug_info.reset(true); + } + } + } + + // .debug is optional, so will not fail if there's a problem + cverb << vbfd << "failed to process separate debug file " + << debug_filename << endl; + + return debug_info.reset(false); +} + + bool op_bfd::get_linenr(symbol_index_t sym_idx, unsigned int offset, string & source_filename, unsigned int & linenr) const { linenr = 0; - if (!debug_info) + if (!has_debug_info()) return false; char const * functionname; Index: op_bfd.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/libutil++/op_bfd.h,v retrieving revision 1.34 retrieving revision 1.35 diff -u -p -d -r1.34 -r1.35 --- op_bfd.h 3 Apr 2005 22:47:50 -0000 1.34 +++ op_bfd.h 6 Apr 2005 21:07:07 -0000 1.35 @@ -21,6 +21,7 @@ #include <list> #include "utility.h" +#include "cached_value.h" #include "op_types.h" class op_bfd; @@ -154,7 +155,11 @@ public: /** return the text section filepos. */ unsigned long const get_start_offset() const { return text_offset; } - /// return the image name of the underlying binary image + /** + * Return the image name of the underlying binary image. For an + * archive, this returns the path *within* the archive, not the + * full path of the file. + */ std::string get_filename() const; /// sorted vector by vma of interesting symbol. @@ -166,12 +171,15 @@ public: size_t bfd_arch_bits_per_address() const; /// return true if binary contain some debug information - bool has_debug_info() const { return debug_info; } + bool has_debug_info() const; private: - /// filename we open + /// filename we open (not including archive path) std::string filename; + /// path to archive + std::string archive_path; + /// file size in bytes off_t file_size; @@ -184,10 +192,10 @@ private: // information. // corresponding debug file name - std::string debug_filename; + mutable std::string debug_filename; // corresponding debug bfd object. - bfd * dbfd; + mutable bfd * dbfd; // vector of symbol filled by the bfd lib. scoped_array<asymbol*> bfd_syms; @@ -196,7 +204,7 @@ private: unsigned long text_offset; /// true if at least one section has (flags & SEC_DEBUGGING) != 0 - bool debug_info; + mutable cached_value<bool> debug_info; /// temporary container for getting symbols typedef std::list<op_bfd_symbol> symbols_found_t; |