[llvm] r252801 - sancov tool in c++
Mike Aizatsky via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 18 15:42:56 PDT 2016
It is actually formatted with clang-format. There are couple of lines wrong
(not sure how they crept in), but for 99% it is correctly formatted now.
Clang-tidy also finds one issue (include sort order).
I'll submit these nits right now..
On Fri, Mar 18, 2016 at 3:34 PM Kostya Serebryany <kcc at google.com> wrote:
> Yep, Mike, please do that.
>
> On Fri, Mar 18, 2016 at 3:30 PM, Chandler Carruth <chandlerc at google.com>
> wrote:
>
>> Hey Mike and Kostya,
>>
>> This entire pass, and all the code that has been added on top of it, is
>> not *at all* following LLVM's coding conventions. It doesn't look like it
>> has been formatted with clang-format, and the formatting it does have isn't
>> the LLVM convention at all.
>>
>> As a start, please run clang-format over this following the LLVM
>> conventions. Also, you might try some of the LLVM clang-tidy checks to pull
>> in more of the coding conventions.
>>
>>
>> On Wed, Nov 11, 2015 at 10:00 PM Mike Aizatsky via llvm-commits <
>> llvm-commits at lists.llvm.org> wrote:
>>
>>> Author: aizatsky
>>> Date: Wed Nov 11 14:58:20 2015
>>> New Revision: 252801
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=252801&view=rev
>>> Log:
>>> sancov tool in c++
>>>
>>> First batch of sancov.py rewrite in c++.
>>> Supports "-print" and "-coveredfns" commands.
>>>
>>> Followup to http://reviews.llvm.org/D14356 in a better location.
>>>
>>> Differential Revision: http://reviews.llvm.org/D14579
>>>
>>> Added:
>>> llvm/trunk/tools/sancov/
>>> llvm/trunk/tools/sancov/CMakeLists.txt
>>> llvm/trunk/tools/sancov/Makefile
>>> llvm/trunk/tools/sancov/sancov.cc
>>>
>>> Added: llvm/trunk/tools/sancov/CMakeLists.txt
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/sancov/CMakeLists.txt?rev=252801&view=auto
>>>
>>> ==============================================================================
>>> --- llvm/trunk/tools/sancov/CMakeLists.txt (added)
>>> +++ llvm/trunk/tools/sancov/CMakeLists.txt Wed Nov 11 14:58:20 2015
>>> @@ -0,0 +1,11 @@
>>> +set(LLVM_LINK_COMPONENTS
>>> + DebugInfoDWARF
>>> + DebugInfoPDB
>>> + Object
>>> + Support
>>> + Symbolize
>>> + )
>>> +
>>> +add_llvm_tool(sancov
>>> + sancov.cc
>>> + )
>>>
>>> Added: llvm/trunk/tools/sancov/Makefile
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/sancov/Makefile?rev=252801&view=auto
>>>
>>> ==============================================================================
>>> --- llvm/trunk/tools/sancov/Makefile (added)
>>> +++ llvm/trunk/tools/sancov/Makefile Wed Nov 11 14:58:20 2015
>>> @@ -0,0 +1,17 @@
>>> +##===- tools/sancov/Makefile ----------------------*- Makefile -*-===##
>>> +#
>>> +# The LLVM Compiler Infrastructure
>>> +#
>>> +# This file is distributed under the University of Illinois Open Source
>>> +# License. See LICENSE.TXT for details.
>>> +#
>>>
>>> +##===----------------------------------------------------------------------===##
>>> +
>>> +LEVEL := ../..
>>> +TOOLNAME := sancov
>>> +LINK_COMPONENTS := DebugInfoDWARF DebugInfoPDB Object Support Symbolize
>>> +
>>> +# This tool has no plugins, optimize startup time.
>>> +TOOL_NO_EXPORTS := 1
>>> +
>>> +include $(LEVEL)/Makefile.common
>>>
>>> Added: llvm/trunk/tools/sancov/sancov.cc
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/sancov/sancov.cc?rev=252801&view=auto
>>>
>>> ==============================================================================
>>> --- llvm/trunk/tools/sancov/sancov.cc (added)
>>> +++ llvm/trunk/tools/sancov/sancov.cc Wed Nov 11 14:58:20 2015
>>> @@ -0,0 +1,264 @@
>>> +//===-- sancov.cc --------------------------------------------===//
>>> +//
>>> +// The LLVM Compiler Infrastructure
>>> +//
>>> +// This file is distributed under the University of Illinois Open Source
>>> +// License. See LICENSE.TXT for details.
>>> +//
>>>
>>> +//===----------------------------------------------------------------------===//
>>> +//
>>> +// This file is a command-line tool for reading and analyzing sanitizer
>>> +// coverage.
>>>
>>> +//===----------------------------------------------------------------------===//
>>> +#include "llvm/ADT/STLExtras.h"
>>> +#include "llvm/DebugInfo/Symbolize/Symbolize.h"
>>> +#include "llvm/Support/CommandLine.h"
>>> +#include "llvm/Support/Errc.h"
>>> +#include "llvm/Support/ErrorOr.h"
>>> +#include "llvm/Support/FileSystem.h"
>>> +#include "llvm/Support/LineIterator.h"
>>> +#include "llvm/Support/ManagedStatic.h"
>>> +#include "llvm/Support/MemoryBuffer.h"
>>> +#include "llvm/Support/Path.h"
>>> +#include "llvm/Support/PrettyStackTrace.h"
>>> +#include "llvm/Support/Signals.h"
>>> +#include "llvm/Support/ToolOutputFile.h"
>>> +#include "llvm/Support/raw_ostream.h"
>>> +
>>> +#include <set>
>>> +#include <stdio.h>
>>> +#include <vector>
>>> +
>>> +using namespace llvm;
>>> +
>>> +namespace {
>>> +
>>> +// --------- COMMAND LINE FLAGS ---------
>>> +
>>> +enum ActionType { PrintAction, CoveredFunctionsAction };
>>> +
>>> +cl::opt<ActionType> Action(
>>> + cl::desc("Action (required)"), cl::Required,
>>> + cl::values(clEnumValN(PrintAction, "print", "Print coverage
>>> addresses"),
>>> + clEnumValN(CoveredFunctionsAction, "covered_functions",
>>> + "Print all covered funcions."),
>>> + clEnumValEnd));
>>> +
>>> +static cl::list<std::string> ClInputFiles(cl::Positional, cl::OneOrMore,
>>> + cl::desc("<filenames...>"));
>>> +
>>> +static cl::opt<std::string>
>>> + ClBinaryName("obj", cl::Required,
>>> + cl::desc("Path to object file to be symbolized"));
>>> +
>>> +static cl::opt<bool>
>>> + ClDemangle("demangle", cl::init(true),
>>> + cl::desc("Print demangled function name."));
>>> +
>>> +// --------- FORMAT SPECIFICATION ---------
>>> +
>>> +struct FileHeader {
>>> + uint32_t Bitness;
>>> + uint32_t Magic;
>>> +};
>>> +
>>> +static const uint32_t BinCoverageMagic = 0xC0BFFFFF;
>>> +static const uint32_t Bitness32 = 0xFFFFFF32;
>>> +static const uint32_t Bitness64 = 0xFFFFFF64;
>>> +
>>> +// ---------
>>> +
>>> +template <typename T> static void FailIfError(const ErrorOr<T> &E) {
>>> + if (E)
>>> + return;
>>> +
>>> + auto Error = E.getError();
>>> + errs() << "Error: " << Error.message() << "(" << Error.value() <<
>>> ")\n";
>>> + exit(-2);
>>> +}
>>> +
>>> +template <typename T>
>>> +static void readInts(const char *Start, const char *End,
>>> + std::vector<uint64_t> *V) {
>>> + const T *S = reinterpret_cast<const T *>(Start);
>>> + const T *E = reinterpret_cast<const T *>(End);
>>> + V->reserve(E - S);
>>> + std::copy(S, E, std::back_inserter(*V));
>>> +}
>>> +
>>> +static std::string CommonPrefix(std::string A, std::string B) {
>>> + if (A.size() > B.size())
>>> + return std::string(B.begin(),
>>> + std::mismatch(B.begin(), B.end(),
>>> A.begin()).first);
>>> + else
>>> + return std::string(A.begin(),
>>> + std::mismatch(A.begin(), A.end(),
>>> B.begin()).first);
>>> +}
>>> +
>>> +class CoverageData {
>>> + public:
>>> + // Read single file coverage data.
>>> + static ErrorOr<std::unique_ptr<CoverageData>> read(std::string
>>> FileName) {
>>> + ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
>>> + MemoryBuffer::getFile(FileName);
>>> + if (!BufOrErr)
>>> + return BufOrErr.getError();
>>> + std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
>>> + if (Buf->getBufferSize() < 8) {
>>> + errs() << "File too small (<8): " << Buf->getBufferSize();
>>> + return make_error_code(errc::illegal_byte_sequence);
>>> + }
>>> + const FileHeader *Header =
>>> + reinterpret_cast<const FileHeader *>(Buf->getBufferStart());
>>> +
>>> + if (Header->Magic != BinCoverageMagic) {
>>> + errs() << "Wrong magic: " << Header->Magic;
>>> + return make_error_code(errc::illegal_byte_sequence);
>>> + }
>>> +
>>> + auto Addrs = make_unique<std::vector<uint64_t>>();
>>> +
>>> + switch (Header->Bitness) {
>>> + case Bitness64:
>>> + readInts<uint64_t>(Buf->getBufferStart() + 8, Buf->getBufferEnd(),
>>> + Addrs.get());
>>> + break;
>>> + case Bitness32:
>>> + readInts<uint32_t>(Buf->getBufferStart() + 8, Buf->getBufferEnd(),
>>> + Addrs.get());
>>> + break;
>>> + default:
>>> + errs() << "Unsupported bitness: " << Header->Bitness;
>>> + return make_error_code(errc::illegal_byte_sequence);
>>> + }
>>> +
>>> + return std::unique_ptr<CoverageData>(new
>>> CoverageData(std::move(Addrs)));
>>> + }
>>> +
>>> + // Merge multiple coverage data together.
>>> + static std::unique_ptr<CoverageData>
>>> + merge(const std::vector<std::unique_ptr<CoverageData>> &Covs) {
>>> + std::set<uint64_t> Addrs;
>>> +
>>> + for (const auto &Cov : Covs)
>>> + Addrs.insert(Cov->Addrs->begin(), Cov->Addrs->end());
>>> +
>>> + auto AddrsVector = make_unique<std::vector<uint64_t>>(
>>> + Addrs.begin(), Addrs.end());
>>> + return std::unique_ptr<CoverageData>(
>>> + new CoverageData(std::move(AddrsVector)));
>>> + }
>>> +
>>> + // Read list of files and merges their coverage info.
>>> + static ErrorOr<std::unique_ptr<CoverageData>>
>>> + readAndMerge(const std::vector<std::string> &FileNames) {
>>> + std::vector<std::unique_ptr<CoverageData>> Covs;
>>> + for (const auto &FileName : FileNames) {
>>> + auto Cov = read(FileName);
>>> + if (!Cov)
>>> + return Cov.getError();
>>> + Covs.push_back(std::move(Cov.get()));
>>> + }
>>> + return merge(Covs);
>>> + }
>>> +
>>> + // Print coverage addresses.
>>> + void printAddrs(raw_ostream &out) {
>>> + for (auto Addr : *Addrs) {
>>> + out << "0x";
>>> + out.write_hex(Addr);
>>> + out << "\n";
>>> + }
>>> + }
>>> +
>>> + // Print list of covered functions.
>>> + // Line format: <file_name>:<line> <function_name>
>>> + void printCoveredFunctions(raw_ostream &out) {
>>> + if (Addrs->empty())
>>> + return;
>>> + symbolize::LLVMSymbolizer::Options SymbolizerOptions;
>>> + SymbolizerOptions.Demangle = ClDemangle;
>>> + symbolize::LLVMSymbolizer Symbolizer;
>>> +
>>> + struct FileLoc {
>>> + std::string FileName;
>>> + uint32_t Line;
>>> + bool operator<(const FileLoc &Rhs) const {
>>> + return std::tie(FileName, Line) < std::tie(Rhs.FileName,
>>> Rhs.Line);
>>> + }
>>> + };
>>> +
>>> + // FileLoc -> FunctionName
>>> + std::map<FileLoc, std::string> Fns;
>>> +
>>> + // Fill in Fns map.
>>> + for (auto Addr : *Addrs) {
>>> + auto InliningInfo = Symbolizer.symbolizeInlinedCode(ClBinaryName,
>>> Addr);
>>> + FailIfError(InliningInfo);
>>> + for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) {
>>> + auto FrameInfo = InliningInfo->getFrame(i);
>>> + SmallString<256> FileName(FrameInfo.FileName);
>>> + sys::path::remove_dots(FileName, /* remove_dot_dot */ true);
>>> + FileLoc Loc = { FileName.str(), FrameInfo.Line };
>>> + Fns[Loc] = FrameInfo.FunctionName;
>>> + }
>>> + }
>>> +
>>> + // Compute file names common prefix.
>>> + std::string FilePrefix = Fns.begin()->first.FileName;
>>> + for (const auto &P : Fns)
>>> + FilePrefix = CommonPrefix(FilePrefix, P.first.FileName);
>>> +
>>> + // Print first function occurence in a file.
>>> + {
>>> + std::string LastFileName;
>>> + std::set<std::string> ProcessedFunctions;
>>> +
>>> + for (const auto &P : Fns) {
>>> + std::string FileName = P.first.FileName;
>>> + std::string FunctionName = P.second;
>>> + uint32_t Line = P.first.Line;
>>> +
>>> + if (LastFileName != FileName)
>>> + ProcessedFunctions.clear();
>>> + LastFileName = FileName;
>>> +
>>> + if (!ProcessedFunctions.insert(FunctionName).second)
>>> + continue;
>>> +
>>> + out << FileName.substr(FilePrefix.size()) << ":" << Line << " "
>>> + << FunctionName << "\n";
>>> + }
>>> + }
>>> + }
>>> +
>>> + private:
>>> + explicit CoverageData(std::unique_ptr<std::vector<uint64_t>> Addrs)
>>> + : Addrs(std::move(Addrs)) {}
>>> +
>>> + std::unique_ptr<std::vector<uint64_t>> Addrs;
>>> +};
>>> +} // namespace
>>> +
>>> +int main(int argc, char **argv) {
>>> + // Print stack trace if we signal out.
>>> + sys::PrintStackTraceOnErrorSignal();
>>> + PrettyStackTraceProgram X(argc, argv);
>>> + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
>>> +
>>> + cl::ParseCommandLineOptions(argc, argv, "Sanitizer Coverage
>>> Processing Tool");
>>> +
>>> + auto CovData = CoverageData::readAndMerge(ClInputFiles);
>>> + FailIfError(CovData);
>>> +
>>> + switch (Action) {
>>> + case PrintAction: {
>>> + CovData.get()->printAddrs(outs());
>>> + return 0;
>>> + }
>>> + case CoveredFunctionsAction: {
>>> + CovData.get()->printCoveredFunctions(outs());
>>> + return 0;
>>> + }
>>> + }
>>> +}
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160318/49e371e0/attachment.html>
More information about the llvm-commits
mailing list