[llvm] [SamplePGO] Handle "sequence too long" errors more gracefully (PR #114982)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 5 05:09:10 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-pgo

Author: Krzysztof Pszeniczny (amharc)

<details>
<summary>Changes</summary>

Currently the `SampleProfileReader` calls `std::vector::reserve` directly with the `size_t` it reads from the binary format. `std::vector::reserve` will throw `std::length_error` if the value is larger than `max_size()` (which results in an `abort()` in the `-fno-exceptions` mode). Having a function return `std::error_code` in some cases of malformed inputs, but throw an exception in others is confusing. Let's return `sampleprof_error::too_large` instead.

---
Full diff: https://github.com/llvm/llvm-project/pull/114982.diff


1 Files Affected:

- (modified) llvm/lib/ProfileData/SampleProfReader.cpp (+14-2) 


``````````diff
diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp
index 98c78443785275..70ae87dd22cd9a 100644
--- a/llvm/lib/ProfileData/SampleProfReader.cpp
+++ b/llvm/lib/ProfileData/SampleProfReader.cpp
@@ -857,9 +857,11 @@ std::error_code SampleProfileReaderExtBinaryBase::readFuncOffsetTable() {
     return EC;
 
   bool UseFuncOffsetList = useFuncOffsetList();
-  if (UseFuncOffsetList)
+  if (UseFuncOffsetList) {
+    if (*Size > FuncOffsetList.max_size())
+      return sampleprof_error::too_large;
     FuncOffsetList.reserve(*Size);
-  else
+  } else
     FuncOffsetTable.reserve(*Size);
 
   for (uint64_t I = 0; I < *Size; ++I) {
@@ -1112,9 +1114,13 @@ std::error_code SampleProfileReaderBinary::readNameTable() {
   bool UseMD5 = useMD5();
 
   NameTable.clear();
+  if (*Size > NameTable.max_size())
+    return sampleprof_error::too_large;
   NameTable.reserve(*Size);
   if (!ProfileIsCS) {
     MD5SampleContextTable.clear();
+    if (*Size > MD5SampleContextTable.max_size())
+      return sampleprof_error::too_large;
     if (UseMD5)
       MD5SampleContextTable.reserve(*Size);
     else
@@ -1157,6 +1163,8 @@ SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5,
       return sampleprof_error::truncated;
 
     NameTable.clear();
+    if (*Size > NameTable.max_size())
+      return sampleprof_error::too_large;
     NameTable.reserve(*Size);
     for (size_t I = 0; I < *Size; ++I) {
       using namespace support;
@@ -1177,6 +1185,8 @@ SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5,
       return EC;
 
     NameTable.clear();
+    if (*Size > NameTable.max_size())
+      return sampleprof_error::too_large;
     NameTable.reserve(*Size);
     if (!ProfileIsCS)
       MD5SampleContextTable.resize(*Size);
@@ -1206,6 +1216,8 @@ std::error_code SampleProfileReaderExtBinaryBase::readCSNameTableSec() {
     return EC;
 
   CSNameTable.clear();
+  if (*Size > CSNameTable.max_size())
+    return sampleprof_error::too_large;
   CSNameTable.reserve(*Size);
   if (ProfileIsCS) {
     // Delay MD5 computation of CS context until they are needed. Use 0 to

``````````

</details>


https://github.com/llvm/llvm-project/pull/114982


More information about the llvm-commits mailing list