xray-fdr-dump.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Implements the FDR trace dumping tool, using the libraries for handling FDR
  10. // 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. using namespace llvm;
  25. using namespace xray;
  26. static cl::SubCommand Dump("fdr-dump", "FDR Trace Dump");
  27. static cl::opt<std::string> DumpInput(cl::Positional,
  28. cl::desc("<xray fdr mode log>"),
  29. cl::Required, cl::sub(Dump));
  30. static cl::opt<bool> DumpVerify("verify",
  31. cl::desc("verify structure of the log"),
  32. cl::init(false), cl::sub(Dump));
  33. static CommandRegistration Unused(&Dump, []() -> Error {
  34. // Open the file provided.
  35. auto FDOrErr = sys::fs::openNativeFileForRead(DumpInput);
  36. if (!FDOrErr)
  37. return FDOrErr.takeError();
  38. uint64_t FileSize;
  39. if (auto EC = sys::fs::file_size(DumpInput, FileSize))
  40. return createStringError(EC, "Failed to get file size for '%s'.",
  41. DumpInput.c_str());
  42. std::error_code EC;
  43. sys::fs::mapped_file_region MappedFile(
  44. *FDOrErr, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,
  45. EC);
  46. sys::fs::closeFile(*FDOrErr);
  47. DataExtractor DE(StringRef(MappedFile.data(), MappedFile.size()), true, 8);
  48. uint64_t OffsetPtr = 0;
  49. auto FileHeaderOrError = readBinaryFormatHeader(DE, OffsetPtr);
  50. if (!FileHeaderOrError)
  51. return FileHeaderOrError.takeError();
  52. auto &H = FileHeaderOrError.get();
  53. FileBasedRecordProducer P(H, DE, OffsetPtr);
  54. RecordPrinter RP(outs(), "\n");
  55. if (!DumpVerify) {
  56. PipelineConsumer C({&RP});
  57. while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
  58. auto R = P.produce();
  59. if (!R)
  60. return R.takeError();
  61. if (auto E = C.consume(std::move(R.get())))
  62. return E;
  63. }
  64. return Error::success();
  65. }
  66. BlockPrinter BP(outs(), RP);
  67. std::vector<std::unique_ptr<Record>> Records;
  68. LogBuilderConsumer C(Records);
  69. while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
  70. auto R = P.produce();
  71. if (!R) {
  72. // Print records we've found so far.
  73. for (auto &Ptr : Records)
  74. if (auto E = Ptr->apply(RP))
  75. return joinErrors(std::move(E), R.takeError());
  76. return R.takeError();
  77. }
  78. if (auto E = C.consume(std::move(R.get())))
  79. return E;
  80. }
  81. // Once we have a trace, we then index the blocks.
  82. BlockIndexer::Index Index;
  83. BlockIndexer BI(Index);
  84. for (auto &Ptr : Records)
  85. if (auto E = Ptr->apply(BI))
  86. return E;
  87. if (auto E = BI.flush())
  88. return E;
  89. // Then we validate while printing each block.
  90. BlockVerifier BV;
  91. for (auto ProcessThreadBlocks : Index) {
  92. auto &Blocks = ProcessThreadBlocks.second;
  93. for (auto &B : Blocks) {
  94. for (auto *R : B.Records) {
  95. if (auto E = R->apply(BV))
  96. return E;
  97. if (auto E = R->apply(BP))
  98. return E;
  99. }
  100. BV.reset();
  101. BP.reset();
  102. }
  103. }
  104. outs().flush();
  105. return Error::success();
  106. });