#include <string>
Go to the source code of this file.
Functions | |
void | writeProfileData (int inputFileDescriptor, const std::string &prefix) |
Definition at line 159 of file ProfParse.cc.
References addr, Sym::addr_, c, e, lat::endl(), Sym::id_, idComp(), idSort(), info, iter, len, Sym::library_, make_name(), name, Sym::name_, Sym::next_id_, Reader::nextSample(), pathSort(), r, python::multivaluedict::sort(), symSort(), PathTracker::tree_, v, value, and verifyFile().
Referenced by SimpleProfiler::complete(), and writeProfileDataC().
00160 { 00161 std::string output_tree(prefix+"_paths"); 00162 std::string output_names(prefix+"_names"); 00163 std::string output_totals(prefix+"_totals"); 00164 00165 std::ofstream nost(output_names.c_str()); 00166 std::ofstream tost(output_tree.c_str()); 00167 std::ofstream sost(output_totals.c_str()); 00168 00169 verifyFile(nost,output_names); 00170 verifyFile(tost,output_tree); 00171 verifyFile(sost,output_totals); 00172 00173 VertexSet symset; 00174 PathSet pathset; 00175 std::pair<VertexSet::iterator,bool> irc,prev_irc; 00176 std::pair<PathSet::iterator,bool> prc; 00177 00178 VoidVec v; 00179 int len=0; 00180 int total=0; 00181 int total_failed=0; 00182 int total_missing=0; 00183 // int failure_count=0; 00184 Sym last_none_entry; 00185 Sym last_good_entry; 00186 Reader r(fd); 00187 std::string unk("unknown_name"); 00188 00189 while (r.nextSample(v)) { 00190 PathTracker ptrack; 00191 ++total; 00192 len = v.size(); 00193 if(len==0) continue; // should never happen! 00194 VoidVec::reverse_iterator c(v.rbegin()),e(v.rend()); 00195 bool first_pass=true; 00196 00197 while(c != e) { 00198 Sym::address_type value = reinterpret_cast<Sym::address_type>(*c); 00199 00200 const Sym* entry = 0; 00201 Dl_info info; 00202 void* addr = static_cast<void*>(value); 00203 00204 if(dladdr(addr,&info) != 0) { 00205 std::string name = make_name(info, addr, "unknown_"); 00206 00207 last_good_entry.name_ = name; 00208 last_good_entry.library_ = info.dli_fname; 00209 last_good_entry.id_ = 0; 00210 void* function_address = info.dli_saddr; 00211 00212 // If we find the address of this function, we make a 00213 // unique VertexTracker for that function. If not, we 00214 // make a unique VertexTracker for this exact address. 00215 last_good_entry.addr_ = 00216 function_address ? function_address : value; 00217 00218 entry = &last_good_entry; 00219 } else { // dladdr has failed 00220 /* 00221 std::cerr << "sample " << total 00222 << ": dladdr failed for address: " << *c 00223 << std::endl; 00224 */ 00225 ++total_failed; 00226 std::ostringstream oss; 00227 oss << "lookup_failure_" << addr; 00228 last_none_entry.name_ = oss.str(); 00229 last_none_entry.library_ = "unknown"; 00230 last_none_entry.id_ = Sym::next_id_++; 00231 last_none_entry.addr_ = value; 00232 00233 entry = &last_none_entry; 00234 } 00235 00236 irc = symset.insert(VertexTracker(*entry)); 00237 if(irc.second) { 00238 irc.first->setID(); 00239 } 00240 irc.first->incTotal(); 00241 ptrack.tree_.push_back(irc.first->id_); 00242 00243 if(!first_pass) ++prev_irc.first->edges_[irc.first->id_]; 00244 else first_pass=false; 00245 00246 prev_irc = irc; 00247 ++c; 00248 } 00249 00250 irc.first->incLeaf(); 00251 prc = pathset.insert(ptrack); 00252 if(prc.second) { 00253 prc.first->setID(); 00254 } 00255 prc.first->incTotal(); 00256 } 00257 00258 // ------------------ copy the vertices for sorting and searching ------ 00259 00260 int setsize = symset.size(); 00261 int edgesize = 0; 00262 Viter vsyms; 00263 vsyms.reserve(setsize); 00264 00265 //cout << "------ symset -----" << std::endl; 00266 VertexSet::const_iterator isym(symset.begin()),esym(symset.end()); 00267 while(isym!=esym) { 00268 //cout << " " << *isym << std::endl; 00269 vsyms.push_back(isym); 00270 ++isym; 00271 } 00272 00273 // ------ calculate samples for parents and percentages in vertices ------ 00274 00275 //edm::sort_all(vsyms,idSort); 00276 std::sort(vsyms.begin(), vsyms.end(), idSort); 00277 //Viter::iterator Vib(vsyms.begin()),Vie(vsyms.end()); 00278 //std::cout << "sorted table --------------" << std::endl; 00279 //while(Vib!=Vie) { std::cout << " " << *(*Vib) << std::endl; ++Vib; } 00280 00281 PathSet::const_iterator pat_it_beg(pathset.begin()), 00282 pat_it_end(pathset.end()); 00283 00284 while(pat_it_beg!=pat_it_end) { 00285 // get set of unique IDs from the path 00286 ULVec pathcopy(pat_it_beg->tree_); 00287 //edm::sort_all(pathcopy); 00288 std::sort(pathcopy.begin(), pathcopy.end()); 00289 ULVec::iterator iter = unique(pathcopy.begin(),pathcopy.end()); 00290 ULVec::iterator cop_beg(pathcopy.begin()); 00291 //cout << "length of unique = " << distance(cop_beg,iter) << std::endl; 00292 while(cop_beg!=iter) { 00293 //cout << " entry " << *cop_beg << std::endl; 00294 Viter::iterator sym_iter = upper_bound(vsyms.begin(),vsyms.end(), 00295 *cop_beg,idComp); 00296 if(sym_iter==vsyms.begin()) { 00297 ++total_missing; 00298 /* 00299 std::cerr << "found a missing sym entry for address " << *cop_beg 00300 << std::endl; 00301 */ 00302 } else { 00303 --sym_iter; 00304 //cout << " symiter " << *(*sym_iter) << std::endl; 00305 (*sym_iter)->incPath(pat_it_beg->total_); 00306 } 00307 ++cop_beg; 00308 } 00309 00310 ++pat_it_beg; 00311 } 00312 00313 VertexSet::iterator ver_iter(symset.begin()),ver_iter_end(symset.end()); 00314 while(ver_iter != ver_iter_end) { 00315 ver_iter->percent_leaf_ = (float)ver_iter->total_as_leaf_ / (float)total; 00316 ver_iter->percent_path_ = (float)ver_iter->in_path_ / (float)total; 00317 ++ver_iter; 00318 } 00319 00320 // -------------- write out the vertices ---------------- 00321 00322 00323 //edm::sort_all(vsyms,symSort); 00324 std::sort(vsyms.begin(), vsyms.end(), symSort); 00325 Viter::reverse_iterator vvi(vsyms.rbegin()),vve(vsyms.rend()); 00326 while(vvi != vve) { 00327 nost << *(*vvi) << "\n"; 00328 ++vvi; 00329 } 00330 00331 00332 // --------------- write out the paths ------------------ 00333 00334 int pathsize = pathset.size(); 00335 Piter vpaths; 00336 vpaths.reserve(pathsize); 00337 00338 PathSet::const_iterator ipath(pathset.begin()),epath(pathset.end()); 00339 while(ipath != epath) { 00340 vpaths.push_back(ipath); 00341 ++ipath; 00342 } 00343 00344 //edm::sort_all(vpaths,pathSort); 00345 std::sort(vpaths.begin(),vpaths.end(),pathSort); 00346 00347 Piter::reverse_iterator ppi(vpaths.rbegin()),ppe(vpaths.rend()); 00348 while(ppi != ppe) { 00349 tost << *(*ppi) << "\n"; 00350 ++ppi; 00351 } 00352 00353 // ------------ totals -------------------- 00354 sost << "total_samples " << total << "\n" 00355 << "total_functions " << setsize << "\n" 00356 << "total_paths " << pathsize << "\n" 00357 << "total_edges " << edgesize << std::endl 00358 << "total_failed_lookups " << total_failed << std::endl 00359 << "total_missing_sym_entries " << total_missing << std::endl; 00360 00361 }