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

Kevin Frei via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 15 10:58:56 PST 2024


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

>From 1a35492390db608e10b32ee8d40de90488b173a9 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 1/6] 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 2b438a8b134613..1f4a9cf32dcb4d 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);

>From d501daddc4112c158b9eea476c61dbe1546e25e8 Mon Sep 17 00:00:00 2001
From: Kevin Frei <freik at meta.com>
Date: Wed, 14 Feb 2024 09:12:31 -0800
Subject: [PATCH 2/6] git clang-format continues to struggle :/

---
 llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 5c8b5ba48f4193..3d5b895992ab24 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -2042,8 +2042,8 @@ void DWARFVerifier::summarize() {
                               sys::fs::OF_Text | sys::fs::OF_None);
     if (EC) {
       error() << "error opening aggregate error json file '"
-              << DumpOpts.AggregateErrJsonFile << "' for writing: "
-              << EC.message() << '\n';
+              << DumpOpts.AggregateErrJsonFile
+              << "' for writing: " << EC.message() << '\n';
       return;
     }
     JsonStream << "{\"errors\":[\n";

>From 9e0ef0308cf328ce9852c2dac5c9c46663ffbf07 Mon Sep 17 00:00:00 2001
From: Kevin Frei <freik at meta.com>
Date: Wed, 14 Feb 2024 09:34:44 -0800
Subject: [PATCH 3/6] Fixing file format and actually outputting the file

---
 llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp   | 12 ++++++++----
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp |  7 +++++--
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 3d5b895992ab24..fc405a67d9607c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -2039,7 +2039,7 @@ void DWARFVerifier::summarize() {
   if (!DumpOpts.AggregateErrJsonFile.empty()) {
     std::error_code EC;
     raw_fd_ostream JsonStream(DumpOpts.AggregateErrJsonFile, EC,
-                              sys::fs::OF_Text | sys::fs::OF_None);
+                              sys::fs::OF_Text);
     if (EC) {
       error() << "error opening aggregate error json file '"
               << DumpOpts.AggregateErrJsonFile
@@ -2047,12 +2047,16 @@ void DWARFVerifier::summarize() {
       return;
     }
     JsonStream << "{\"errors\":[\n";
+    bool prev = false;
     ErrorCategory.EnumerateResults([&](StringRef category, unsigned count) {
-      JsonStream << "\"category\":\"";
+      if (prev)
+        JsonStream << ",\n";
+      JsonStream << "{\"category\":\"";
       llvm::printEscapedString(category, JsonStream);
-      JsonStream << "\",\"count\":" << count;
+      JsonStream << "\",\"count\":" << count << "}";
+      prev = true;
     });
-    JsonStream << "]}\n";
+    JsonStream << "\n]}\n";
   }
 }
 
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 1f4a9cf32dcb4d..f17f3f33a93909 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -297,7 +297,8 @@ static opt<ErrorDetailLevel> ErrorDetails(
     cat(DwarfDumpCategory));
 static opt<std::string> AggregationJsonFile(
     "aggregate-output-file", cl::init(""),
-    cl::desc("Output JSON-formatted error summary to the specified file."),
+    cl::desc("When using --verify, 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));
@@ -353,6 +354,7 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) {
                        ErrorDetails != NoDetailsOrSummary;
     DumpOpts.ShowAggregateErrors = ErrorDetails != OnlyDetailsNoSummary &&
                                    ErrorDetails != NoDetailsOnlySummary;
+    DumpOpts.AggregateErrJsonFile = AggregationJsonFile;
     return DumpOpts.noImplicitRecursion();
   }
   return DumpOpts;
@@ -841,7 +843,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";
+    WithColor::warning()
+        << "-aggregate-output-file has no affect without -verify";
 
   std::error_code EC;
   ToolOutputFile OutputFile(OutputFilename, EC, sys::fs::OF_TextWithCRLF);

>From c84d5b543a4ad2e4f120b1dc7f57f7ab5181079a Mon Sep 17 00:00:00 2001
From: Kevin Frei <freik at meta.com>
Date: Wed, 14 Feb 2024 16:18:25 -0800
Subject: [PATCH 4/6] Updated to use explicit JSON objects, renamed flag to
 --json-summary-file

---
 llvm/include/llvm/DebugInfo/DIContext.h      |  2 +-
 llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp   | 28 ++++++++++----------
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 11 ++++----
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index a6407389b9dcc0..b3e0def55cf174 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -206,7 +206,7 @@ struct DIDumpOptions {
   bool IsEH = false;
   bool DumpNonSkeleton = false;
   bool ShowAggregateErrors = false;
-  std::string AggregateErrJsonFile = "";
+  std::string JsonSummaryFile = "";
   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 fc405a67d9607c..1422e9cef97a7b 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -32,6 +32,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include <map>
@@ -2036,27 +2037,26 @@ void DWARFVerifier::summarize() {
       error() << s << " occurred " << count << " time(s).\n";
     });
   }
-  if (!DumpOpts.AggregateErrJsonFile.empty()) {
+  if (!DumpOpts.JsonSummaryFile.empty()) {
     std::error_code EC;
-    raw_fd_ostream JsonStream(DumpOpts.AggregateErrJsonFile, EC,
-                              sys::fs::OF_Text);
+    raw_fd_ostream JsonStream(DumpOpts.JsonSummaryFile, EC, sys::fs::OF_Text);
     if (EC) {
       error() << "error opening aggregate error json file '"
-              << DumpOpts.AggregateErrJsonFile
-              << "' for writing: " << EC.message() << '\n';
+              << DumpOpts.JsonSummaryFile << "' for writing: " << EC.message()
+              << '\n';
       return;
     }
-    JsonStream << "{\"errors\":[\n";
-    bool prev = false;
+
+    llvm::json::Object Categories;
     ErrorCategory.EnumerateResults([&](StringRef category, unsigned count) {
-      if (prev)
-        JsonStream << ",\n";
-      JsonStream << "{\"category\":\"";
-      llvm::printEscapedString(category, JsonStream);
-      JsonStream << "\",\"count\":" << count << "}";
-      prev = true;
+      llvm::json::Object Val;
+      Val.try_emplace("count", count);
+      Categories.try_emplace(category, std::move(Val));
     });
-    JsonStream << "\n]}\n";
+    llvm::json::Object RootNode;
+    RootNode.try_emplace("error-categories", std::move(Categories));
+
+    JsonStream << llvm::json::Value(std::move(RootNode));
   }
 }
 
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index f17f3f33a93909..0c72869919270c 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -295,8 +295,8 @@ 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(""),
+static opt<std::string> JsonSummaryFile(
+    "json-summary-file", cl::init(""),
     cl::desc("When using --verify, output JSON-formatted error summary to the "
              "specified file."),
     cl::value_desc("filename.json"), cat(DwarfDumpCategory));
@@ -354,7 +354,7 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) {
                        ErrorDetails != NoDetailsOrSummary;
     DumpOpts.ShowAggregateErrors = ErrorDetails != OnlyDetailsNoSummary &&
                                    ErrorDetails != NoDetailsOnlySummary;
-    DumpOpts.AggregateErrJsonFile = AggregationJsonFile;
+    DumpOpts.JsonSummaryFile = JsonSummaryFile;
     return DumpOpts.noImplicitRecursion();
   }
   return DumpOpts;
@@ -842,9 +842,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()
-        << "-aggregate-output-file has no affect without -verify";
+  if (!Verify && !JsonSummaryFile.empty())
+    WithColor::warning() << "-json-summary-file has no affect without -verify";
 
   std::error_code EC;
   ToolOutputFile OutputFile(OutputFilename, EC, sys::fs::OF_TextWithCRLF);

>From 23d546ddef16523d3c36310a4f3b37e14f4905d5 Mon Sep 17 00:00:00 2001
From: Kevin Frei <freik at meta.com>
Date: Thu, 15 Feb 2024 09:08:45 -0800
Subject: [PATCH 5/6] Removed a header leftover from earlier draft

---
 llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 1422e9cef97a7b..e82926f6fc95fc 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -9,7 +9,6 @@
 #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"

>From 7c9c9d3830f483359596f8e5e219c98cefcd031d Mon Sep 17 00:00:00 2001
From: Kevin Frei <freik at meta.com>
Date: Thu, 15 Feb 2024 10:58:40 -0800
Subject: [PATCH 6/6] Imply --verify instea of warn, better error message

---
 llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp   | 2 +-
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index e82926f6fc95fc..0f27395faf017a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -2040,7 +2040,7 @@ void DWARFVerifier::summarize() {
     std::error_code EC;
     raw_fd_ostream JsonStream(DumpOpts.JsonSummaryFile, EC, sys::fs::OF_Text);
     if (EC) {
-      error() << "error opening aggregate error json file '"
+      error() << "unable to open json summary file '"
               << DumpOpts.JsonSummaryFile << "' for writing: " << EC.message()
               << '\n';
       return;
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 0c72869919270c..ca49f49828cbc2 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -840,10 +840,10 @@ int main(int argc, char **argv) {
                           "-verbose is currently not supported";
     return 1;
   }
-  if (!Verify && ErrorDetails != Unspecified)
-    WithColor::warning() << "-error-detail has no affect without -verify";
-  if (!Verify && !JsonSummaryFile.empty())
-    WithColor::warning() << "-json-summary-file has no affect without -verify";
+  // -error-detail and -json-summary-file both imply -verify
+  if (ErrorDetails != Unspecified || !JsonSummaryFile.empty()) {
+    Verify = true;
+  }
 
   std::error_code EC;
   ToolOutputFile OutputFile(OutputFilename, EC, sys::fs::OF_TextWithCRLF);



More information about the llvm-commits mailing list