[llvm] llvm-dwarfdump --verify aggregated output to JSON file (PR #81762)

Kevin Frei via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 14 09:08:16 PST 2024


https://github.com/kevinfrei created https://github.com/llvm/llvm-project/pull/81762

In order to make tooling around dwarf health easier, I've added an `--aggregate-output-file` file to dwarfdump --verify that will spit out error summary data with counts to a JSON file.

I've added the same capability to llvm-gsymutil in a different PR: [todo: add link when PR is up]


>From c61e34e8458e07c7ab91ef5224a8e3d87ea2baa7 Mon Sep 17 00:00:00 2001
From: Kevin Frei <freik at meta.com>
Date: Wed, 14 Feb 2024 09:04:41 -0800
Subject: [PATCH] dwarfdump --verify aggregated output to JSON file

---
 llvm/include/llvm/DebugInfo/DIContext.h      |  1 +
 llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp   | 24 +++++++++++++++++++-
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp |  6 +++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index 288ddf77bdfda7..a6407389b9dcc0 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -206,6 +206,7 @@ struct DIDumpOptions {
   bool IsEH = false;
   bool DumpNonSkeleton = false;
   bool ShowAggregateErrors = false;
+  std::string AggregateErrJsonFile = "";
   std::function<llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)>
       GetNameForDWARFReg;
 
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 20ef59e7b4422e..5c8b5ba48f4193 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -9,6 +9,7 @@
 #include "llvm/ADT/IntervalMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
 #include "llvm/DebugInfo/DWARF/DWARFAttribute.h"
@@ -29,6 +30,7 @@
 #include "llvm/Support/DJB.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
@@ -2026,12 +2028,32 @@ void OutputCategoryAggregator::EnumerateResults(
 }
 
 void DWARFVerifier::summarize() {
-  if (ErrorCategory.GetNumCategories() && DumpOpts.ShowAggregateErrors) {
+  if (!ErrorCategory.GetNumCategories())
+    return;
+  if (DumpOpts.ShowAggregateErrors) {
     error() << "Aggregated error counts:\n";
     ErrorCategory.EnumerateResults([&](StringRef s, unsigned count) {
       error() << s << " occurred " << count << " time(s).\n";
     });
   }
+  if (!DumpOpts.AggregateErrJsonFile.empty()) {
+    std::error_code EC;
+    raw_fd_ostream JsonStream(DumpOpts.AggregateErrJsonFile, EC,
+                              sys::fs::OF_Text | sys::fs::OF_None);
+    if (EC) {
+      error() << "error opening aggregate error json file '"
+              << DumpOpts.AggregateErrJsonFile << "' for writing: "
+              << EC.message() << '\n';
+      return;
+    }
+    JsonStream << "{\"errors\":[\n";
+    ErrorCategory.EnumerateResults([&](StringRef category, unsigned count) {
+      JsonStream << "\"category\":\"";
+      llvm::printEscapedString(category, JsonStream);
+      JsonStream << "\",\"count\":" << count;
+    });
+    JsonStream << "]}\n";
+  }
 }
 
 raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 8cdd84bcc867cb..40b1b5db5fe3cd 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -295,6 +295,10 @@ static opt<ErrorDetailLevel> ErrorDetails(
            clEnumValN(BothDetailsAndSummary, "full",
                       "Display each error as well as a summary. [default]")),
     cat(DwarfDumpCategory));
+static opt<std::string> AggregationJsonFile(
+    "aggregate-output-file", cl::init(""),
+    cl::desc("Output JSON-formatted error summary to the specified file."),
+    cl::value_desc("filename.json"), cat(DwarfDumpCategory));
 static opt<bool> Quiet("quiet", desc("Use with -verify to not emit to STDOUT."),
                        cat(DwarfDumpCategory));
 static opt<bool> DumpUUID("uuid", desc("Show the UUID for each architecture."),
@@ -836,6 +840,8 @@ int main(int argc, char **argv) {
   }
   if (!Verify && ErrorDetails != Unspecified)
     WithColor::warning() << "-error-detail has no affect without -verify";
+  if (!Verify && !AggregationJsonFile.empty())
+    WithColor::warning() << "-aggregation-json has no affect without -verify";
 
   std::error_code EC;
   ToolOutputFile OutputFile(OutputFilename, EC, sys::fs::OF_TextWithCRLF);



More information about the llvm-commits mailing list