-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[llvm-cov] Add --debug-info flag to llvm-cov to lookup debug info file. #66798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Test debug info correlate with clang coverage. | ||
|
||
// Test the case when there is no __llvm_prf_names in the binary. | ||
// RUN: %clang_profgen -o %t.normal -fcoverage-mapping %S/../Inputs/instrprof-debug-info-correlate-main.cpp %S/../Inputs/instrprof-debug-info-correlate-foo.cpp | ||
// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal | ||
// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw | ||
|
||
// RUN: %clang_profgen -o %t -g -mllvm --debug-info-correlate -fcoverage-mapping %S/../Inputs/instrprof-debug-info-correlate-main.cpp %S/../Inputs/instrprof-debug-info-correlate-foo.cpp | ||
// RUN: env LLVM_PROFILE_FILE=%t.proflite %run %t | ||
// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.proflite | ||
|
||
// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata) | ||
|
||
// RUN: llvm-cov report --instr-profile=%t.profdata %t | FileCheck %s -check-prefix=NONAME | ||
|
||
// Test debug info correlate with clang coverage (online merging). | ||
|
||
// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t.normal | ||
// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t.normal | ||
// RUN: llvm-profdata merge -o %t.normal.profdata %t-1.profraw %t-2.profraw | ||
|
||
// RUN: rm -rf %t.profdir && mkdir %t.profdir | ||
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t | ||
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t | ||
// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.profdir | ||
|
||
// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata) | ||
|
||
// RUN: llvm-cov report --instr-profile=%t.profdata %t | FileCheck %s -check-prefix=NONAME | ||
// RUN: llvm-cov report --instr-profile=%t.normal.profdata %t | FileCheck %s -check-prefix=NONAME | ||
|
||
// NONAME: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover | ||
// NONAME-NEXT: -- | ||
// NONAME-NEXT: instrprof-debug-info-correlate-bar.h 3 1 66.67% 1 0 100.00% 5 1 80.00% 2 1 50.00% | ||
// NONAME-NEXT: instrprof-debug-info-correlate-foo.cpp 5 2 60.00% 2 1 50.00% 6 2 66.67% 2 1 50.00% | ||
// NONAME-NEXT: instrprof-debug-info-correlate-main.cpp 4 0 100.00% 1 0 100.00% 5 0 100.00% 2 0 100.00% | ||
// NONAME-NEXT: -- | ||
// NONAME-NEXT: TOTAL 12 3 75.00% 4 1 75.00% 16 3 81.25% 6 2 66.67% | ||
|
||
// Test the case when there is __llvm_prf_names in the binary (those are names of uninstrumented functions). | ||
// RUN: %clang_profgen -o %t.normal -fcoverage-mapping -mllvm -enable-name-compression=false %s | ||
// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal | ||
// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw | ||
|
||
// RUN: %clang_profgen -o %t -g -mllvm --debug-info-correlate -fcoverage-mapping -mllvm -enable-name-compression=false %s | ||
// RUN: env LLVM_PROFILE_FILE=%t.proflite %run %t | ||
// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.proflite | ||
|
||
// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata) | ||
|
||
// RUN: llvm-cov export --format=lcov --instr-profile=%t.profdata %t --debug-info=%t.dSYM | FileCheck %s -check-prefix=NAME | ||
|
||
// Test debug info correlate with clang coverage (online merging). | ||
|
||
// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t.normal | ||
// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t.normal | ||
// RUN: llvm-profdata merge -o %t.normal.profdata %t-1.profraw %t-2.profraw | ||
|
||
// RUN: rm -rf %t.profdir && mkdir %t.profdir | ||
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t | ||
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t | ||
// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.profdir | ||
|
||
// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata) | ||
|
||
// RUN: llvm-cov export --format=lcov --instr-profile=%t.profdata %t --debug-info=%t.dSYM | FileCheck %s -check-prefix=NAME | ||
// NAME: _Z9used_funcv | ||
// NAME: main | ||
// NAME: _ZN1A11unused_funcEv | ||
|
||
struct A { | ||
void unused_func() {} | ||
}; | ||
void used_func() {} | ||
int main() { | ||
used_func(); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -349,8 +349,9 @@ static Error handleMaybeNoDataFoundError(Error E) { | |||||
|
||||||
Error CoverageMapping::loadFromFile( | ||||||
StringRef Filename, StringRef Arch, StringRef CompilationDir, | ||||||
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage, | ||||||
bool &DataFound, SmallVectorImpl<object::BuildID> *FoundBinaryIDs) { | ||||||
StringRef DebugInfoFilename, IndexedInstrProfReader &ProfileReader, | ||||||
CoverageMapping &Coverage, bool &DataFound, | ||||||
SmallVectorImpl<object::BuildID> *FoundBinaryIDs) { | ||||||
auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN( | ||||||
Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false); | ||||||
if (std::error_code EC = CovMappingBufOrErr.getError()) | ||||||
|
@@ -362,7 +363,7 @@ Error CoverageMapping::loadFromFile( | |||||
|
||||||
SmallVector<object::BuildIDRef> BinaryIDs; | ||||||
auto CoverageReadersOrErr = BinaryCoverageReader::create( | ||||||
CovMappingBufRef, Arch, Buffers, ProfSymTab, | ||||||
CovMappingBufRef, Arch, Buffers, DebugInfoFilename, ProfSymTab, | ||||||
CompilationDir, FoundBinaryIDs ? &BinaryIDs : nullptr); | ||||||
if (Error E = CoverageReadersOrErr.takeError()) { | ||||||
E = handleMaybeNoDataFoundError(std::move(E)); | ||||||
|
@@ -388,7 +389,8 @@ Error CoverageMapping::loadFromFile( | |||||
|
||||||
Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load( | ||||||
ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename, | ||||||
vfs::FileSystem &FS, ArrayRef<StringRef> Arches, StringRef CompilationDir, | ||||||
vfs::FileSystem &FS, StringRef DebugInfoFilename, | ||||||
ArrayRef<StringRef> Arches, StringRef CompilationDir, | ||||||
const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs) { | ||||||
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename, FS); | ||||||
if (Error E = ProfileReaderOrErr.takeError()) | ||||||
|
@@ -409,7 +411,8 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load( | |||||
for (const auto &File : llvm::enumerate(ObjectFilenames)) { | ||||||
if (Error E = | ||||||
loadFromFile(File.value(), GetArch(File.index()), CompilationDir, | ||||||
*ProfileReader, *Coverage, DataFound, &FoundBinaryIDs)) | ||||||
DebugInfoFilename, *ProfileReader, *Coverage, | ||||||
DataFound, &FoundBinaryIDs)) | ||||||
return std::move(E); | ||||||
} | ||||||
|
||||||
|
@@ -436,8 +439,9 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load( | |||||
if (PathOpt) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
llvm-project/llvm/lib/Object/BuildID.cpp Line 68 in 265d48a
If |
||||||
std::string Path = std::move(*PathOpt); | ||||||
StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef(); | ||||||
if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader, | ||||||
*Coverage, DataFound)) | ||||||
if (Error E = | ||||||
loadFromFile(Path, Arch, DebugInfoFilename, CompilationDir, | ||||||
*ProfileReader, *Coverage, DataFound)) | ||||||
return std::move(E); | ||||||
} else if (CheckBinaryIDs) { | ||||||
return createFileError( | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -444,8 +444,9 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() { | |||||
ObjectFilename); | ||||||
auto FS = vfs::getRealFileSystem(); | ||||||
auto CoverageOrErr = CoverageMapping::load( | ||||||
ObjectFilenames, PGOFilename, *FS, CoverageArches, | ||||||
ViewOpts.CompilationDirectory, BIDFetcher.get(), CheckBinaryIDs); | ||||||
ObjectFilenames, PGOFilename, *FS, ViewOpts.DebugInfoFilename, | ||||||
CoverageArches, ViewOpts.CompilationDirectory, BIDFetcher.get(), | ||||||
CheckBinaryIDs); | ||||||
if (Error E = CoverageOrErr.takeError()) { | ||||||
error("failed to load coverage: " + toString(std::move(E))); | ||||||
return nullptr; | ||||||
|
@@ -774,6 +775,11 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { | |||||
"check-binary-ids", cl::desc("Fail if an object couldn't be found for a " | ||||||
"binary ID in the profile")); | ||||||
|
||||||
cl::opt<std::string> DebugInfoFilename( | ||||||
"debug-info", cl::init(""), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
NIT: The default value is already the empty string |
||||||
cl::desc("Read and extract profile metadata from debug info and show " | ||||||
"the functions it found.")); | ||||||
|
||||||
auto commandLineParser = [&, this](int argc, const char **argv) -> int { | ||||||
cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); | ||||||
ViewOpts.Debug = DebugDump; | ||||||
|
@@ -929,6 +935,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { | |||||
ViewOpts.ExportSummaryOnly = SummaryOnly; | ||||||
ViewOpts.NumThreads = NumThreads; | ||||||
ViewOpts.CompilationDirectory = CompilationDirectory; | ||||||
ViewOpts.DebugInfoFilename = DebugInfoFilename; | ||||||
|
||||||
return 0; | ||||||
}; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the binary already has debug info, we could use for correlation instead of passing the redundant
--debug-info=%t
, right? Of course this wouldn't work for MachO or if the binary is stripped of debug info. Is it possible (or at least easy to only require--debug-info
if the provided binary doesn't already have it?