[llvm] 1792852 - [symbolizer] Change reaction on invalid input
Serge Pavlov via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 30 03:55:34 PDT 2023
Author: Serge Pavlov
Date: 2023-08-30T17:54:37+07:00
New Revision: 1792852f86dc75efa1f44d46b1a0daf386d64afa
URL: https://github.com/llvm/llvm-project/commit/1792852f86dc75efa1f44d46b1a0daf386d64afa
DIFF: https://github.com/llvm/llvm-project/commit/1792852f86dc75efa1f44d46b1a0daf386d64afa.diff
LOG: [symbolizer] Change reaction on invalid input
If llvm-symbolizer finds a malformed command, it echoes it to the
standard output. New versions of binutils (starting from 2.39) allow to
specify an address by a symbols. Implementation of this feature in
llvm-symbolizer makes the current reaction on invalid input
inappropriate. Almost any invalid command may be treated as a symbol
name, so the right reaction should be "symbol not found" in such case.
The exception are commands that are recognized but have incorrect
syntax, like "FILE:FILE:". The utility must produce descriptive
diagnostic for such input and route it to the stderr.
This change implements the new reaction on invalid input and is a
prerequisite for implementation of symbol lookup in llvm-symbolizer.
Differential Revision: https://reviews.llvm.org/D157210
Added:
llvm/test/tools/llvm-symbolizer/get-input-file.test
Modified:
llvm/docs/CommandGuide/llvm-symbolizer.rst
llvm/docs/ReleaseNotes.rst
llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
llvm/test/Support/interrupts.test
llvm/test/tools/llvm-symbolizer/debuginfod.test
llvm/test/tools/llvm-symbolizer/file-prefix.test
llvm/test/tools/llvm-symbolizer/flag-grouping.test
llvm/test/tools/llvm-symbolizer/flush-output.s
llvm/test/tools/llvm-symbolizer/functions.s
llvm/test/tools/llvm-symbolizer/input-base.test
llvm/test/tools/llvm-symbolizer/invalid-input-address.test
llvm/test/tools/llvm-symbolizer/options-from-env.test
llvm/test/tools/llvm-symbolizer/output-style-empty-line.test
llvm/test/tools/llvm-symbolizer/output-style-json-code.test
llvm/test/tools/llvm-symbolizer/output-style-json-data.test
llvm/test/tools/llvm-symbolizer/output-style-json-frame.ll
llvm/test/tools/llvm-symbolizer/sym-verbose.test
llvm/test/tools/llvm-symbolizer/sym.test
llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
Removed:
################################################################################
diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst
index d058cde98f1b0e..fe5df077b45664 100644
--- a/llvm/docs/CommandGuide/llvm-symbolizer.rst
+++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst
@@ -18,8 +18,8 @@ symbolize logs containing :doc:`Symbolizer Markup </SymbolizerMarkupFormat>` via
If no address is specified on the command-line, it reads the addresses from
standard input. If no input name is specified on the command-line, but addresses
-are, or if at any time an input value is not recognized, the input is simply
-echoed to the output.
+are, the first address value is treated as an input name. If an input value is not
+recognized, it reports that source information is not found.
Input names can be specified together with the addresses either on standard
input or as positional arguments on the command-line. By default, input names
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 5c4b85c3a85aa1..096157b7710a67 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -160,6 +160,9 @@ Changes to the Debug Info
Changes to the LLVM tools
---------------------------------
+* llvm-symbolizer now treats invalid input as an address for which source
+ information is not found.
+
Changes to LLDB
---------------------------------
diff --git a/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
index b89f1da5857acf..026f917ced5bc1 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
@@ -47,9 +47,6 @@ class DIPrinter {
virtual void print(const Request &Request,
const std::vector<DILocal> &Locals) = 0;
- virtual void printInvalidCommand(const Request &Request,
- StringRef Command) = 0;
-
virtual bool printError(const Request &Request,
const ErrorInfoBase &ErrorInfo) = 0;
@@ -83,7 +80,7 @@ class PlainPrinterBase : public DIPrinter {
virtual void printFooter() {}
private:
- void printHeader(uint64_t Address);
+ void printHeader(std::optional<uint64_t> Address);
public:
PlainPrinterBase(raw_ostream &OS, ErrorHandler EH, PrinterConfig &Config)
@@ -95,8 +92,6 @@ class PlainPrinterBase : public DIPrinter {
void print(const Request &Request,
const std::vector<DILocal> &Locals) override;
- void printInvalidCommand(const Request &Request, StringRef Command) override;
-
bool printError(const Request &Request,
const ErrorInfoBase &ErrorInfo) override;
@@ -147,8 +142,6 @@ class JSONPrinter : public DIPrinter {
void print(const Request &Request,
const std::vector<DILocal> &Locals) override;
- void printInvalidCommand(const Request &Request, StringRef Command) override;
-
bool printError(const Request &Request,
const ErrorInfoBase &ErrorInfo) override;
diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index f9669b554b4708..dcf5eee2bb32b6 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -105,10 +105,10 @@ class SourceCode {
}
};
-void PlainPrinterBase::printHeader(uint64_t Address) {
- if (Config.PrintAddress) {
+void PlainPrinterBase::printHeader(std::optional<uint64_t> Address) {
+ if (Address.has_value() && Config.PrintAddress) {
OS << "0x";
- OS.write_hex(Address);
+ OS.write_hex(*Address);
StringRef Delimiter = Config.Pretty ? ": " : "\n";
OS << Delimiter;
}
@@ -182,7 +182,7 @@ void PlainPrinterBase::print(const DILineInfo &Info, bool Inlined) {
}
void PlainPrinterBase::print(const Request &Request, const DILineInfo &Info) {
- printHeader(*Request.Address);
+ printHeader(Request.Address);
print(Info, false);
printFooter();
}
@@ -260,11 +260,6 @@ void PlainPrinterBase::print(const Request &Request,
printFooter();
}
-void PlainPrinterBase::printInvalidCommand(const Request &Request,
- StringRef Command) {
- OS << Command << '\n';
-}
-
bool PlainPrinterBase::printError(const Request &Request,
const ErrorInfoBase &ErrorInfo) {
ErrHandler(ErrorInfo, Request.ModuleName);
@@ -367,13 +362,6 @@ void JSONPrinter::print(const Request &Request,
printJSON(std::move(Json));
}
-void JSONPrinter::printInvalidCommand(const Request &Request,
- StringRef Command) {
- printError(Request,
- StringError("unable to parse arguments: " + Command,
- std::make_error_code(std::errc::invalid_argument)));
-}
-
bool JSONPrinter::printError(const Request &Request,
const ErrorInfoBase &ErrorInfo) {
json::Object Json = toJSON(Request, ErrorInfo.message());
diff --git a/llvm/test/Support/interrupts.test b/llvm/test/Support/interrupts.test
index 1201e12829c413..86730f5139c042 100644
--- a/llvm/test/Support/interrupts.test
+++ b/llvm/test/Support/interrupts.test
@@ -12,7 +12,7 @@ import time
def run_symbolizer():
proc = subprocess.Popen([sys.argv[2]], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
# Write then read some output to ensure the process has started fully.
- proc.stdin.write(b'foo\n')
+ proc.stdin.write(b'foo bar\n')
proc.stdin.flush()
proc.stdout.readline()
# Windows handles signals
diff erently.
diff --git a/llvm/test/tools/llvm-symbolizer/debuginfod.test b/llvm/test/tools/llvm-symbolizer/debuginfod.test
index 98559077cfe057..1e2c935ffeb0bc 100644
--- a/llvm/test/tools/llvm-symbolizer/debuginfod.test
+++ b/llvm/test/tools/llvm-symbolizer/debuginfod.test
@@ -39,9 +39,9 @@ RUN: FileCheck %s --check-prefix=FOUND
# Passing BUILDID twice is a syntax error.
RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \
-RUN: "BUILDID:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" | \
+RUN: "BUILDID:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" 2>&1 | \
RUN: FileCheck %s --check-prefix=BUILDIDBUILDID
-BUILDIDBUILDID: BUILDID:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d
+BUILDIDBUILDID: error: 'BUILDID:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d': duplicate input file specification prefix
# CODE should work preceding build ID.
RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \
@@ -63,16 +63,16 @@ NOTHINGFOUND-NEXT: ??:0:0
# BUILDID shouldn't be parsed if --obj is given, just like regular filenames.
RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \
RUN: --obj=%t/addr.exe \
-RUN: "BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" | \
+RUN: "BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" 2>&1 | \
RUN: FileCheck %s --check-prefix=BUILDIDIGNORED
-BUILDIDIGNORED: BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d
+BUILDIDIGNORED: error: 'BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d': input file has already been specified
# Providing both BUILDID and FILE is a syntax error.
RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \
-RUN: "BUILDID:FILE:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" | \
+RUN: "BUILDID:FILE:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" 2>&1 | \
RUN: FileCheck %s --check-prefix=BUILDIDFILE
-BUILDIDFILE: BUILDID:FILE:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d
+BUILDIDFILE: error: 'BUILDID:FILE:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d': duplicate input file specification prefix
RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \
-RUN: "FILE:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" | \
+RUN: "FILE:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d" 2>&1 | \
RUN: FileCheck %s --check-prefix=FILEBUILDID
-FILEBUILDID: FILE:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d
+FILEBUILDID: error: 'FILE:BUILDID:127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d': duplicate input file specification prefix
diff --git a/llvm/test/tools/llvm-symbolizer/file-prefix.test b/llvm/test/tools/llvm-symbolizer/file-prefix.test
index a309914118050f..66f645017f1fc9 100644
--- a/llvm/test/tools/llvm-symbolizer/file-prefix.test
+++ b/llvm/test/tools/llvm-symbolizer/file-prefix.test
@@ -4,6 +4,8 @@ RUN: FileCheck %s --check-prefix=FOUND
FOUND: {{[/\]+}}tmp{{[/\]+}}x.c:14:0
# Passing FILE twice is a syntax error.
-RUN: llvm-symbolizer "CODE FILE:FILE:%p/Inputs/addr.exe 0x40054d" | \
-RUN: FileCheck %s --check-prefix=FILEFILE
-FILEFILE: CODE FILE:FILE:{{.*}}/Inputs/addr.exe 0x40054d
+RUN: llvm-symbolizer "CODE FILE:FILE:%p/Inputs/addr.exe 0x40054d" 2>%t.err | FileCheck --check-prefix=NOTFOUND %s
+RUN: FileCheck %s --check-prefix=FILEFILE --input-file %t.err
+NOTFOUND: ??
+NOTFOUND-NEXT: ??:0:0
+FILEFILE: error: 'CODE FILE:FILE:{{.*}}/Inputs/addr.exe 0x40054d': duplicate input file specification prefix
diff --git a/llvm/test/tools/llvm-symbolizer/flag-grouping.test b/llvm/test/tools/llvm-symbolizer/flag-grouping.test
index cc2dbfdc893d93..7bcb68dd470677 100644
--- a/llvm/test/tools/llvm-symbolizer/flag-grouping.test
+++ b/llvm/test/tools/llvm-symbolizer/flag-grouping.test
@@ -3,8 +3,8 @@ RUN: llvm-symbolizer -apCie %p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck
RUN: llvm-symbolizer -apCie=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck %s
RUN: llvm-symbolizer -apCie%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck %s
-CHECK: some text
+CHECK: ?? at ??:0:0
CHECK: 0x40054d: inctwo
CHECK: (inlined by) inc
CHECK (inlined by) main
-CHECK: some text2
+CHECK: ?? at ??:0:0
diff --git a/llvm/test/tools/llvm-symbolizer/flush-output.s b/llvm/test/tools/llvm-symbolizer/flush-output.s
index 840f430feaf810..070bf3fa3c86e3 100644
--- a/llvm/test/tools/llvm-symbolizer/flush-output.s
+++ b/llvm/test/tools/llvm-symbolizer/flush-output.s
@@ -14,4 +14,4 @@ foo:
# RUN: | FileCheck %s
# CHECK: flush-output.s:10
-# CHECK: bad
+# CHECK: ??:0
diff --git a/llvm/test/tools/llvm-symbolizer/functions.s b/llvm/test/tools/llvm-symbolizer/functions.s
index 3093d801d395f9..953760ac24af90 100644
--- a/llvm/test/tools/llvm-symbolizer/functions.s
+++ b/llvm/test/tools/llvm-symbolizer/functions.s
@@ -26,7 +26,8 @@
# NONE-NOT: foo
# NONE: functions.cpp:2:0
-# ERR: none
+# ERR: ??
+# ERR-NEXT: ??:0
# The assembly below is a stripped down version of the output of:
# clang -S -g --target=x86_64-pc-linux
diff --git a/llvm/test/tools/llvm-symbolizer/get-input-file.test b/llvm/test/tools/llvm-symbolizer/get-input-file.test
new file mode 100644
index 00000000000000..e98b8ca389697e
--- /dev/null
+++ b/llvm/test/tools/llvm-symbolizer/get-input-file.test
@@ -0,0 +1,47 @@
+# If binary input file is not specified, llvm-symbolizer assumes it is the first
+# item in the command.
+
+# No input items at all, complain about missing input file.
+RUN: echo | llvm-symbolizer 2>%t.1.err | FileCheck %s --check-prefix=NOSOURCE
+RUN: FileCheck --input-file=%t.1.err --check-prefix=NOFILE %s
+
+# Only one input item, complain about missing addresses.
+RUN: llvm-symbolizer "foo" 2>%t.2.err | FileCheck %s --check-prefix=NOSOURCE
+RUN: FileCheck --input-file=%t.2.err --check-prefix=NOADDR %s
+
+# Two items specified, check if the first one is an existing file.
+RUN: llvm-symbolizer "foo 400" 2>%t.3.err | FileCheck %s --check-prefix=NOSOURCE
+RUN: FileCheck --input-file=%t.3.err --check-prefix=NOTFOUND %s
+
+# FILE: must be followed by a file name.
+RUN: llvm-symbolizer "FILE:" 2>%t.4.err | FileCheck %s --check-prefix=NOSOURCE
+RUN: FileCheck --input-file=%t.4.err --check-prefix=MISSING-FILE %s
+
+# BUILDID: must be followed by a hash.
+RUN: llvm-symbolizer "BUILDID:" 2>%t.5.err | FileCheck %s --check-prefix=NOSOURCE
+RUN: FileCheck --input-file=%t.5.err --check-prefix=MISSING-HASH %s
+
+# Wrong build-id.
+RUN: llvm-symbolizer "BUILDID: foo" 2>%t.6.err | FileCheck %s --check-prefix=NOSOURCE
+RUN: FileCheck --input-file=%t.6.err --check-prefix=BAD-HASH %s
+
+# Unbalanced string quotes in the file name.
+RUN: llvm-symbolizer "FILE:\"foo" 2>%t.7.err | FileCheck %s --check-prefix=NOSOURCE
+RUN: FileCheck --input-file=%t.7.err --check-prefix=BAD-QUOTE %s
+
+NOSOURCE: ??
+NOSOURCE-NEXT: ??:0:0
+
+NOFILE: error: no input filename has been specified
+
+NOADDR: error: 'foo': no module offset has been specified
+
+NOTFOUND: error: 'foo': {{[nN]}}o such file or directory
+
+MISSING-FILE: error: 'FILE:': must be followed by an input file
+
+MISSING-HASH: error: 'BUILDID:': must be followed by a hash
+
+BAD-HASH: error: 'BUILDID: foo': wrong format of build-id
+
+BAD-QUOTE: error: 'FILE:"foo': unbalanced quotes in input file name
diff --git a/llvm/test/tools/llvm-symbolizer/input-base.test b/llvm/test/tools/llvm-symbolizer/input-base.test
index 21b3fc837e16c1..78cf1a38bf4e04 100644
--- a/llvm/test/tools/llvm-symbolizer/input-base.test
+++ b/llvm/test/tools/llvm-symbolizer/input-base.test
@@ -8,7 +8,7 @@ RUN: llvm-symbolizer -e %p/Inputs/addr.exe -a 0B1001000110100 | FileCheck %s
RUN: llvm-symbolizer -e %p/Inputs/addr.exe -a 0o11064 | FileCheck %s
# llvm-symbolizer / StringRef::getAsInteger only accepts the 0o prefix in lowercase.
-RUN: llvm-symbolizer -e %p/Inputs/addr.exe -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL-UPPER
+RUN: llvm-symbolizer -e %p/Inputs/addr.exe -a 0O1234 | FileCheck %s --check-prefix=INVALID
# llvm-addr2line always requires hexadecimal, but accepts an optional 0x prefix.
RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0x1234 | FileCheck %s
@@ -17,17 +17,16 @@ 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
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0o1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL
+RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL
CHECK: 0x1234
CHECK-NEXT: ??
+INVALID: ??
+INVALID-NEXT: ??:0
+
HEXADECIMAL-NOT-BINARY: 0xb1010
HEXADECIMAL-NOT-BINARY: ??
-INVALID-NOT-OCTAL-LOWER: 0o1234
-INVALID-NOT-OCTAL-LOWER-NOT: ??
-
-INVALID-NOT-OCTAL-UPPER: 0O1234
-INVALID-NOT-OCTAL-UPPER-NOT: ??
+INVALID-NOT-OCTAL: ??:0
diff --git a/llvm/test/tools/llvm-symbolizer/invalid-input-address.test b/llvm/test/tools/llvm-symbolizer/invalid-input-address.test
index 44291186d7fd2d..e9f25c5e299401 100644
--- a/llvm/test/tools/llvm-symbolizer/invalid-input-address.test
+++ b/llvm/test/tools/llvm-symbolizer/invalid-input-address.test
@@ -1,10 +1,12 @@
# Use address that can't fit in a 64-bit number. Show that llvm-symbolizer
-# simply echoes it as per other malformed input addresses.
+# simply treats it as an unknown symbol.
RUN: llvm-symbolizer --obj=%p/Inputs/addr.exe 0x10000000000000000 | FileCheck --check-prefix=LARGE-ADDR %s
-LARGE-ADDR-NOT: {{.}}
-LARGE-ADDR: 0x10000000000000000
-LARGE-ADDR-NOT: {{.}}
+LARGE-ADDR-NOT: {{.}}
+LARGE-ADDR: ??
+LARGE-ADDR-NEXT: ??:0:0
+LARGE-ADDR-EMPTY:
+LARGE-ADDR-NOT: {{.}}
RUN: echo '"some text"' '"some text2"' > %t.rsp
RUN: echo -e 'some text\nsome text2\n' > %t.inp
@@ -19,5 +21,5 @@ RUN: llvm-addr2line --obj=%p/Inputs/addr.exe < %t.inp | FileCheck --check-prefix
RUN: llvm-addr2line --obj=%p/Inputs/addr.exe "some text" "some text2" | FileCheck --check-prefix=BAD-INPUT %s
RUN: llvm-addr2line --obj=%p/Inputs/addr.exe @%t.rsp | FileCheck --check-prefix=BAD-INPUT %s
-BAD-INPUT: some text
-BAD-INPUT-NEXT: some text2
+BAD-INPUT: ??
+BAD-INPUT-NEXT: ??:0
diff --git a/llvm/test/tools/llvm-symbolizer/options-from-env.test b/llvm/test/tools/llvm-symbolizer/options-from-env.test
index 5fb566f56a0253..51e35b284b843f 100644
--- a/llvm/test/tools/llvm-symbolizer/options-from-env.test
+++ b/llvm/test/tools/llvm-symbolizer/options-from-env.test
@@ -1,6 +1,16 @@
-# RUN: env LLVM_SYMBOLIZER_OPTS='0 1 --verbose' llvm-symbolizer 2 | FileCheck %s
-# RUN: env LLVM_ADDR2LINE_OPTS='0 1 --verbose' llvm-addr2line 2 | FileCheck %s
+RUN: env LLVM_SYMBOLIZER_OPTS='-e %p/Inputs/discrim --verbose' llvm-symbolizer 0x400590 | FileCheck --check-prefix=LLVM %s
+RUN: env LLVM_ADDR2LINE_OPTS='-e %p/Inputs/discrim --verbose' llvm-addr2line 0x400590 | FileCheck --check-prefix=GNU %s
-# CHECK: 0
-# CHECK-NEXT: 1
-# CHECK-NEXT: 2
+LLVM: foo
+LLVM-NEXT: Filename: /tmp{{[\\/]}}discrim.c
+LLVM-NEXT: Function start filename: /tmp{{[\\/]}}discrim.c
+LLVM-NEXT: Function start line: 4
+LLVM-NEXT: Function start address: 0x400590
+LLVM-NEXT: Line: 5
+LLVM-NEXT: Column: 7
+
+GNU: Filename: /tmp{{[\\/]}}discrim.c
+GNU-NEXT: Function start filename: /tmp{{[\\/]}}discrim.c
+GNU-NEXT: Function start line: 4
+GNU-NEXT: Line: 5
+GNU-NEXT: Column: 7
diff --git a/llvm/test/tools/llvm-symbolizer/output-style-empty-line.test b/llvm/test/tools/llvm-symbolizer/output-style-empty-line.test
index a3797d7b2e94c1..70622ec3ab57d7 100644
--- a/llvm/test/tools/llvm-symbolizer/output-style-empty-line.test
+++ b/llvm/test/tools/llvm-symbolizer/output-style-empty-line.test
@@ -13,7 +13,7 @@ RUN: | FileCheck %s --check-prefix=LLVM
LLVM: x.c:14:0
LLVM-EMPTY:
-LLVM-NEXT: some text2
+LLVM-NEXT: ??
RUN: llvm-symbolizer --output-style=GNU -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \
RUN: | FileCheck %s --check-prefix=GNU
@@ -25,4 +25,4 @@ RUN: llvm-addr2line --output-style=GNU -i -e %p/Inputs/addr.exe < %p/Inputs/addr
RUN: | FileCheck %s --check-prefix=GNU
GNU: x.c:14
-GNU-NEXT: some text2
+GNU-NEXT: ??
diff --git a/llvm/test/tools/llvm-symbolizer/output-style-json-code.test b/llvm/test/tools/llvm-symbolizer/output-style-json-code.test
index e3977f291d4909..9179b673f39fd0 100644
--- a/llvm/test/tools/llvm-symbolizer/output-style-json-code.test
+++ b/llvm/test/tools/llvm-symbolizer/output-style-json-code.test
@@ -25,39 +25,39 @@
# RUN: llvm-symbolizer --output-style=JSON --no-inlines -e %p/Inputs/addr.exe < %p/Inputs/addr.inp | \
# RUN: FileCheck %s --check-prefix=NO-INLINES --strict-whitespace --match-full-lines --implicit-check-not={{.}}
## Invalid first argument before any valid one.
-# NO-INLINES:{"Error":{"Message":"unable to parse arguments: some text"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# NO-INLINES:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
## Resolve valid address.
# NO-INLINES-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2}]}
## Invalid argument after a valid one.
-# NO-INLINES-NEXT:{"Error":{"Message":"unable to parse arguments: some text2"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# NO-INLINES-NEXT:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
## This test case is testing stdin input, inlines by default.
# RUN: llvm-symbolizer --output-style=JSON -e %p/Inputs/addr.exe < %p/Inputs/addr.inp | \
# RUN: FileCheck %s --check-prefix=INLINE --strict-whitespace --match-full-lines --implicit-check-not={{.}}
## Invalid first argument before any valid one.
-# INLINE:{"Error":{"Message":"unable to parse arguments: some text"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# INLINE:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
## Resolve valid address.
# INLINE-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inctwo","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inc","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
## Invalid argument after a valid one.
-# INLINE-NEXT:{"Error":{"Message":"unable to parse arguments: some text2"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# INLINE-NEXT:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
## Also check the last test case with llvm-adr2line.
## The expected result is the same with -f -i.
# RUN: llvm-addr2line --output-style=JSON -f -i -e %p/Inputs/addr.exe < %p/Inputs/addr.inp | \
# RUN: FileCheck %s --check-prefix=INLINE-A2L --strict-whitespace --match-full-lines --implicit-check-not={{.}}
## Invalid first argument before any valid one.
-# INLINE-A2L:{"Error":{"Message":"unable to parse arguments: some text"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# INLINE-A2L:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
## Resolve valid address.
# INLINE-A2L-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inctwo","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inc","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
## Invalid argument after a valid one.
-# INLINE-A2L-NEXT:{"Error":{"Message":"unable to parse arguments: some text2"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# INLINE-A2L-NEXT:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
## Note llvm-addr2line without -f does not print the function name in JSON too.
# RUN: llvm-addr2line --output-style=JSON -i -e %p/Inputs/addr.exe < %p/Inputs/addr.inp | \
# RUN: FileCheck %s --check-prefix=NO-FUNC-A2L --strict-whitespace --match-full-lines --implicit-check-not={{.}}
## Invalid first argument before any valid one.
-# NO-FUNC-A2L:{"Error":{"Message":"unable to parse arguments: some text"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# NO-FUNC-A2L:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
## Resolve valid address.
# NO-FUNC-A2L-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
## Invalid argument after a valid one.
-# NO-FUNC-A2L-NEXT:{"Error":{"Message":"unable to parse arguments: some text2"},"ModuleName":"{{.*}}/Inputs/addr.exe"}
+# NO-FUNC-A2L-NEXT:{"ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}
diff --git a/llvm/test/tools/llvm-symbolizer/output-style-json-data.test b/llvm/test/tools/llvm-symbolizer/output-style-json-data.test
index f77cf40b907418..722ac73d751043 100644
--- a/llvm/test/tools/llvm-symbolizer/output-style-json-data.test
+++ b/llvm/test/tools/llvm-symbolizer/output-style-json-data.test
@@ -10,7 +10,7 @@
## Handle invalid argument.
# RUN: llvm-symbolizer "DATA tmp.o Z" --output-style=JSON | \
# RUN: FileCheck %s --check-prefix=INVARG --strict-whitespace --match-full-lines --implicit-check-not={{.}}
-# INVARG:[{"Error":{"Message":"unable to parse arguments: DATA tmp.o Z"},"ModuleName":"tmp.o"}]
+# INVARG:[{"ModuleName":"tmp.o","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}]
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
diff --git a/llvm/test/tools/llvm-symbolizer/output-style-json-frame.ll b/llvm/test/tools/llvm-symbolizer/output-style-json-frame.ll
index d6cb4030c0927e..8a99345420fdeb 100644
--- a/llvm/test/tools/llvm-symbolizer/output-style-json-frame.ll
+++ b/llvm/test/tools/llvm-symbolizer/output-style-json-frame.ll
@@ -10,7 +10,7 @@
;; Handle invalid argument.
; RUN: llvm-symbolizer "FRAME tmp.o Z" --output-style=JSON | \
; RUN: FileCheck %s --check-prefix=INVARG --strict-whitespace --match-full-lines --implicit-check-not={{.}}
-; INVARG:[{"Error":{"Message":"unable to parse arguments: FRAME tmp.o Z"},"ModuleName":"tmp.o"}]
+; INVARG:[{"ModuleName":"tmp.o","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}]
; RUN: llc -filetype=obj -o %t.o %s
diff --git a/llvm/test/tools/llvm-symbolizer/sym-verbose.test b/llvm/test/tools/llvm-symbolizer/sym-verbose.test
index 2c4f4c3621fe54..831fd6c7f05071 100644
--- a/llvm/test/tools/llvm-symbolizer/sym-verbose.test
+++ b/llvm/test/tools/llvm-symbolizer/sym-verbose.test
@@ -13,7 +13,7 @@
RUN: llvm-symbolizer --verbose --print-address --obj=%p/Inputs/discrim < %p/Inputs/discrim.inp | FileCheck %s
-CHECK: some text
+CHECK: ??
CHECK: 0x400590
CHECK-NEXT: foo
@@ -118,4 +118,4 @@ CHECK-NEXT: Line: 10
CHECK-NEXT: Column: 0
CHECK-NEXT: Discriminator: 2
-CHECK: some more text
+CHECK: ??
diff --git a/llvm/test/tools/llvm-symbolizer/sym.test b/llvm/test/tools/llvm-symbolizer/sym.test
index a9a1339bd6c48a..a5793efb65029f 100644
--- a/llvm/test/tools/llvm-symbolizer/sym.test
+++ b/llvm/test/tools/llvm-symbolizer/sym.test
@@ -21,7 +21,8 @@ RUN: llvm-symbolizer --print-address --obj=%p/Inputs/addr.exe < %p/Inputs/addr.i
RUN: llvm-symbolizer --addresses --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck %s
RUN: llvm-symbolizer -a --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck %s
-CHECK: some text
+CHECK: ??:0:0
+CHECK-EMPTY:
CHECK-NEXT: 0x40054d
CHECK-NEXT: inctwo
CHECK-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:3:3
@@ -30,7 +31,8 @@ CHECK-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:7:0
CHECK-NEXT: main
CHECK-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:14:0
CHECK-EMPTY:
-CHECK-NEXT: some text2
+CHECK-NEXT: ??
+CHECK-NEXT: ??:0:0
RUN: llvm-symbolizer --inlining --print-address --pretty-print --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefix="PRETTY" %s
RUN: llvm-symbolizer --inlining --print-address -p --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefix="PRETTY" %s
@@ -43,11 +45,11 @@ RUN: llvm-symbolizer -i --print-address -p --obj=%p/Inputs/addr.exe < %p/Inputs/
# Support this compatibility alias for a while.
RUN: llvm-symbolizer --inlining=true --print-address -p --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefix="PRETTY" %s
-PRETTY: some text
+PRETTY: ??:0:0
PRETTY: {{[0x]+}}40054d: inctwo at {{[/\]+}}tmp{{[/\]+}}x.c:3:3
PRETTY: (inlined by) inc at {{[/\]+}}tmp{{[/\]+}}x.c:7:0
PRETTY: (inlined by) main at {{[/\]+}}tmp{{[/\]+}}x.c:14:0
-PRETTY: some text2
+PRETTY: ??:0:0
RUN: llvm-addr2line --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefix=A2L %s
RUN: llvm-addr2line -a --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2L,A2L_A %s
@@ -62,7 +64,7 @@ RUN: llvm-addr2line -pai --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileChe
RUN: llvm-addr2line -pfi --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_F,A2LP_FI %s
RUN: llvm-addr2line -pafi --obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_AF,A2LP_FI %s
-A2L: some text
+A2L: ??:0
A2L_A-NEXT: 0x40054d
A2L_F-NEXT: inctwo
A2L-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:3{{$}}
@@ -70,9 +72,10 @@ A2L_FI-NEXT: inc{{$}}
A2L_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:7{{$}}
A2L_FI-NEXT: main
A2L_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:14{{$}}
-A2L-NEXT: some text2
+A2L_F-NEXT: ??
+A2L-NEXT: ??:0
-A2LP: some text
+A2LP: ??:0
A2LP_A-NEXT: 0x40054d: {{[/\]+}}tmp{{[/\]+}}x.c:3{{$}}
A2LP_F-NEXT: inctwo at {{[/\]+}}tmp{{[/\]+}}x.c:3{{$}}
A2LP_AF-NEXT: 0x40054d: inctwo at {{[/\]+}}tmp{{[/\]+}}x.c:3{{$}}
@@ -80,4 +83,4 @@ A2LP_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:7{{$}}
A2LP_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:14{{$}}
A2LP_FI-NEXT: (inlined by) inc at {{[/\]+}}tmp{{[/\]+}}x.c:7{{$}}
A2LP_FI-NEXT: (inlined by) main at {{[/\]+}}tmp{{[/\]+}}x.c:14{{$}}
-A2LP-NEXT: some text2
+A2LP-NEXT: ??:0
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 4c1c2f224984c7..78a0e6772f3fb3 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -32,6 +32,7 @@
#include "llvm/Support/COM.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/LLVMDriver.h"
@@ -80,10 +81,10 @@ class SymbolizerOptTable : public opt::GenericOptTable {
static std::string ToolName;
-static void printError(const ErrorInfoBase &EI, StringRef Path) {
+static void printError(const ErrorInfoBase &EI, StringRef AuxInfo) {
WithColor::error(errs(), ToolName);
- if (!EI.isA<FileError>())
- errs() << "'" << Path << "': ";
+ if (!AuxInfo.empty())
+ errs() << "'" << AuxInfo << "': ";
EI.log(errs());
errs() << '\n';
}
@@ -151,10 +152,14 @@ static StringRef getSpaceDelimitedWord(StringRef &Source) {
return Result;
}
-static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
- StringRef InputString, Command &Cmd,
- std::string &ModuleName, object::BuildID &BuildID,
- uint64_t &ModuleOffset) {
+static Error makeStringError(StringRef Msg) {
+ return make_error<StringError>(Msg, inconvertibleErrorCode());
+}
+
+static Error parseCommand(StringRef BinaryName, bool IsAddr2Line,
+ StringRef InputString, Command &Cmd,
+ std::string &ModuleName, object::BuildID &BuildID,
+ uint64_t &ModuleOffset) {
ModuleName = BinaryName;
if (InputString.consume_front("CODE ")) {
Cmd = Command::Code;
@@ -174,34 +179,40 @@ static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
InputString = InputString.ltrim();
if (InputString.consume_front("FILE:")) {
if (HasFilePrefix || HasBuildIDPrefix)
- // Input file specification prefix has already been seen.
- return false;
+ return makeStringError("duplicate input file specification prefix");
HasFilePrefix = true;
continue;
}
if (InputString.consume_front("BUILDID:")) {
if (HasBuildIDPrefix || HasFilePrefix)
- // Input file specification prefix has already been seen.
- return false;
+ return makeStringError("duplicate input file specification prefix");
HasBuildIDPrefix = true;
continue;
}
break;
}
+ // If an input file is not specified on the command line, try to extract it
+ // from the command.
if (HasBuildIDPrefix || HasFilePrefix) {
+ InputString = InputString.ltrim();
+ if (InputString.empty()) {
+ if (HasFilePrefix)
+ return makeStringError("must be followed by an input file");
+ else
+ return makeStringError("must be followed by a hash");
+ }
+
if (!BinaryName.empty() || !BuildID.empty())
- // Input file has already been specified on the command line.
- return false;
+ return makeStringError("input file has already been specified");
+
StringRef Name = getSpaceDelimitedWord(InputString);
if (Name.empty())
- // Wrong name for module file.
- return false;
+ return makeStringError("unbalanced quotes in input file name");
if (HasBuildIDPrefix) {
BuildID = parseBuildID(Name);
if (BuildID.empty())
- // Wrong format of BuildID hash.
- return false;
+ return makeStringError("wrong format of build-id");
} else {
ModuleName = Name;
}
@@ -209,20 +220,28 @@ static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
// No input file has been specified. If the input string contains at least
// two items, assume that the first item is a file name.
ModuleName = getSpaceDelimitedWord(InputString);
- if (ModuleName.empty() || InputString.empty())
- // No input filename has been specified.
- return false;
+ if (ModuleName.empty())
+ return makeStringError("no input filename has been specified");
}
- // Skip delimiters and parse module offset.
+ // Parse module offset.
InputString = InputString.ltrim();
+ if (InputString.empty())
+ return makeStringError("no module offset has been specified");
int OffsetLength = InputString.find_first_of(" \n\r");
StringRef Offset = InputString.substr(0, OffsetLength);
// GNU addr2line assumes the offset is hexadecimal and allows a redundant
// "0x" or "0X" prefix; do the same for compatibility.
if (IsAddr2Line)
Offset.consume_front("0x") || Offset.consume_front("0X");
- return !Offset.getAsInteger(IsAddr2Line ? 16 : 0, ModuleOffset);
+
+ // If the input is not a valid module offset, it is not an error, but its
+ // lookup does not make sense. Return error of
diff erent kind to distinguish
+ // from error or success.
+ if (Offset.getAsInteger(IsAddr2Line ? 16 : 0, ModuleOffset))
+ return errorCodeToError(errc::invalid_argument);
+
+ return Error::success();
}
template <typename T>
@@ -268,6 +287,11 @@ void executeCommand(StringRef ModuleName, const T &ModuleSpec, Command Cmd,
Symbolizer.pruneCache();
}
+static void printUnknownLineInfo(std::string ModuleName, DIPrinter &Printer) {
+ Request SymRequest = {ModuleName, std::nullopt};
+ Printer.print(SymRequest, DILineInfo());
+}
+
static void symbolizeInput(const opt::InputArgList &Args,
object::BuildIDRef IncomingBuildID,
uint64_t AdjustVMA, bool IsAddr2Line,
@@ -277,9 +301,16 @@ static void symbolizeInput(const opt::InputArgList &Args,
std::string ModuleName;
object::BuildID BuildID(IncomingBuildID.begin(), IncomingBuildID.end());
uint64_t Offset = 0;
- if (!parseCommand(Args.getLastArgValue(OPT_obj_EQ), IsAddr2Line,
- StringRef(InputString), Cmd, ModuleName, BuildID, Offset)) {
- Printer.printInvalidCommand({ModuleName, std::nullopt}, InputString);
+ if (Error E = parseCommand(Args.getLastArgValue(OPT_obj_EQ), IsAddr2Line,
+ StringRef(InputString), Cmd, ModuleName, BuildID,
+ Offset)) {
+ handleAllErrors(
+ std::move(E),
+ [&](const StringError &EI) {
+ printError(EI, InputString);
+ printUnknownLineInfo(ModuleName, Printer);
+ },
+ [&](const ECError &EI) { printUnknownLineInfo(ModuleName, Printer); });
return;
}
bool ShouldInline = Args.hasFlag(OPT_inlines, OPT_no_inlines, !IsAddr2Line);
More information about the llvm-commits
mailing list