brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 017ff03 Raw
120 lines · cpp
1//===- xray-fdr-dump.cpp: XRay FDR Trace Dump Tool ------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Implements the FDR trace dumping tool, using the libraries for handling FDR10// mode traces specifically.11//12//===----------------------------------------------------------------------===//13#include "xray-registry.h"14#include "llvm/Support/CommandLine.h"15#include "llvm/Support/FileSystem.h"16#include "llvm/XRay/BlockIndexer.h"17#include "llvm/XRay/BlockPrinter.h"18#include "llvm/XRay/BlockVerifier.h"19#include "llvm/XRay/FDRRecordConsumer.h"20#include "llvm/XRay/FDRRecordProducer.h"21#include "llvm/XRay/FDRRecords.h"22#include "llvm/XRay/FileHeaderReader.h"23#include "llvm/XRay/RecordPrinter.h"24 25using namespace llvm;26using namespace xray;27 28static cl::SubCommand Dump("fdr-dump", "FDR Trace Dump");29static cl::opt<std::string> DumpInput(cl::Positional,30                                      cl::desc("<xray fdr mode log>"),31                                      cl::Required, cl::sub(Dump));32static cl::opt<bool> DumpVerify("verify",33                                cl::desc("verify structure of the log"),34                                cl::init(false), cl::sub(Dump));35 36static CommandRegistration Unused(&Dump, []() -> Error {37  // Open the file provided.38  auto FDOrErr = sys::fs::openNativeFileForRead(DumpInput);39  if (!FDOrErr)40    return FDOrErr.takeError();41 42  uint64_t FileSize;43  if (auto EC = sys::fs::file_size(DumpInput, FileSize))44    return createStringError(EC, "Failed to get file size for '%s'.",45                             DumpInput.c_str());46 47  std::error_code EC;48  sys::fs::mapped_file_region MappedFile(49      *FDOrErr, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,50      EC);51  sys::fs::closeFile(*FDOrErr);52 53  DataExtractor DE(StringRef(MappedFile.data(), MappedFile.size()), true, 8);54  uint64_t OffsetPtr = 0;55 56  auto FileHeaderOrError = readBinaryFormatHeader(DE, OffsetPtr);57  if (!FileHeaderOrError)58    return FileHeaderOrError.takeError();59  auto &H = FileHeaderOrError.get();60 61  FileBasedRecordProducer P(H, DE, OffsetPtr);62 63  RecordPrinter RP(outs(), "\n");64  if (!DumpVerify) {65    PipelineConsumer C({&RP});66    while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {67      auto R = P.produce();68      if (!R)69        return R.takeError();70      if (auto E = C.consume(std::move(R.get())))71        return E;72    }73    return Error::success();74  }75 76  BlockPrinter BP(outs(), RP);77  std::vector<std::unique_ptr<Record>> Records;78  LogBuilderConsumer C(Records);79  while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {80    auto R = P.produce();81    if (!R) {82      // Print records we've found so far.83      for (auto &Ptr : Records)84        if (auto E = Ptr->apply(RP))85          return joinErrors(std::move(E), R.takeError());86      return R.takeError();87    }88    if (auto E = C.consume(std::move(R.get())))89      return E;90  }91 92  // Once we have a trace, we then index the blocks.93  BlockIndexer::Index Index;94  BlockIndexer BI(Index);95  for (auto &Ptr : Records)96    if (auto E = Ptr->apply(BI))97      return E;98 99  if (auto E = BI.flush())100    return E;101 102  // Then we validate while printing each block.103  BlockVerifier BV;104  for (const auto &ProcessThreadBlocks : Index) {105    auto &Blocks = ProcessThreadBlocks.second;106    for (auto &B : Blocks) {107      for (auto *R : B.Records) {108        if (auto E = R->apply(BV))109          return E;110        if (auto E = R->apply(BP))111          return E;112      }113      BV.reset();114      BP.reset();115    }116  }117  outs().flush();118  return Error::success();119});120