From: Serhei Makarov Date: Thu, 26 Feb 2026 17:03:45 +0000 (-0500) Subject: src/stackprof.cxx: Restrict recorded pcs to mod->low_addr..high_addr X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=31d7abd06758253bc8e54b1aea036d8b2a2ab244;p=thirdparty%2Felfutils.git src/stackprof.cxx: Restrict recorded pcs to mod->low_addr..high_addr This covers the ld-linux.so out-of-range pc. Not seeing the range check being triggered for any other modules. --- diff --git a/src/stackprof.cxx b/src/stackprof.cxx index 7f6d1f5f..2d89e919 100644 --- a/src/stackprof.cxx +++ b/src/stackprof.cxx @@ -2018,7 +2018,9 @@ void GprofUnwindSampleConsumer::process(const UnwindSample *sample) const char *mainfile; const char *debugfile; - dwfl_module_info (mod, NULL, NULL, NULL, NULL, + Dwarf_Addr low_addr; + Dwarf_Addr high_addr; + dwfl_module_info (mod, NULL, &low_addr, &high_addr, NULL, NULL, &mainfile, &debugfile); if (mainfile && !buildid_to_mainfile.count(buildid)) buildid_to_mainfile[buildid] = mainfile; @@ -2028,7 +2030,17 @@ void GprofUnwindSampleConsumer::process(const UnwindSample *sample) UnwindModuleStats *buildid_ent = this->stats->buildid_find_or_create(buildid, mod); + uint64_t last_pc = pc; int i = dwfl_module_relocate_address (mod, &pc); + /* XXX: Out-of-range address seen with ld-linux.so, not useful for profiledb purposes: */ + if ((last_pc < low_addr || last_pc > high_addr)) + { + if (verbose) + clog << format(N_("{}: Skipping pc={:x} raw_pc={:x} outside module range start={:x}..end={:x}"), + mainfile == NULL ? "" : mainfile, + pc, last_pc, low_addr, high_addr) << endl; + return; + } (void) i; // XXX: could get dwfl_module_relocation_info (mod, i, NULL), but no need? buildid_ent->record_pc(pc); @@ -2037,7 +2049,16 @@ void GprofUnwindSampleConsumer::process(const UnwindSample *sample) // call, so we can't track it as a call-graph arc. TODO: at least count them if (sample->addrs.size() >= 2 && mod == mod2) // intra-module call { + last_pc = pc2; int j = dwfl_module_relocate_address (mod, &pc2); // map pc2 also + if (last_pc < low_addr || last_pc > high_addr) + { + if (verbose) + clog << format(N_("{}: Skipping pc={:x} raw_pc={:x} outside module range start={:x}..end={:x}"), + mainfile == NULL ? "" : mainfile, + pc, last_pc, low_addr, high_addr) << endl; + return; + } (void) j; buildid_ent->record_callgraph_arc(pc2, pc); }