};
-extern "C" {
-struct gmon_hist_hdr;
-}
-
// An GprofUnwindSampleConsumer instance consumes UnwindSamples and tabulates
// them by buildid, for eventual writing out into gmon.out format files.
class GprofUnwindSampleConsumer: public UnwindSampleConsumer
case 'G':
gmon = true; /* Automatically enable gmon mode if they set a gmon option. */
- if (strcmp (arg, "none") == 0)
+ if (std::string_view(arg) == "none")
gmon_hist_split = HIST_SPLIT_NONE;
- else if (strcmp (arg, "even") == 0)
+ else if (std::string_view(arg) == "even")
gmon_hist_split = HIST_SPLIT_EVEN;
- else if (strcmp (arg, "flex") == 0)
+ else if (std::string_view(arg) == "flex")
gmon_hist_split = HIST_SPLIT_FLEX;
break;
if (show_summary)
{
- clog << format("starting perf_event_attr configuration type={:x} config={:x} {}{} \n",
+ clog << format("perf_event_attr configuration type={:x} config={:x} {}{} \n",
attr.type, attr.config,
(attr.freq ? "sample_freq=" : "sample_period="),
(attr.freq ? attr.sample_freq : attr.sample_period));
struct utsname u;
uname(&u);
int em = EM_NONE;
- if (strcmp(u.machine, "x86_64") == 0) em = EM_X86_64;
- else if (strcmp(u.machine, "i686") == 0 || strcmp(u.machine, "i386") == 0) em = EM_386;
- else if (strcmp(u.machine, "aarch64") == 0 || strcmp(u.machine, "armv7l")) em = EM_ARM;
+ std::string_view machine = u.machine;
+ if (machine == "x86_64") em = EM_X86_64;
+ else if (machine == "i686" || machine == "i386") em = EM_386;
+ else if (machine == "aarch64" || machine == "armv7l") em = EM_ARM;
else {
cerr << format("ERROR: Unsupported architecture: {}\n", u.machine);
exit(1);
const char *modname = dwfl_module_info (m, NULL, NULL, NULL, NULL,
NULL, &mainfile, &debugfile);
clog << format(" module={} mainfile={} debugfile={}\n",
- modname, mainfile, debugfile);
+ modname, mainfile, debugfile?debugfile:"<none>");
/* TODO: Also store this data to avoid repeated extraction for
the final buildid summary? */
#ifdef DEBUG_MODULES
// unwind data consumers // gprof
/* gmon.out file format bits */
-extern "C" {
-
#define GMON_MAGIC "gmon"
#define GMON_VERSION 1
char _dimension_string[16];
};
-};
void GprofUnwindSampleConsumer::record_gmon_hist(ostream &of, map<uint64_t, uint32_t> &histogram, uint64_t low_pc, uint64_t high_pc, uint64_t alignment)
{
uint32_t prof_rate = attr.sample_freq;
of.write(reinterpret_cast<const char *>(&prof_rate), sizeof(prof_rate));
// dimension string is 15 chars long (not null terminated)
- char dimension_string[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- if (libpfm_event != "")
- strncpy(dimension_string, libpfm_event.c_str(), 15);
- else
- strcpy(dimension_string, "ticks");
- of.write(reinterpret_cast<const char *>(dimension_string), 15);
+ std::string dimension_base = libpfm_event.empty() ? "ticks" :
+ libpfm_event.substr(0, 15);
+ dimension_base.resize(15, '\0'); // ensure exactly 15 bytes
+ of.write(dimension_base.data(), 15);
// dimension character abbreviation: just take the first char of above
- of.write(reinterpret_cast<const char *>(dimension_string), 1);
+ of.write(dimension_base.data(), 1);
// write histogram buckets
uint64_t bucket_addr = low_pc;
clog << "\n=== buildid / sample counts ===\n";
}
- UnwindStatsTable::buildid_map_t m (this->stats->buildid_tab.begin(), this->stats->buildid_tab.end());
- for (auto& p : m) // traverse in sorted order
+ UnwindStatsTable::buildid_map_t sorted_map (this->stats->buildid_tab.begin(), this->stats->buildid_tab.end());
+ for (auto& p : sorted_map) // traverse in sorted order
{
const string& buildid = p.first;
- UnwindModuleStats& m = p.second;
- this->record_gmon_out(buildid, m);
+ UnwindModuleStats& module_stats = p.second;
+ this->record_gmon_out(buildid, module_stats);
if (show_summary)
{
/* In record_gmon_out we will write the buildid-->path mapping
mainfile,
debugfile.empty() ? "" : " +debugfile ",
debugfile,
- m.histogram.size(),
- m.callgraph.size());
+ module_stats.histogram.size(),
+ module_stats.callgraph.size());
}
}
if (show_summary)
clog << "\n";
}
+
+int
+GprofUnwindSampleConsumer::maxframes()
+{
+ return 1; // gprof only needs one level of backtracing
+}
+
+
void GprofUnwindSampleConsumer::process(const UnwindSample *sample)
{
if (sample->addrs.size() < 1)
}
}
-int
-GprofUnwindSampleConsumer::maxframes()
-{
- return opt_maxframes >= 0 ? opt_maxframes : 1;
-}