[symbolizer] Change error message if module not found (recommit)

This is a recommit of 75f1f158812d, reverted in 7a443b1c493d, because
it caused compilation error in
compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp.
The error was fixed by Kasimir Georgiev in de4c038c7ba2, but this
commit was reverted in de088dd3a0aa, because the initial commit was
reverted.

This commit reverts both the reverting commits, 7a443b1c493d and
de088dd3a0aa.

Original commit message is below.

If llvm-symbolize did not find module, the error looked like:

    LLVMSymbolizer: error reading file: No such file or directory

This message does not follow common practice: LLVMSymbolizer is not an
utility name. Also the message did not not contain the name of missed file.

With this change the error message looks differently:

    llvm-symbolizer: error: 'abc': No such file or directory

This format is closer to messages produced by other utilities and allow
proper coloring.

Differential Revision: https://reviews.llvm.org/D148032
This commit is contained in:
Serge Pavlov 2023-04-23 06:35:35 +00:00
parent a8aa43bb1a
commit 1d5fa4f88f
10 changed files with 56 additions and 39 deletions

View File

@ -41,6 +41,16 @@ static llvm::symbolize::PrinterConfig getDefaultPrinterConfig() {
return Config;
}
static llvm::symbolize::ErrorHandler symbolize_error_handler(
llvm::raw_string_ostream &OS) {
return
[&](const llvm::ErrorInfoBase &ErrorInfo, llvm::StringRef ErrorBanner) {
OS << ErrorBanner;
ErrorInfo.log(OS);
OS << '\n';
};
}
namespace __sanitizer {
int internal_snprintf(char *buffer, uintptr_t length, const char *format,
...);
@ -57,8 +67,8 @@ bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset,
llvm::raw_string_ostream OS(Result);
llvm::symbolize::PrinterConfig Config = getDefaultPrinterConfig();
llvm::symbolize::Request Request{ModuleName, ModuleOffset};
auto Printer =
std::make_unique<llvm::symbolize::LLVMPrinter>(OS, OS, Config);
auto Printer = std::make_unique<llvm::symbolize::LLVMPrinter>(
OS, symbolize_error_handler(OS), Config);
// TODO: it is neccessary to set proper SectionIndex here.
// object::SectionedAddress::UndefSection works for only absolute addresses.
@ -86,8 +96,8 @@ bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset,
llvm::symbolize::PrinterConfig Config = getDefaultPrinterConfig();
llvm::raw_string_ostream OS(Result);
llvm::symbolize::Request Request{ModuleName, ModuleOffset};
auto Printer =
std::make_unique<llvm::symbolize::LLVMPrinter>(OS, OS, Config);
auto Printer = std::make_unique<llvm::symbolize::LLVMPrinter>(
OS, symbolize_error_handler(OS), Config);
// TODO: it is neccessary to set proper SectionIndex here.
// object::SectionedAddress::UndefSection works for only absolute addresses.

View File

@ -51,8 +51,7 @@ public:
StringRef Command) = 0;
virtual bool printError(const Request &Request,
const ErrorInfoBase &ErrorInfo,
StringRef ErrorBanner) = 0;
const ErrorInfoBase &ErrorInfo) = 0;
virtual void listBegin() = 0;
virtual void listEnd() = 0;
@ -66,10 +65,12 @@ struct PrinterConfig {
int SourceContextLines;
};
using ErrorHandler = function_ref<void(const ErrorInfoBase &, StringRef)>;
class PlainPrinterBase : public DIPrinter {
protected:
raw_ostream &OS;
raw_ostream &ES;
ErrorHandler ErrHandler;
PrinterConfig Config;
void print(const DILineInfo &Info, bool Inlined);
@ -85,8 +86,8 @@ private:
void printHeader(uint64_t Address);
public:
PlainPrinterBase(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
: OS(OS), ES(ES), Config(Config) {}
PlainPrinterBase(raw_ostream &OS, ErrorHandler EH, PrinterConfig &Config)
: OS(OS), ErrHandler(EH), Config(Config) {}
void print(const Request &Request, const DILineInfo &Info) override;
void print(const Request &Request, const DIInliningInfo &Info) override;
@ -96,8 +97,8 @@ public:
void printInvalidCommand(const Request &Request, StringRef Command) override;
bool printError(const Request &Request, const ErrorInfoBase &ErrorInfo,
StringRef ErrorBanner) override;
bool printError(const Request &Request,
const ErrorInfoBase &ErrorInfo) override;
void listBegin() override {}
void listEnd() override {}
@ -110,8 +111,8 @@ private:
void printFooter() override;
public:
LLVMPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
: PlainPrinterBase(OS, ES, Config) {}
LLVMPrinter(raw_ostream &OS, ErrorHandler EH, PrinterConfig &Config)
: PlainPrinterBase(OS, EH, Config) {}
};
class GNUPrinter : public PlainPrinterBase {
@ -119,8 +120,9 @@ private:
void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
public:
GNUPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
: PlainPrinterBase(OS, ES, Config) {}
GNUPrinter(raw_ostream &OS, ErrorHandler EH, PrinterConfig &Config)
: PlainPrinterBase(OS, EH, Config) {}
};
class JSONPrinter : public DIPrinter {
@ -147,8 +149,8 @@ public:
void printInvalidCommand(const Request &Request, StringRef Command) override;
bool printError(const Request &Request, const ErrorInfoBase &ErrorInfo,
StringRef ErrorBanner) override;
bool printError(const Request &Request,
const ErrorInfoBase &ErrorInfo) override;
void listBegin() override;
void listEnd() override;

View File

@ -266,11 +266,8 @@ void PlainPrinterBase::printInvalidCommand(const Request &Request,
}
bool PlainPrinterBase::printError(const Request &Request,
const ErrorInfoBase &ErrorInfo,
StringRef ErrorBanner) {
ES << ErrorBanner;
ErrorInfo.log(ES);
ES << '\n';
const ErrorInfoBase &ErrorInfo) {
ErrHandler(ErrorInfo, Request.ModuleName);
// Print an empty struct too.
return true;
}
@ -374,13 +371,11 @@ void JSONPrinter::printInvalidCommand(const Request &Request,
StringRef Command) {
printError(Request,
StringError("unable to parse arguments: " + Command,
std::make_error_code(std::errc::invalid_argument)),
"");
std::make_error_code(std::errc::invalid_argument)));
}
bool JSONPrinter::printError(const Request &Request,
const ErrorInfoBase &ErrorInfo,
StringRef ErrorBanner) {
const ErrorInfoBase &ErrorInfo) {
json::Object Json = toJSON(Request, ErrorInfo.message());
if (ObjectList)
ObjectList->push_back(std::move(Json));

View File

@ -632,8 +632,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(ArrayRef<uint8_t> BuildID) {
std::string Path;
if (!getOrFindDebugBinary(BuildID, Path)) {
return createStringError(errc::no_such_file_or_directory,
Twine("could not find build ID '") +
toHex(BuildID) + "'");
"could not find build ID");
}
return getOrCreateModuleInfo(Path);
}

View File

@ -49,7 +49,7 @@ Symbols:
# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: llvm-symbolizer --obj=%t2 0 0 2>&1 | FileCheck %s --check-prefix=CHECK2
# CHECK2: error reading file: st_name (0xffff) is past the end of the string table of size
# CHECK2: llvm-symbolizer{{.*}}: error: '{{.*}}symtab-file2.yaml.tmp2': st_name (0xffff) is past the end of the string table of size
# CHECK2-NEXT: ??
# CHECK2-NEXT: ??:0:0
# CHECK2-EMPTY:

View File

@ -1,3 +1,3 @@
RUN: llvm-symbolizer --obj=unexisting-file 0x1234 2>&1 | FileCheck -DMSG=%errc_ENOENT %s
CHECK: LLVMSymbolizer: error reading file: [[MSG]]
CHECK: llvm-symbolizer{{.*}}: error: 'unexisting-file': [[MSG]]

View File

@ -7,4 +7,4 @@ STDOUT: ??:0:0
STDOUT: ??
STDOUT: ??:0:0
STDERR-COUNT-2: LLVMSymbolizer: error reading file: could not find build ID 'ABAD'
STDERR-COUNT-2: llvm-symbolizer{{.*}}: error: 'ABAD': could not find build ID

View File

@ -37,13 +37,13 @@ RUN: | FileCheck %s --check-prefix=NOT-EXIST-GNU -DMSG=%errc_ENOENT
RUN: llvm-symbolizer --output-style=LLVM --obj=%p/Inputs/not.exist 0x1 0x2 --no-inlines 2>&1 \
RUN: | FileCheck %s --check-prefix=NOT-EXIST-LLVM -DMSG=%errc_ENOENT
# NOT-EXIST-GNU: LLVMSymbolizer: error reading file: [[MSG]]
# NOT-EXIST-GNU: llvm-symbolizer{{.*}}: error: '{{.*}}Inputs/not.exist': [[MSG]]
# NOT-EXIST-GNU-NEXT: ??
# NOT-EXIST-GNU-NEXT: ??:0
# NOT-EXIST-GNU-NEXT: ??
# NOT-EXIST-GNU-NEXT: ??:0
# NOT-EXIST-LLVM: LLVMSymbolizer: error reading file: [[MSG]]
# NOT-EXIST-LLVM: llvm-symbolizer{{.*}}: error: '{{.*}}Inputs/not.exist': [[MSG]]
# NOT-EXIST-LLVM-NEXT: ??
# NOT-EXIST-LLVM-NEXT: ??:0:0
# NOT-EXIST-LLVM-EMPTY:

View File

@ -4,7 +4,7 @@ RUN: FileCheck -DMSG=%errc_ENOENT --check-prefix=ERROR %s < %t.err
llvm-symbolizer should print one error and two unknown line info records.
ERROR: LLVMSymbolizer: error reading file: {{.*}}: [[MSG]]
ERROR: llvm-symbolizer{{.*}}: error: '{{.*}}missing_pdb.pdb': [[MSG]]
ERROR-NOT: error reading file
CHECK: ??

View File

@ -36,6 +36,7 @@
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdio>
@ -83,6 +84,16 @@ public:
};
} // namespace
static std::string ToolName;
static void printError(const ErrorInfoBase &EI, StringRef Path) {
WithColor::error(errs(), ToolName);
if (!EI.isA<FileError>())
errs() << "'" << Path << "': ";
EI.log(errs());
errs() << '\n';
}
template <typename T>
static void print(const Request &Request, Expected<T> &ResOrErr,
DIPrinter &Printer) {
@ -96,8 +107,7 @@ static void print(const Request &Request, Expected<T> &ResOrErr,
bool PrintEmpty = true;
handleAllErrors(std::move(ResOrErr.takeError()),
[&](const ErrorInfoBase &EI) {
PrintEmpty = Printer.printError(
Request, EI, "LLVMSymbolizer: error reading file: ");
PrintEmpty = Printer.printError(Request, EI);
});
if (PrintEmpty)
@ -378,7 +388,8 @@ int main(int argc, char **argv) {
InitLLVM X(argc, argv);
sys::InitializeCOMRAII COM(sys::COMThreadingMode::MultiThreaded);
bool IsAddr2Line = sys::path::stem(argv[0]).contains("addr2line");
ToolName = argv[0];
bool IsAddr2Line = sys::path::stem(ToolName).contains("addr2line");
BumpPtrAllocator A;
StringSaver Saver(A);
SymbolizerOptTable Tbl;
@ -461,11 +472,11 @@ int main(int argc, char **argv) {
std::unique_ptr<DIPrinter> Printer;
if (Style == OutputStyle::GNU)
Printer = std::make_unique<GNUPrinter>(outs(), errs(), Config);
Printer = std::make_unique<GNUPrinter>(outs(), printError, Config);
else if (Style == OutputStyle::JSON)
Printer = std::make_unique<JSONPrinter>(outs(), Config);
else
Printer = std::make_unique<LLVMPrinter>(outs(), errs(), Config);
Printer = std::make_unique<LLVMPrinter>(outs(), printError, Config);
std::vector<std::string> InputAddresses = Args.getAllArgValues(OPT_INPUT);
if (InputAddresses.empty()) {