23 #define DMGL_AUTO (1 << 8)
24 extern char* cplus_demangle(
const char *mangled,
int options);
34 mutable unsigned int id_;
55 ULVec::const_iterator
i(a.
tree_.begin()),
e(a.
tree_.end());
56 while(
i!=
e) { ost << (
unsigned int)*
i <<
" "; ++
i; }
65 std::cerr <<
"cannot open output file " << name << std::endl;
66 throw std::runtime_error(
"failed to open output file");
73 static bool symSort(
const VertexSet::const_iterator&
a,
74 const VertexSet::const_iterator&
b)
76 return a->total_as_leaf_ < b->total_as_leaf_;
79 static bool idSort(
const VertexSet::const_iterator&
a,
80 const VertexSet::const_iterator&
b)
82 return a->id_ < b->id_;
86 const VertexSet::const_iterator&
b)
91 static bool pathSort(
const PathSet::const_iterator&
a,
92 const PathSet::const_iterator&
b)
94 return a->total_ < b->total_;
111 int sz =
read(
fd_,&cnt,
sizeof(
unsigned int));
114 perror(
"Reader::nextSample: read count");
115 std::cerr <<
"could not read next sample from profile data\n";
118 if(sz == 0)
return false;
119 if((
unsigned)sz<
sizeof(
unsigned int)) {
121 <<
"could not read the correct amount of profile data\n";
125 std::cerr <<
"Reader::nextSample: stack length is nonsense " << cnt <<
"\n";
131 int byte_cnt = cnt*
sizeof(
void*);
133 while((sz =
read(
fd_,pos,byte_cnt)) < byte_cnt) {
135 perror(
"Reader::nextSample: read stack");
149 if (info.dli_fname == 0 || info.dli_fname[0] == 0x0) {
150 std::ostringstream oss;
151 oss <<
"no_object_" << where;
154 if (info.dli_saddr)
return info.dli_sname;
155 std::ostringstream oss;
156 oss << prefix << where;
166 std::ofstream nost(output_names.c_str());
167 std::ofstream tost(output_tree.c_str());
168 std::ofstream sost(output_totals.c_str());
176 std::pair<VertexSet::iterator,bool> irc,prev_irc;
177 std::pair<PathSet::iterator,bool> prc;
195 VoidVec::reverse_iterator
c(v.rbegin()),
e(v.rend());
196 bool first_pass=
true;
201 const Sym* entry = 0;
203 void* addr =
static_cast<void*
>(
value);
205 if(dladdr(addr,&info) != 0) {
209 last_good_entry.
library_ = info.dli_fname;
210 last_good_entry.
id_ = 0;
211 void* function_address = info.dli_saddr;
216 last_good_entry.
addr_ =
217 function_address ? function_address :
value;
219 entry = &last_good_entry;
227 std::ostringstream oss;
228 oss <<
"lookup_failure_" << addr;
229 last_none_entry.
name_ = oss.str();
230 last_none_entry.
library_ =
"unknown";
234 entry = &last_none_entry;
241 irc.first->incTotal();
242 ptrack.
tree_.push_back(irc.first->id_);
244 if(!first_pass) ++prev_irc.first->edges_[irc.first->id_];
245 else first_pass=
false;
251 irc.first->incLeaf();
252 prc = pathset.insert(ptrack);
256 prc.first->incTotal();
261 int setsize = symset.size();
264 vsyms.reserve(setsize);
267 VertexSet::const_iterator isym(symset.begin()),esym(symset.end());
270 vsyms.push_back(isym);
282 PathSet::const_iterator pat_it_beg(pathset.begin()),
283 pat_it_end(pathset.end());
285 while(pat_it_beg!=pat_it_end) {
287 ULVec pathcopy(pat_it_beg->tree_);
289 std::sort(pathcopy.begin(), pathcopy.end());
290 ULVec::iterator
iter = unique(pathcopy.begin(),pathcopy.end());
291 ULVec::iterator cop_beg(pathcopy.begin());
293 while(cop_beg!=iter) {
295 Viter::iterator sym_iter = upper_bound(vsyms.begin(),vsyms.end(),
297 if(sym_iter==vsyms.begin()) {
306 (*sym_iter)->incPath(pat_it_beg->total_);
314 VertexSet::iterator ver_iter(symset.begin()),ver_iter_end(symset.end());
315 float ftotal = (total != 0 ? (float)total : 1.0);
316 while(ver_iter != ver_iter_end) {
317 ver_iter->percent_leaf_ = (float)ver_iter->total_as_leaf_ / ftotal;
318 ver_iter->percent_path_ = (
float)ver_iter->in_path_ / ftotal;
327 Viter::reverse_iterator vvi(vsyms.rbegin()),vve(vsyms.rend());
329 nost << *(*vvi) <<
"\n";
336 int pathsize = pathset.size();
338 vpaths.reserve(pathsize);
340 PathSet::const_iterator ipath(pathset.begin()),epath(pathset.end());
341 while(ipath != epath) {
342 vpaths.push_back(ipath);
349 Piter::reverse_iterator ppi(vpaths.rbegin()),ppe(vpaths.rend());
351 tost << *(*ppi) <<
"\n";
356 sost <<
"total_samples " << total <<
"\n"
357 <<
"total_functions " << setsize <<
"\n"
358 <<
"total_paths " << pathsize <<
"\n"
359 <<
"total_edges " << edgesize << std::endl
360 <<
"total_failed_lookups " << total_failed << std::endl
361 <<
"total_missing_sym_entries " << total_missing << std::endl;
static bool idSort(const VertexSet::const_iterator &a, const VertexSet::const_iterator &b)
std::vector< VertexSet::const_iterator > Viter
static bool idComp(unsigned int id, const VertexSet::const_iterator &b)
std::ostream & operator<<(std::ostream &out, const ALILine &li)
static bool symSort(const VertexSet::const_iterator &a, const VertexSet::const_iterator &b)
static std::atomic< unsigned int > next_id_
static std::atomic< int > next_id_
std::string make_name(Dl_info const &info, void *where, std::string const &prefix)
bool operator<(const PathTracker &a) const
std::vector< void * > VoidVec
std::vector< PathSet::const_iterator > Piter
std::vector< unsigned int > ULVec
void writeProfileDataC(int fd, const std::string &prefix)
bool nextSample(VoidVec &vv)
void writeProfileData(int fd, const std::string &prefix)
void verifyFile(std::ostream &ost, const std::string &name)
std::set< VertexTracker > VertexSet
static bool pathSort(const PathSet::const_iterator &a, const PathSet::const_iterator &b)
std::set< PathTracker > PathSet