From: John L. <mov...@us...> - 2003-08-03 19:22:04
|
Update of /cvsroot/oprofile/oprofile/libutil++ In directory sc8-pr-cvs1:/tmp/cvs-serv454/libutil++ Modified Files: Tag: BRANCH_CALLGRAPH op_bfd.cpp op_bfd.h Log Message: biggish merge from head Index: op_bfd.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libutil++/op_bfd.cpp,v retrieving revision 1.24.2.4 retrieving revision 1.24.2.5 diff -u -p -d -r1.24.2.4 -r1.24.2.5 --- op_bfd.cpp 11 Jul 2003 01:39:56 -0000 1.24.2.4 +++ op_bfd.cpp 3 Aug 2003 19:22:01 -0000 1.24.2.5 @@ -54,8 +54,9 @@ op_bfd_symbol::op_bfd_symbol(bfd_vma vma } -op_bfd::op_bfd(string const & filename, string_filter const & symbol_filter) +op_bfd::op_bfd(string const & fname, string_filter const & symbol_filter) : + filename(fname), file_size(0), ibfd(0), text_offset(0), @@ -69,6 +70,8 @@ op_bfd::op_bfd(string const & filename, op_get_fsize(filename.c_str(), &file_size); + /* bfd keeps its own reference to the filename char *, + * so it must have a lifetime longer than the ibfd */ ibfd = bfd_openr(filename.c_str(), NULL); if (!ibfd) { @@ -115,18 +118,9 @@ op_bfd::~op_bfd() } -/** - * symcomp - comparator - * - */ -static bool symcomp(op_bfd_symbol const & a, op_bfd_symbol const & b) -{ - return a.filepos() < b.filepos(); -} - -bool op_bfd_symbol::operator<(op_bfd_symbol const& lhs) const +bool op_bfd_symbol::operator<(op_bfd_symbol const& rhs) const { - return symcomp(*this, lhs); + return filepos() < rhs.filepos(); } namespace { @@ -210,7 +204,7 @@ struct remove_filter { * * The symbols are filtered through * the interesting_symbol() predicate and sorted - * with the symcomp() comparator. + * with op_bfd_symbol::operator<() comparator. */ void op_bfd::get_symbols(op_bfd::symbols_found_t & symbols) { @@ -326,16 +320,18 @@ bool op_bfd::get_linenr(symbol_index_t s char const * cfilename = ""; bfd_vma pc; + op_bfd_symbol const & sym = syms[sym_idx]; + // take care about artificial symbol - if (syms[sym_idx].symbol() == 0) + if (sym.symbol() == 0) return false; - asection* section = syms[sym_idx].symbol()->section; + asection* section = sym.symbol()->section; if ((bfd_get_section_flags (ibfd, section) & SEC_ALLOC) == 0) return false; - pc = sym_offset(sym_idx, offset) + syms[sym_idx].value(); + pc = sym_offset(sym_idx, offset) + sym.value(); if (pc >= bfd_section_size(ibfd, section)) return false; @@ -349,10 +345,29 @@ bool op_bfd::get_linenr(symbol_index_t s ret = false; } - // functioname and symbol name can be different if we query linenr info - // if we accept it we can get samples for the wrong symbol (#484660) - if (ret && functionname && syms[sym_idx].name() != string(functionname)) { - ret = false; + // functionname and symbol name can be different if we accept it we + // can get samples for the wrong symbol (#484660) + // Note this break static inline function, since for these functions we + // get a different symbol name than symbol name but we recover later. + if (ret && functionname && sym.name() != string(functionname)) { + // gcc doesn't emit mangled name for C++ static function so we + // try to recover by accepting this linenr info if functionname + // is a substring of sym.name, this is not a bug see gcc + // bugzilla #11774. Check agaisnt the filename part of the + // is error prone error (e.g. namespace A { static int f1(); }) + // so we check only for a substring and warn the user. + static bool warned = false; + if (!warned) { + // FIXME: enough precise message ? We will get this + // message for static C++ function too, must we + // warn only if the following check fails ? + cerr << "warning: some functions compiled without " + << "debug information may have incorrect source " + << "line attributions" << endl; + warned = true; + } + if (sym.name().find(functionname) == string::npos) + ret = false; } /* binutils 2.12 and below have a small bug where functions without a @@ -370,8 +385,8 @@ bool op_bfd::get_linenr(symbol_index_t s if (linenr == 0) { // FIXME: looking at debug info for all gcc version shows // than the same problems can -perhaps- occur for epilog code: - // find a samples files with samples in epilog and try oprofpp - // -L -o on it, check it also with op_to_source. + // find a samples files with samples in epilog and try oreport + // -l -g on it, check it also with opannotate. // first restrict the search on a sensible range of vma, // 16 is an intuitive value based on epilog code look @@ -388,7 +403,7 @@ bool op_bfd::get_linenr(symbol_index_t s &linenr); if (ret && linenr != 0 - && syms[sym_idx].name() == string(functionname)) { + && sym.name() == string(functionname)) { return true; } } @@ -400,6 +415,9 @@ bool op_bfd::get_linenr(symbol_index_t s // multiple calls. The more easy way to recover is to reissue // the first call, we don't need to recheck return value, we // know that the call will succeed. + // As mentionned above a previous work-around break static + // inline function. We recover here by not checking than + // functionname == sym.name bfd_find_nearest_line(ibfd, section, bfd_syms.get(), pc, &cfilename, &functionname, &linenr); } @@ -547,7 +565,7 @@ op_bfd_symbol const op_bfd::create_artif string op_bfd::get_filename() const { - return bfd_get_filename(ibfd); + return filename; } Index: op_bfd.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/libutil++/op_bfd.h,v retrieving revision 1.18.2.1 retrieving revision 1.18.2.2 diff -u -p -d -r1.18.2.1 -r1.18.2.2 --- op_bfd.h 14 Jun 2003 01:07:27 -0000 1.18.2.1 +++ op_bfd.h 3 Aug 2003 19:22:01 -0000 1.18.2.2 @@ -157,6 +157,9 @@ public: size_t bfd_arch_bits_per_address() const; private: + /// filename we open + std::string filename; + /// file size in bytes off_t file_size; |