[BOLT][merge-fdata] Skip truncated lines in raw profile data (#183187)

Raw profile data file may contain lines truncated due to unexpected
app exit. This change is to have merge_fdata check number of fields
in each line of raw profile data file and ignore a line if the number
is not expected.
This commit is contained in:
YongKang Zhu
2026-02-25 21:42:30 -08:00
committed by GitHub
parent d12870ea96
commit 143664fcd3
6 changed files with 52 additions and 10 deletions

View File

@@ -8,13 +8,13 @@
# CHECK: boltedcollection
# CHECK: no_lbr
# CHECK: 1 main 2
# CHECK: 1 main 0 2
#--- a.fdata
boltedcollection
no_lbr
1 main 1
1 main 0 1
#--- b.fdata
boltedcollection
no_lbr
1 main 1
1 main 0 1

View File

@@ -10,7 +10,7 @@
#--- a.fdata
boltedcollection
no_lbr
1 main 1
1 main 0 1
#--- b.fdata
no_lbr
1 main 1
1 main 0 1

View File

@@ -10,6 +10,6 @@
#--- a.fdata
no_lbr
1 main 1
1 main 0 1
#--- b.fdata
1 main 1
1 main 0 1

View File

@@ -8,11 +8,11 @@
# RUN: FileCheck %s --input-file %t/merged.fdata
# CHECK: no_lbr
# CHECK: 1 main 2
# CHECK: 1 main 0 2
#--- a.fdata
no_lbr
1 main 1
1 main 0 1
#--- b.fdata
no_lbr
1 main 1
1 main 0 1

View File

@@ -0,0 +1,20 @@
## Check that merge-fdata skips truncated lines with a warning
# REQUIRES: system-linux
# RUN: split-file %s %t
# RUN: merge-fdata %t/a.fdata %t/b.fdata -o %t/merged.fdata 2>&1 | \
# RUN: FileCheck -check-prefix=CHECK-WARN %s
# RUN: FileCheck %s --input-file %t/merged.fdata
# CHECK-WARN: WARNING: {{.*}}b.fdata: ignoring malformed entry
## Only the valid entry should appear in the merged output
# CHECK: 1 main 0 1 main 2 1 3
# CHECK-NOT: trunc
#--- a.fdata
1 main 0 1 main 2 0 1
#--- b.fdata
1 main 0 1 main 2 1 2
1 trunc 0 1

View File

@@ -318,11 +318,33 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
do {
StringRef Line(FdataLine);
Line = Line.rtrim();
if (Line.empty())
continue;
CounterTy Count;
unsigned Type = 0;
if (Line.split(' ').first.getAsInteger(10, Type))
report_error(Filename, "Malformed / corrupted entry type");
bool IsBranchEntry = Type < 3;
// Validate the number of fields in the line. Count only unescaped spaces
// as field separators, since function names may contain escaped spaces,
// like "foo\ bar".
size_t NumFields = 1;
for (size_t I = 0; I < Line.size(); ++I) {
if (Line[I] == '\\')
++I;
else if (Line[I] == ' ')
++NumFields;
}
size_t ExpectedFields =
IsBranchEntry ? (NoLBRCollection.value_or(false) ? 4 : 8) : 7;
if (NumFields != ExpectedFields) {
errs() << "WARNING: " << Filename << ": ignoring malformed entry with "
<< NumFields << " fields (expected " << ExpectedFields << ")\n";
continue;
}
auto [Signature, ExecCount] = Line.rsplit(' ');
if (ExecCount.getAsInteger(10, Count.Exec))
report_error(Filename, "Malformed / corrupted execution count");