[PATCH] D102892: [WIP][lld] Implement crash reproducer for ELF

Petr Hosek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 3 16:27:59 PDT 2021


phosek added a comment.

I left some comments, but after reading the change, I'd suggest a slightly different structure: I think it'd be nice if we could avoid duplicating the logic between the `--reproduce` and `--reproduce-on-crash` case.

What I'm thinking is we could introduce a new function such as `LinkerDriver::generateReproducer`. This function would be responsible for generating the reproducer in both cases: we would always collect reproducer files and then call `generateReproducer` rather than writing the reproducer on demand as is the case now. That also has the advantage of not needing the `std::unique_ptr<llvm::TarWriter> tar` global since the `TarWriter` can be only created inside `generateReproducer` as needed.

I think we should also consider moving the `llvm::CrashRecoveryContext` setup from `safeLldMain` into each driver, for example `elf::link`, that's going to lead to some duplication, but the recovery context setup is fairly minimal and we could avoid having to repeat the flavor during normal execution and recovery and `lldMain` could remain completely agnostic to whether each driver supports crash recovery or not, that detail is fully encapsulated inside the `*::link` function.



================
Comment at: lld/ELF/Driver.cpp:503-504
+
+  if (!path)
+    return;
+  Expected<std::unique_ptr<TarWriter>> errOrWriter =
----------------
Do this check before instantiating the option parser which is a potentially expensive operation.


================
Comment at: lld/ELF/Driver.cpp:507
+      TarWriter::create(path, path::stem(path));
+  if (errOrWriter) {
+    tar = std::move(*errOrWriter);
----------------
I'd do the early return on error. It might be also useful to signal the error back to the caller to avoid printing the output in the case of an error.


================
Comment at: lld/tools/lld/lld.cpp:184
+      bool hasReproduceOnCrash = false;
+      for (const char *arg : args) {
+        std::string arg_str(arg);
----------------
We might consider moving this logic into the ELF implementation so we can use `ELFOptTable` for option parsing.


================
Comment at: lld/tools/lld/lld.cpp:197
+        std::error_code EC =
+            llvm::sys::fs::createTemporaryFile("lld", "tar", reproducerPath);
+        if (EC) {
----------------
I think it'd be also useful to allow explicitly setting the directory where to write the reproducer akin to Clang's `-fcrash-diagnostics-dir`. You could still use `llvm::sys::fs::createTemporaryFile` to create the file and then just move it to the final location at the end which is what Clang does.

You could either introduce another flag, for example `--reproduce-dir` or allow `--reproduce-on-crash` to take an optional value which would be the directory, either option is fine with me.


================
Comment at: lld/tools/lld/lld.cpp:202
+        }
+        stdoutOS << "reproducer writes to \"" << reproducerPath << "\"\n";
+        elf::createCrashReproduceTar(std::string(reproducerPath).data(), args);
----------------
written


================
Comment at: lld/tools/lld/lld.cpp:202
+        }
+        stdoutOS << "reproducer writes to \"" << reproducerPath << "\"\n";
+        elf::createCrashReproduceTar(std::string(reproducerPath).data(), args);
----------------
phosek wrote:
> written
I think this output should be only printed after `elf::createCrashReproduceTar` so you don't print an output in the case that function fails for some reason.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102892/new/

https://reviews.llvm.org/D102892



More information about the llvm-commits mailing list