22 #define DMGL_AUTO (1 << 8)
23 extern char* cplus_demangle(
const char *mangled,
int options);
33 mutable unsigned int id_;
54 ULVec::const_iterator
i(a.
tree_.begin()),
e(a.
tree_.end());
55 while(
i!=
e) { ost << (
unsigned int)*
i <<
" "; ++
i; }
64 std::cerr <<
"cannot open output file " << name << std::endl;
65 throw std::runtime_error(
"failed to open output file");
72 static bool symSort(
const VertexSet::const_iterator&
a,
73 const VertexSet::const_iterator&
b)
75 return a->total_as_leaf_ < b->total_as_leaf_;
78 static bool idSort(
const VertexSet::const_iterator&
a,
79 const VertexSet::const_iterator&
b)
81 return a->id_ < b->id_;
85 const VertexSet::const_iterator&
b)
90 static bool pathSort(
const PathSet::const_iterator&
a,
91 const PathSet::const_iterator&
b)
93 return a->total_ < b->total_;
110 int sz =
read(
fd_,&cnt,
sizeof(
unsigned int));
113 perror(
"Reader::nextSample: read count");
114 std::cerr <<
"could not read next sample from profile data\n";
117 if(sz == 0)
return false;
118 if((
unsigned)sz<
sizeof(
unsigned int)) {
120 <<
"could not read the correct amount of profile data\n";
124 std::cerr <<
"Reader::nextSample: stack length is nonsense " << cnt <<
"\n";
130 int byte_cnt = cnt*
sizeof(
void*);
132 while((sz =
read(
fd_,pos,byte_cnt)) < byte_cnt) {
134 perror(
"Reader::nextSample: read stack");
145 std::string
const&
prefix)
147 std::string object_name;
148 if (info.dli_fname == 0 || info.dli_fname[0] == 0x0) {
149 std::ostringstream oss;
150 oss <<
"no_object_" << where;
153 if (info.dli_saddr)
return info.dli_sname;
154 std::ostringstream oss;
155 oss << prefix << where;
161 std::string output_tree(prefix+
"_paths");
162 std::string output_names(prefix+
"_names");
163 std::string output_totals(prefix+
"_totals");
165 std::ofstream nost(output_names.c_str());
166 std::ofstream tost(output_tree.c_str());
167 std::ofstream sost(output_totals.c_str());
175 std::pair<VertexSet::iterator,bool> irc,prev_irc;
176 std::pair<PathSet::iterator,bool> prc;
187 std::string unk(
"unknown_name");
194 VoidVec::reverse_iterator
c(v.rbegin()),
e(v.rend());
195 bool first_pass=
true;
202 void* addr =
static_cast<void*
>(
value);
204 if(dladdr(addr,&info) != 0) {
208 last_good_entry.
library_ = info.dli_fname;
209 last_good_entry.
id_ = 0;
210 void* function_address = info.dli_saddr;
215 last_good_entry.
addr_ =
216 function_address ? function_address :
value;
218 entry = &last_good_entry;
226 std::ostringstream oss;
227 oss <<
"lookup_failure_" << addr;
228 last_none_entry.
name_ = oss.str();
229 last_none_entry.
library_ =
"unknown";
233 entry = &last_none_entry;
240 irc.first->incTotal();
241 ptrack.
tree_.push_back(irc.first->id_);
243 if(!first_pass) ++prev_irc.first->edges_[irc.first->id_];
244 else first_pass=
false;
250 irc.first->incLeaf();
251 prc = pathset.insert(ptrack);
255 prc.first->incTotal();
260 int setsize = symset.size();
263 vsyms.reserve(setsize);
266 VertexSet::const_iterator isym(symset.begin()),esym(symset.end());
269 vsyms.push_back(isym);
281 PathSet::const_iterator pat_it_beg(pathset.begin()),
282 pat_it_end(pathset.end());
284 while(pat_it_beg!=pat_it_end) {
286 ULVec pathcopy(pat_it_beg->tree_);
288 std::sort(pathcopy.begin(), pathcopy.end());
289 ULVec::iterator iter = unique(pathcopy.begin(),pathcopy.end());
290 ULVec::iterator cop_beg(pathcopy.begin());
292 while(cop_beg!=iter) {
294 Viter::iterator sym_iter = upper_bound(vsyms.begin(),vsyms.end(),
296 if(sym_iter==vsyms.begin()) {
305 (*sym_iter)->incPath(pat_it_beg->total_);
313 VertexSet::iterator ver_iter(symset.begin()),ver_iter_end(symset.end());
314 float ftotal = (total != 0 ? (float)total : 1.0);
315 while(ver_iter != ver_iter_end) {
316 ver_iter->percent_leaf_ = (float)ver_iter->total_as_leaf_ / ftotal;
317 ver_iter->percent_path_ = (
float)ver_iter->in_path_ / ftotal;
326 Viter::reverse_iterator vvi(vsyms.rbegin()),vve(vsyms.rend());
328 nost << *(*vvi) <<
"\n";
335 int pathsize = pathset.size();
337 vpaths.reserve(pathsize);
339 PathSet::const_iterator ipath(pathset.begin()),epath(pathset.end());
340 while(ipath != epath) {
341 vpaths.push_back(ipath);
348 Piter::reverse_iterator ppi(vpaths.rbegin()),ppe(vpaths.rend());
350 tost << *(*ppi) <<
"\n";
355 sost <<
"total_samples " << total <<
"\n"
356 <<
"total_functions " << setsize <<
"\n"
357 <<
"total_paths " << pathsize <<
"\n"
358 <<
"total_edges " << edgesize << std::endl
359 <<
"total_failed_lookups " << total_failed << std::endl
360 <<
"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)
std::pair< std::string, MonitorElement * > entry
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)
static unsigned int next_id_
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