[llvm] r252801 - sancov tool in c++

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 18 15:34:54 PDT 2016


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/4c6614cf/attachment-0001.html>


More information about the llvm-commits mailing list