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