From: Philippe E. <ph...@us...> - 2002-03-13 21:26:45
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv23263/oprofile/pp Modified Files: opf_container.cpp opp_symbol.cpp oprofpp_util.cpp Log Message: pp/oprofpp_util : fix # 529622 - pp/opf_container.cpp, pp/opp_symbol.cp : tidy Index: opf_container.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/opf_container.cpp,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- opf_container.cpp 7 Mar 2002 23:21:26 -0000 1.28 +++ opf_container.cpp 13 Mar 2002 21:26:42 -0000 1.29 @@ -109,18 +109,14 @@ // get a vector of symbols sorted by increased count. void get_symbols_by_count(size_t counter, vector<const symbol_entry*>& v) const; private: - void flush_input_symbol(size_t counter) const; void build_by_file_loc() const; - vector<symbol_entry> v; - - typedef multiset<const symbol_entry *, less_symbol_entry_by_samples_nr> - set_symbol_by_samples_nr; + vector<symbol_entry> symbols; typedef set<const symbol_entry *, less_by_file_loc> set_symbol_by_file_loc; - // Carefull : these *MUST* be declared after the vector to ensure + // Carefull : this *MUST* be declared after the vector to ensure // a correct life-time. // symbol_entry sorted by decreasing samples number. // symbol_entry_by_samples_nr[0] is sorted from counter0 etc. @@ -129,8 +125,6 @@ // the nth first symbols that accumulate a certain amount of samples. // lazily build when necessary from const function so mutable - mutable set_symbol_by_samples_nr symbol_entry_by_samples_nr[OP_MAX_COUNTERS]; - mutable set_symbol_by_file_loc symbol_entry_by_file_loc; }; @@ -138,27 +132,21 @@ symbol_container_impl::symbol_container_impl() { - // symbol_entry_by_samples_nr has been setup by the default ctr, we - // need to rebuild it. do not assume that index 0 is correctly built - for (size_t i = 0 ; i < OP_MAX_COUNTERS ; ++i) { - less_symbol_entry_by_samples_nr compare(i); - symbol_entry_by_samples_nr[i] = set_symbol_by_samples_nr(compare); - } } inline size_t symbol_container_impl::size() const { - return v.size(); + return symbols.size(); } inline const symbol_entry & symbol_container_impl::operator[](size_t index) const { - return v[index]; + return symbols[index]; } inline void symbol_container_impl::push_back(const symbol_entry & symbol) { - v.push_back(symbol); + symbols.push_back(symbol); } const symbol_entry * @@ -179,21 +167,11 @@ return 0; } -void symbol_container_impl::flush_input_symbol(size_t counter) const -{ - // Update the sets of symbols entries sorted by samples count and the - // set of symbol entries sorted by file location. - if (v.size() && symbol_entry_by_samples_nr[counter].empty()) { - for (size_t i = 0 ; i < v.size() ; ++i) - symbol_entry_by_samples_nr[counter].insert(&v[i]); - } -} - void symbol_container_impl::build_by_file_loc() const { - if (v.size() && symbol_entry_by_file_loc.empty()) { - for (size_t i = 0 ; i < v.size() ; ++i) - symbol_entry_by_file_loc.insert(&v[i]); + if (symbols.size() && symbol_entry_by_file_loc.empty()) { + for (size_t i = 0 ; i < symbols.size() ; ++i) + symbol_entry_by_file_loc.insert(&symbols[i]); } } @@ -204,9 +182,10 @@ value.sample.vma = vma; vector<symbol_entry>::const_iterator it = - lower_bound(v.begin(), v.end(), value, less_sample_entry_by_vma()); + lower_bound(symbols.begin(), symbols.end(), + value, less_sample_entry_by_vma()); - if (it != v.end() && it->sample.vma == vma) + if (it != symbols.end() && it->sample.vma == vma) return &(*it); return 0; @@ -215,16 +194,14 @@ // get a vector of symbols sorted by increased count. void symbol_container_impl::get_symbols_by_count(size_t counter, vector<const symbol_entry*> & v) const { - flush_input_symbol(counter); - - v.clear(); + for (size_t i = 0 ; i < symbols.size() ; ++i) + v.push_back(&symbols[i]); - const set_symbol_by_samples_nr & temp = symbol_entry_by_samples_nr[counter]; + // check if this is necessary, already sanitized by caller ? + counter = counter == size_t(-1) ? 0 : counter; + less_symbol_entry_by_samples_nr compare(counter); - set_symbol_by_samples_nr::const_iterator it; - for (it = temp.begin() ; it != temp.end(); ++it) { - v.push_back(*it); - } + std::stable_sort(v.begin(), v.end(), compare); } //--------------------------------------------------------------------------- @@ -662,6 +639,7 @@ bool sort_by_vma) const { vector<const symbol_entry *> v; + symbols.get_symbols_by_count(ctr , v); u32 total_count = samples_count(ctr); Index: opp_symbol.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/opp_symbol.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- opp_symbol.cpp 7 Mar 2002 23:21:26 -0000 1.5 +++ opp_symbol.cpp 13 Mar 2002 21:26:42 -0000 1.6 @@ -341,36 +341,21 @@ string OutputSymbol::format_symb_name(const std::string & name, const sample_entry &, int) { - ostringstream out; - int const is_anon = name[0] == '?'; - if (!is_anon) - out << name; - else - out << "(no symbols)"; - - return out.str(); + return is_anon ? string("(no symbol)") : name; } string OutputSymbol::format_image_name(const std::string &, const sample_entry & sample, int) { - ostringstream out; - - out << sample.file_loc.image_name; - - return out.str(); + return sample.file_loc.image_name; } string OutputSymbol::format_short_image_name(const std::string &, const sample_entry & sample, int) { - ostringstream out; - - out << basename(sample.file_loc.image_name); - - return out.str(); + return basename(sample.file_loc.image_name); } string OutputSymbol::format_linenr_info(const std::string &, Index: oprofpp_util.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp_util.cpp,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- oprofpp_util.cpp 6 Mar 2002 21:52:17 -0000 1.35 +++ oprofpp_util.cpp 13 Mar 2002 21:26:42 -0000 1.36 @@ -574,6 +574,7 @@ if (filename == NULL || ret == false) { filename = ""; linenr = 0; + ret = false; } // functioname and symbol name can be different if we query linenr info @@ -581,6 +582,51 @@ if (ret == true && functionname && strcmp(functionname, syms[sym_idx]->name)) { ret = false; + } + + // gcc 2.95 defer emission of linenr info after the end of function + // prolog so on finding linenr info for samples inside the prolog + // (or for the function symbol itself) return always 0 as linenr. We + // work around by scanning forward for a vma with valid linenr info. + // Problem uncovered by Norbert Kaufmann. The work-around decrease, + // on tincas application, the number of failure to retrieve linenr + // info from 835 to 173. Most of the remaining are c++ inline function + // mainly from the stl library. Fix #529622 + if (/*ret == false || */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. + + // first restrict the search on a sensible range of vma, + // 16 is an intuitive value based on epilog code look + size_t max_search = 16; + size_t section_size = bfd_section_size(ibfd, section); + if (pc + max_search > section_size) + max_search = section_size - pc; + + for (size_t i = 1 ; i < max_search ; ++i) { + bool ret = bfd_find_nearest_line(ibfd, section, + bfd_syms, pc+i, + &filename, + &functionname, + &linenr); + + if (ret == true && linenr != 0 && + strcmp(functionname, syms[sym_idx]->name) == 0) { + return ret; // we win + } + } + + // We lose it's worthwhile to try more. + + // bfd_find_nearest_line clobber the memory pointed by filename + // from a previous call when the filename change across + // 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. + bfd_find_nearest_line(ibfd, section, bfd_syms, pc, + &filename, &functionname, &linenr); } return ret; |