[dsymutil] Prevent interleaved errors and warnings
authorJonas Devlieghere <jonas@devlieghere.com>
Wed, 5 Apr 2023 04:49:55 +0000 (21:49 -0700)
committerJonas Devlieghere <jonas@devlieghere.com>
Wed, 5 Apr 2023 04:57:42 +0000 (21:57 -0700)
Use a mutex to protect the printing of errors and warnings and prevents
interleaving. There are two sources of parallelism in dsymutil that
could result in interleaved output: errors from different architectures
being processed in parallel and errors from the analyze and clone steps
which execute in lockstep. This patch addresses both by using a unique
mutex across all error reporting.

llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
llvm/tools/dsymutil/DwarfLinkerForBinary.h
llvm/tools/dsymutil/dsymutil.cpp

index 0db7b6e..6c756c0 100644 (file)
@@ -121,13 +121,14 @@ static void dumpDIE(const DWARFDie *DIE, bool Verbose) {
 /// specific \p DIE related to the warning.
 void DwarfLinkerForBinary::reportWarning(Twine Warning, Twine Context,
                                          const DWARFDie *DIE) const {
-
+  std::lock_guard<std::mutex> Guard(ErrorHandlerMutex);
   warn(Warning, Context);
   dumpDIE(DIE, Options.Verbose);
 }
 
 void DwarfLinkerForBinary::reportError(Twine Error, Twine Context,
                                        const DWARFDie *DIE) const {
+  std::lock_guard<std::mutex> Guard(ErrorHandlerMutex);
   error(Error, Context);
   dumpDIE(DIE, Options.Verbose);
 }
index 4eb93ee..b38ff62 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/Remarks/RemarkFormat.h"
 #include "llvm/Remarks/RemarkLinker.h"
+#include <mutex>
 
 namespace llvm {
 namespace dsymutil {
@@ -35,8 +36,9 @@ namespace dsymutil {
 class DwarfLinkerForBinary {
 public:
   DwarfLinkerForBinary(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
-                       LinkOptions Options)
-      : OutFile(OutFile), BinHolder(BinHolder), Options(std::move(Options)) {}
+                       LinkOptions Options, std::mutex &ErrorHandlerMutex)
+      : OutFile(OutFile), BinHolder(BinHolder), Options(std::move(Options)),
+        ErrorHandlerMutex(ErrorHandlerMutex) {}
 
   /// Link the contents of the DebugMap.
   bool link(const DebugMap &);
@@ -224,6 +226,8 @@ private:
   raw_fd_ostream &OutFile;
   BinaryHolder &BinHolder;
   LinkOptions Options;
+  std::mutex &ErrorHandlerMutex;
+
   std::unique_ptr<DwarfStreamer> Streamer;
   std::vector<std::unique_ptr<DWARFFile>> ObjectsForLinking;
   std::vector<std::unique_ptr<DWARFContext>> ContextForLinking;
index f2dbba2..f504ac0 100644 (file)
@@ -717,6 +717,8 @@ int main(int argc, char **argv) {
     std::atomic_char AllOK(1);
     SmallVector<MachOUtils::ArchAndFile, 4> TempFiles;
 
+    std::mutex ErrorHandlerMutex;
+
     const bool Crashed = !CRC.RunSafely([&]() {
       for (auto &Map : *DebugMapPtrsOrErr) {
         if (Options.LinkOpts.Verbose || Options.DumpDebugMap)
@@ -767,7 +769,8 @@ int main(int argc, char **argv) {
 
         auto LinkLambda = [&,
                            OutputFile](std::shared_ptr<raw_fd_ostream> Stream) {
-          DwarfLinkerForBinary Linker(*Stream, BinHolder, Options.LinkOpts);
+          DwarfLinkerForBinary Linker(*Stream, BinHolder, Options.LinkOpts,
+                                      ErrorHandlerMutex);
           AllOK.fetch_and(Linker.link(*Map));
           Stream->flush();
           if (flagIsSet(Options.Verify, DWARFVerify::Output) ||