[PATCH] D153595: [llvm-addr2line] Exit early if the input file cannot be read

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 22 16:11:06 PDT 2023


MaskRay created this revision.
MaskRay added reviewers: dblaikie, mgorny, sepavloff, jhenderson.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

GNU addr2line exits immediately if -e (default to a.out) specifies a
file that cannot be open or a directory. In contrast llvm-addr2line does not
exit and, if addresses are not specified in command line, waits for input on
stdin. The GNU behavior argubly seems more desired. Change llvm-addr2line to
match its behavior.

Tests from D147652 <https://reviews.llvm.org/D147652> by Serge Pavlov with small adjustment.

We can make D153219 <https://reviews.llvm.org/D153219> extend this behavior to llvm-symbolizer as well.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153595

Files:
  llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
  llvm/test/tools/llvm-symbolizer/input-base.test
  llvm/test/tools/llvm-symbolizer/input-file-err.test
  llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp


Index: llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
===================================================================
--- llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -478,6 +478,20 @@
   else
     Printer = std::make_unique<LLVMPrinter>(outs(), printError, Config);
 
+  // When an input file is specified, exit immediately if the file cannot be
+  // read. If getOrCreateModuleInfo suceeds, symbolizeInput will reuse the
+  // cached file handle.
+  if (auto *Arg = Args.getLastArg(OPT_obj_EQ); Arg && IsAddr2Line) {
+    auto ModuleOrErr = Symbolizer.getOrCreateModuleInfo(Arg->getValue());
+    if (!ModuleOrErr) {
+      Request SymRequest = {Arg->getValue(), 0};
+      handleAllErrors(ModuleOrErr.takeError(), [&](const ErrorInfoBase &EI) {
+        Printer->printError(SymRequest, EI);
+      });
+      return 1;
+    }
+  }
+
   std::vector<std::string> InputAddresses = Args.getAllArgValues(OPT_INPUT);
   if (InputAddresses.empty()) {
     const int kMaxInputStringLength = 1024;
Index: llvm/test/tools/llvm-symbolizer/input-file-err.test
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-symbolizer/input-file-err.test
@@ -0,0 +1,9 @@
+RUN: not llvm-addr2line -e %p/Inputs/nonexistent 0x12 2>&1 | FileCheck %s --check-prefix=NONEXIST-A2L -DMSG=%errc_ENOENT
+RUN: not llvm-addr2line -e %p/Inputs/nonexistent 2>&1 | FileCheck %s --check-prefix=NONEXIST-A2L -DMSG=%errc_ENOENT
+NONEXIST-A2L: error: '{{.*}}Inputs/nonexistent': [[MSG]]
+
+RUN: not llvm-addr2line -e %p/Inputs 2>&1 | FileCheck %s --check-prefix=DIRECTORY-A2L -DMSG=%errc_EISDIR
+DIRECTORY-A2L: error: '{{.*}}Inputs': [[MSG]]
+
+RUN: not llvm-addr2line --output-style=JSON -e %p/Inputs/nonexistent 2>&1 | FileCheck %s --check-prefix=NONEXIST-JSON -DMSG=%errc_ENOENT
+NONEXIST-JSON: {"Address":"0x0","Error":{"Message":"[[MSG]]"},"ModuleName":"{{.*}}nonexistent"}
Index: llvm/test/tools/llvm-symbolizer/input-base.test
===================================================================
--- llvm/test/tools/llvm-symbolizer/input-base.test
+++ llvm/test/tools/llvm-symbolizer/input-base.test
@@ -11,14 +11,14 @@
 RUN: llvm-symbolizer -e /dev/null -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL-UPPER
 
 # llvm-addr2line always requires hexadecimal, but accepts an optional 0x prefix.
-RUN: llvm-addr2line -e /dev/null -a 0x1234 | FileCheck %s
-RUN: llvm-addr2line -e /dev/null -a 0X1234 | FileCheck %s
-RUN: llvm-addr2line -e /dev/null -a 1234 | FileCheck %s
-RUN: llvm-addr2line -e /dev/null -a 01234 | FileCheck %s
-RUN: llvm-addr2line -e /dev/null -a 0b1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY
-RUN: llvm-addr2line -e /dev/null -a 0B1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY
-RUN: llvm-addr2line -e /dev/null -a 0o1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL-LOWER
-RUN: llvm-addr2line -e /dev/null -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL-UPPER
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0x1234 | FileCheck %s
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0X1234 | FileCheck %s
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 1234 | FileCheck %s
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 01234 | FileCheck %s
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0b1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0B1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0o1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL-LOWER
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL-UPPER
 
 CHECK: 0x1234
 CHECK-NEXT: ??
Index: llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
===================================================================
--- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -119,6 +119,13 @@
     BIDFetcher = std::move(Fetcher);
   }
 
+  /// Returns a SymbolizableModule or an error if loading debug info failed.
+  /// Only one attempt is made to load a module, and errors during loading are
+  /// only reported once. Subsequent calls to get module info for a module that
+  /// failed to load will return nullptr.
+  Expected<SymbolizableModule *>
+  getOrCreateModuleInfo(const std::string &ModuleName);
+
 private:
   // Bundles together object file with code/data and object file with
   // corresponding debug info. These objects can be the same.
@@ -140,12 +147,6 @@
   symbolizeFrameCommon(const T &ModuleSpecifier,
                        object::SectionedAddress ModuleOffset);
 
-  /// Returns a SymbolizableModule or an error if loading debug info failed.
-  /// Only one attempt is made to load a module, and errors during loading are
-  /// only reported once. Subsequent calls to get module info for a module that
-  /// failed to load will return nullptr.
-  Expected<SymbolizableModule *>
-  getOrCreateModuleInfo(const std::string &ModuleName);
   Expected<SymbolizableModule *> getOrCreateModuleInfo(const ObjectFile &Obj);
 
   /// Returns a SymbolizableModule or an error if loading debug info failed.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153595.533811.patch
Type: text/x-patch
Size: 5223 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230622/29b60e7f/attachment.bin>


More information about the llvm-commits mailing list