[llvm] [Profile] Add a more descriptive message to the bad_header error (PR #211281)
Wael Yehia via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 12 07:39:33 PDT 2026
https://github.com/w2yehia updated https://github.com/llvm/llvm-project/pull/211281
>From de96c8200206432b63db70fdcda1a7e9e5c3efe2 Mon Sep 17 00:00:00 2001
From: Wael Yehia <wyehia at ca.ibm.com>
Date: Wed, 22 Jul 2026 03:43:48 +0000
Subject: [PATCH 1/2] [Profile] Add a more descriptive message to the
bad_header error
---
llvm/lib/ProfileData/InstrProfReader.cpp | 33 ++++++++++++--
.../insufficient-binary-ids-size.test | 20 ++++++---
.../misaligned-binary-ids-size.test | 2 +-
.../raw-magic-but-no-header.test | 2 +-
.../llvm-profdata/truncated-profile.test | 44 +++++++++++++++++++
5 files changed, 90 insertions(+), 11 deletions(-)
create mode 100644 llvm/test/tools/llvm-profdata/truncated-profile.test
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index 05770f83ed160..444ac90768d48 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -513,7 +513,8 @@ Error RawInstrProfReader<IntPtrT>::readHeader() {
if (!hasFormat(*DataBuffer))
return error(instrprof_error::bad_magic);
if (DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header))
- return error(instrprof_error::bad_header);
+ return error(instrprof_error::bad_header,
+ std::string("Profile file header is truncated"));
auto *Header = reinterpret_cast<const RawInstrProf::Header *>(
DataBuffer->getBufferStart());
ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
@@ -597,7 +598,10 @@ Error RawInstrProfReader<IntPtrT>::readHeader(
const uint8_t *BinaryIdEnd = BinaryIdStart + BinaryIdSize;
const uint8_t *BufferEnd = (const uint8_t *)DataBuffer->getBufferEnd();
if (BinaryIdSize % sizeof(uint64_t) || BinaryIdEnd > BufferEnd)
- return error(instrprof_error::bad_header);
+ return error(instrprof_error::bad_header,
+ ("BinaryIdSize (" + Twine(BinaryIdSize) +
+ ") is not a multiple of 8 or the profile is truncated")
+ .str());
ArrayRef<uint8_t> BinaryIdsBuffer(BinaryIdStart, BinaryIdSize);
if (!BinaryIdsBuffer.empty()) {
if (Error Err = readBinaryIdsInternal(*DataBuffer, BinaryIdsBuffer,
@@ -650,7 +654,25 @@ Error RawInstrProfReader<IntPtrT>::readHeader(
auto *Start = reinterpret_cast<const char *>(&Header);
if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
- return error(instrprof_error::bad_header);
+ return error(
+ instrprof_error::bad_header,
+ ("Profile file size (" + Twine(DataBuffer->getBufferSize()) +
+ " bytes) smaller than expected (at least " + Twine(ValueDataOffset) +
+ " bytes = " +
+ Twine(BinaryIdSize) + "(BinaryIdSize) + " +
+ Twine(DataSize) + "(DataSize) + " +
+ Twine(CountersSize) + "(CountersSize) + " +
+ Twine(NumBitmapBytes) + "(NumBitmapBytes) + " +
+ Twine(UniformCountersSectionSize) + "(UniformCountersSectionSize) + " +
+ Twine(NamesSize) + "(NamesSize) + " +
+ Twine(VTableSectionSize) + "(VTableSectionSize) + " +
+ Twine(VTableNameSize) + "(VTableNameSize) + " +
+ Twine(DataOffset - BinaryIdSize + PaddingBytesBeforeCounters +
+ PaddingBytesAfterCounters + PaddingBytesAfterBitmapBytes +
+ PaddingBytesAfterUniformCounters + PaddingBytesAfterNames +
+ PaddingBytesAfterVTableProfData + PaddingBytesAfterVTableNames) +
+ "(Padding))")
+ .str());
if (BIDFetcher) {
std::vector<object::BuildID> BinaryIDs;
@@ -1373,7 +1395,10 @@ Error IndexedInstrProfReader::readHeader() {
uint64_t BinaryIdsSize =
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
if (BinaryIdsSize % sizeof(uint64_t))
- return error(instrprof_error::bad_header);
+ return error(instrprof_error::bad_header,
+ ("BinaryIdSize (" + Twine(BinaryIdsSize) +
+ ") is not a multiple of 8")
+ .str());
// Set the binary ids start.
BinaryIdsBuffer = ArrayRef<uint8_t>(Ptr, BinaryIdsSize);
if (Ptr > (const unsigned char *)DataBuffer->getBufferEnd())
diff --git a/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test b/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test
index 66fba4ba495b7..b2ee0d9246735 100644
--- a/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test
+++ b/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test
@@ -3,12 +3,13 @@
// TODO: use a builtin version of printf
UNSUPPORTED: system-zos
RUN: printf '\201rforpl\377' > %t.profraw
-RUN: printf '\10\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\x0B\0\0\0\0\0\0\0' >> %t.profraw
// We should fail on this because the data buffer (profraw file) is not long
// enough to hold this binary IDs size. NOTE that this (combined with the 8-byte
// alignment requirement for binary IDs size) will ensure we can at least read one
// 8-byte size if the binary IDs are provided.
-RUN: printf '\8\0\0\0\0\0\0\0' >> %t.profraw
+// BinaryIdSize - set to 8 bytes
+RUN: printf '\x08\0\0\0\0\0\0\0' >> %t.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
@@ -17,8 +18,17 @@ RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
-
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// ^^ end of Profile Header ^^
+// Incomplete binary IDs data - only 7 bytes instead of 8
RUN: printf '\0\0\0\0\0\0\0' >> %t.profraw
-// RUN: not llvm-profdata show --binary-ids %t.profraw 2>&1 | FileCheck %s
-// CHECK: invalid instrumentation profile data (file header is corrupt)
+RUN: not llvm-profdata show --binary-ids %t.profraw 2>&1 | FileCheck %s
+CHECK: invalid instrumentation profile data (file header is corrupt): BinaryIdSize (8) is not a multiple of 8 or the profile is truncated
diff --git a/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test b/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test
index 46be16d8b728b..4214b15575560 100644
--- a/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test
+++ b/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test
@@ -30,4 +30,4 @@ RUN: printf '\2\2\2\2\2\2\2\2' >> %t.profraw
RUN: printf '\3\3\3\3\0\0\0\0' >> %t.profraw
// RUN: not llvm-profdata show --binary-ids %t.profraw 2>&1 | FileCheck %s
-// CHECK: invalid instrumentation profile data (file header is corrupt)
+// CHECK: invalid instrumentation profile data (file header is corrupt): BinaryIdSize (63) is not a multiple of 8 or the profile is truncated
diff --git a/llvm/test/tools/llvm-profdata/raw-magic-but-no-header.test b/llvm/test/tools/llvm-profdata/raw-magic-but-no-header.test
index caec1663a04fd..31e1588eedcff 100644
--- a/llvm/test/tools/llvm-profdata/raw-magic-but-no-header.test
+++ b/llvm/test/tools/llvm-profdata/raw-magic-but-no-header.test
@@ -7,4 +7,4 @@ RUN: not llvm-profdata show %t 2>&1 | FileCheck %s
RUN: printf '\377lprofr\201' > %t
RUN: not llvm-profdata show %t 2>&1 | FileCheck %s
-CHECK: error: {{.+}}: invalid instrumentation profile data (file header is corrupt)
+CHECK: error: {{.+}}: invalid instrumentation profile data (file header is corrupt): Profile file header is truncated
diff --git a/llvm/test/tools/llvm-profdata/truncated-profile.test b/llvm/test/tools/llvm-profdata/truncated-profile.test
new file mode 100644
index 0000000000000..fc51a21b217c3
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/truncated-profile.test
@@ -0,0 +1,44 @@
+// Magic
+RUN: printf '\x81rforpl\xff' > %t.profraw
+// Version (11 = 0x0B)
+RUN: printf '\13\0\0\0\0\0\0\0' >> %t.profraw
+// BinaryIdsSize
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// NumData
+RUN: printf '\1\0\0\0\0\0\0\0' >> %t.profraw
+// PaddingBytesBeforeCounters
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// NumCounters
+RUN: printf '\1\0\0\0\0\0\0\0' >> %t.profraw
+// PaddingBytesAfterCounters
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// NumBitmapBytes
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// PaddingBytesAfterBitmapBytes
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// NumUniformCounters
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// PaddingBytesAfterUniformCounters
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// UniformCountersDelta
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// NamesSize
+RUN: printf '\x10\0\0\0\0\0\0\0' >> %t.profraw
+// CountersDelta
+RUN: printf '\xF8\xFF\xFF\xFF\0\0\0\0' >> %t.profraw
+// BitmapDelta
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// NamesDelta
+RUN: printf '\x58\x87\x00\x10\0\0\0\0' >> %t.profraw
+// NumVTables
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// VNamesSize
+RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
+// ValueKindLast
+RUN: printf '\3\0\0\0\0\0\0\0' >> %t.profraw
+// No Binary Ids
+// Array of __llvm_prof_data goes next but we'll truncate it to 4 bytes
+RUN: printf '\0\0\0\0' >> %t.profraw
+
+RUN: not llvm-profdata show %t.profraw 2>&1 | FileCheck %s
+CHECK: invalid instrumentation profile data (file header is corrupt): Profile file size (156 bytes) smaller than expected (at least 248 bytes = 0(BinaryIdSize) + 72(DataSize) + 8(CountersSize) + 0(NumBitmapBytes) + 0(UniformCountersSectionSize) + 16(NamesSize) + 0(VTableSectionSize) + 0(VTableNameSize) + 152(Padding))
>From 089d93a0fbdab747b88764ce2069c54cb29b2d8b Mon Sep 17 00:00:00 2001
From: Wael Yehia <wyehia at ca.ibm.com>
Date: Wed, 12 Aug 2026 14:07:32 +0000
Subject: [PATCH 2/2] address review comments
---
llvm/lib/ProfileData/InstrProfReader.cpp | 13 ++++++++-----
.../llvm-profdata/insufficient-binary-ids-size.test | 2 +-
.../llvm-profdata/misaligned-binary-ids-size.test | 2 +-
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index 444ac90768d48..34a7505d8fc81 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -597,11 +597,14 @@ Error RawInstrProfReader<IntPtrT>::readHeader(
reinterpret_cast<const uint8_t *>(&Header) + sizeof(RawInstrProf::Header);
const uint8_t *BinaryIdEnd = BinaryIdStart + BinaryIdSize;
const uint8_t *BufferEnd = (const uint8_t *)DataBuffer->getBufferEnd();
- if (BinaryIdSize % sizeof(uint64_t) || BinaryIdEnd > BufferEnd)
- return error(instrprof_error::bad_header,
- ("BinaryIdSize (" + Twine(BinaryIdSize) +
- ") is not a multiple of 8 or the profile is truncated")
- .str());
+ if (BinaryIdSize % sizeof(uint64_t))
+ return error(
+ instrprof_error::bad_header,
+ ("BinaryIdSize (" + Twine(BinaryIdSize) + ") is not a multiple of 8")
+ .str());
+ if (BinaryIdEnd > BufferEnd)
+ return error(instrprof_error::truncated);
+
ArrayRef<uint8_t> BinaryIdsBuffer(BinaryIdStart, BinaryIdSize);
if (!BinaryIdsBuffer.empty()) {
if (Error Err = readBinaryIdsInternal(*DataBuffer, BinaryIdsBuffer,
diff --git a/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test b/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test
index b2ee0d9246735..8df89a9ca6cb1 100644
--- a/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test
+++ b/llvm/test/tools/llvm-profdata/insufficient-binary-ids-size.test
@@ -31,4 +31,4 @@ RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw
RUN: printf '\0\0\0\0\0\0\0' >> %t.profraw
RUN: not llvm-profdata show --binary-ids %t.profraw 2>&1 | FileCheck %s
-CHECK: invalid instrumentation profile data (file header is corrupt): BinaryIdSize (8) is not a multiple of 8 or the profile is truncated
+CHECK: truncated profile data
diff --git a/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test b/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test
index 4214b15575560..70662390d5e3b 100644
--- a/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test
+++ b/llvm/test/tools/llvm-profdata/misaligned-binary-ids-size.test
@@ -30,4 +30,4 @@ RUN: printf '\2\2\2\2\2\2\2\2' >> %t.profraw
RUN: printf '\3\3\3\3\0\0\0\0' >> %t.profraw
// RUN: not llvm-profdata show --binary-ids %t.profraw 2>&1 | FileCheck %s
-// CHECK: invalid instrumentation profile data (file header is corrupt): BinaryIdSize (63) is not a multiple of 8 or the profile is truncated
+// CHECK: invalid instrumentation profile data (file header is corrupt): BinaryIdSize (63) is not a multiple of 8
More information about the llvm-commits
mailing list