[llvm] r305767 - [Coverage] PR33517: Check for failure to load func records

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 19 19:05:36 PDT 2017


Author: vedantk
Date: Mon Jun 19 21:05:35 2017
New Revision: 305767

URL: http://llvm.org/viewvc/llvm-project?rev=305767&view=rev
Log:
[Coverage] PR33517: Check for failure to load func records

With PR33517, it became apparent that symbol table creation can fail
when presented with malformed inputs. This patch makes that sort of
error detectable, so llvm-cov etc. can fail more gracefully.

Specifically, we now check that function records loaded from corrupted coverage
mapping data are rejected, e.g when the recorded function name is garbage.

Testing: check-{llvm,clang,profile}, some unit test updates.

Modified:
    llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp
    llvm/trunk/unittests/ProfileData/CoverageMappingTest.cpp

Modified: llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp?rev=305767&r1=305766&r2=305767&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp (original)
+++ llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp Mon Jun 19 21:05:35 2017
@@ -200,6 +200,9 @@ Error CoverageMapping::loadFunctionRecor
     const CoverageMappingRecord &Record,
     IndexedInstrProfReader &ProfileReader) {
   StringRef OrigFuncName = Record.FunctionName;
+  if (OrigFuncName.empty())
+    return make_error<CoverageMapError>(coveragemap_error::malformed);
+
   if (Record.Filenames.empty())
     OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName);
   else

Modified: llvm/trunk/unittests/ProfileData/CoverageMappingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ProfileData/CoverageMappingTest.cpp?rev=305767&r1=305766&r2=305767&view=diff
==============================================================================
--- llvm/trunk/unittests/ProfileData/CoverageMappingTest.cpp (original)
+++ llvm/trunk/unittests/ProfileData/CoverageMappingTest.cpp Mon Jun 19 21:05:35 2017
@@ -28,6 +28,19 @@ static ::testing::AssertionResult NoErro
                                        << "\n";
 }
 
+static ::testing::AssertionResult ErrorEquals(coveragemap_error Expected,
+                                              Error E) {
+  coveragemap_error Found;
+  std::string FoundMsg;
+  handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
+    Found = CME.get();
+    FoundMsg = CME.message();
+  });
+  if (Expected == Found)
+    return ::testing::AssertionSuccess();
+  return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
+}
+
 namespace llvm {
 namespace coverage {
 void PrintTo(const Counter &C, ::std::ostream *os) {
@@ -232,12 +245,14 @@ struct CoverageMappingTest : ::testing::
     return CoverageMapping::load(CoverageReaders, *ProfileReader);
   }
 
-  void loadCoverageMapping(bool EmitFilenames = true) {
+  Error loadCoverageMapping(bool EmitFilenames = true) {
     readProfCounts();
     writeAndReadCoverageRegions(EmitFilenames);
     auto CoverageOrErr = readOutputFunctions();
-    ASSERT_TRUE(NoError(CoverageOrErr.takeError()));
+    if (!CoverageOrErr)
+      return CoverageOrErr.takeError();
     LoadedCoverage = std::move(CoverageOrErr.get());
+    return Error::success();
   }
 };
 
@@ -304,7 +319,7 @@ TEST_P(CoverageMappingTest, load_coverag
     // in order to preserve that information during possible sorting of CMRs.
     addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1);
 
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   for (unsigned I = 0; I < N; ++I) {
     CoverageData Data = LoadedCoverage->getCoverageForFile(FileNames[I]);
@@ -313,6 +328,14 @@ TEST_P(CoverageMappingTest, load_coverag
   }
 }
 
+TEST_P(CoverageMappingTest, load_coverage_with_bogus_function_name) {
+  InstrProfRecord RecordFunc1("", 0x1234, {10});
+  NoError(ProfileWriter.addRecord(std::move(RecordFunc1)));
+  startFunction("", 0x1234);
+  addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5);
+  ErrorEquals(coveragemap_error::malformed, loadCoverageMapping());
+}
+
 TEST_P(CoverageMappingTest, load_coverage_for_several_functions) {
   InstrProfRecord RecordFunc1("func1", 0x1234, {10});
   NoError(ProfileWriter.addRecord(std::move(RecordFunc1)));
@@ -325,7 +348,7 @@ TEST_P(CoverageMappingTest, load_coverag
   startFunction("func2", 0x2345);
   addCMR(Counter::getCounter(0), "bar", 2, 2, 6, 6);
 
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
   EXPECT_EQ(2, std::distance(FunctionRecords.begin(), FunctionRecords.end()));
@@ -369,7 +392,7 @@ TEST_P(CoverageMappingTest, basic_covera
   addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
   addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
   addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -386,7 +409,7 @@ TEST_P(CoverageMappingTest, basic_covera
 TEST_P(CoverageMappingTest, uncovered_function) {
   startFunction("func", 0x1234);
   addCMR(Counter::getZero(), "file1", 1, 2, 3, 4);
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -399,7 +422,7 @@ TEST_P(CoverageMappingTest, uncovered_fu
   startFunction("func", 0x1234);
   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
   addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -417,7 +440,7 @@ TEST_P(CoverageMappingTest, combine_regi
   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
   addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
   addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -436,7 +459,7 @@ TEST_P(CoverageMappingTest, restore_comb
   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
   addCMR(Counter::getCounter(1), "file1", 1, 1, 9, 9);
   addCMR(Counter::getCounter(2), "file1", 3, 3, 5, 5);
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -460,7 +483,7 @@ TEST_P(CoverageMappingTest, dont_combine
   addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
   addCMR(Counter::getCounter(1), "include1", 6, 6, 7, 7);
   addExpansionCMR("file1", "include1", 3, 3, 4, 4);
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -483,7 +506,7 @@ TEST_P(CoverageMappingTest, combine_expa
   addExpansionCMR("file", "include1", 3, 1, 3, 5);
   addExpansionCMR("file", "include2", 3, 1, 3, 5);
 
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("file");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -500,7 +523,7 @@ TEST_P(CoverageMappingTest, strip_filena
 
   startFunction("file1:func", 0x1234);
   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   std::vector<std::string> Names;
   for (const auto &Func : LoadedCoverage->getCoveredFunctions())
@@ -515,7 +538,7 @@ TEST_P(CoverageMappingTest, strip_unknow
 
   startFunction("<unknown>:func", 0x1234);
   addCMR(Counter::getCounter(0), "", 1, 1, 9, 9);
-  loadCoverageMapping(/*EmitFilenames=*/false);
+  NoError(loadCoverageMapping(/*EmitFilenames=*/false));
 
   std::vector<std::string> Names;
   for (const auto &Func : LoadedCoverage->getCoveredFunctions())
@@ -538,7 +561,7 @@ TEST_P(CoverageMappingTest, dont_detect_
   addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
   addExpansionCMR("main", "expanded", 9, 1, 9, 5);
 
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   std::vector<const FunctionRecord *> Instantiations =
       LoadedCoverage->getInstantiations("expanded");
@@ -553,7 +576,7 @@ TEST_P(CoverageMappingTest, load_coverag
   addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
   addExpansionCMR("main", "expanded", 4, 1, 4, 5);
 
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   CoverageData Data = LoadedCoverage->getCoverageForFile("expanded");
   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
@@ -572,7 +595,7 @@ TEST_P(CoverageMappingTest, skip_duplica
   startFunction("func", 0x1234);
   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
 
-  loadCoverageMapping();
+  NoError(loadCoverageMapping());
 
   auto Funcs = LoadedCoverage->getCoveredFunctions();
   unsigned NumFuncs = std::distance(Funcs.begin(), Funcs.end());




More information about the llvm-commits mailing list