Limit default maximum number of errors to 20.

This is in the context of https://llvm.org/bugs/show_bug.cgi?id=31109.
When LLD prints out errors for relocations, it tends to print out
extremely large number of errors (like millions) because it would
print out one error per relocation.

This patch makes LLD bail out if it prints out more than 20 errors.
You can configure the limitation using -error-limit argument.
-error-limit=0 means no limit.

I chose the flag name because Clang has the same feature as -ferror-limit.
"f" doesn't make sense to us, so I omitted it.

Differential Revision: https://reviews.llvm.org/D26981

llvm-svn: 287789
This commit is contained in:
Rui Ueyama 2016-11-23 18:15:37 +00:00
parent 28590b6118
commit ac95f6bfcc
6 changed files with 44 additions and 1 deletions

View File

@ -145,6 +145,7 @@ struct Configuration {
uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
uint16_t EMachine = llvm::ELF::EM_NONE;
uint64_t EntryAddr = 0;
uint64_t ErrorLimit;
uint64_t ImageBase;
uint64_t MaxPageSize;
uint64_t ZStackSize;

View File

@ -43,6 +43,7 @@ LinkerDriver *elf::Driver;
bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
raw_ostream &Error) {
HasError = false;
ErrorCount = 0;
ErrorOS = &Error;
Argv0 = Args[0];
@ -490,6 +491,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->Discard = getDiscardOption(Args);
Config->EhFrameHdr = Args.hasArg(OPT_eh_frame_hdr);
Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags);
Config->ErrorLimit = getInteger(Args, OPT_error_limit, 20);
Config->ExportDynamic = Args.hasArg(OPT_export_dynamic);
Config->FatalWarnings = Args.hasArg(OPT_fatal_warnings);
Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false);

View File

@ -24,6 +24,7 @@ using namespace llvm;
namespace lld {
bool elf::HasError;
uint64_t elf::ErrorCount;
raw_ostream *elf::ErrorOS;
StringRef elf::Argv0;
@ -40,8 +41,16 @@ void elf::warn(const Twine &Msg) {
}
void elf::error(const Twine &Msg) {
*ErrorOS << Argv0 << ": error: " << Msg << "\n";
if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
*ErrorOS << Argv0 << ": error: " << Msg << "\n";
} else if (ErrorCount == Config->ErrorLimit) {
*ErrorOS << Argv0 << ": error: too many errors emitted, stopping now\n";
if (Config->ExitEarly)
exitLld(1);
}
HasError = true;
++ErrorCount;
}
void elf::error(std::error_code EC, const Twine &Prefix) {

View File

@ -32,6 +32,7 @@ namespace lld {
namespace elf {
extern bool HasError;
extern uint64_t ErrorCount;
extern llvm::raw_ostream *ErrorOS;
extern llvm::StringRef Argv0;

View File

@ -68,6 +68,9 @@ def end_lib: F<"end-lib">,
def entry: S<"entry">, MetaVarName<"<entry>">,
HelpText<"Name of entry point symbol">;
def error_limit: S<"error-limit">,
HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">;
def export_dynamic: F<"export-dynamic">,
HelpText<"Put symbols in the dynamic symbol table">;
@ -240,6 +243,7 @@ def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>;
def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
def alias_entry_entry: J<"entry=">, Alias<entry>;
def alias_error_limit: J<"error-limit=">, Alias<error_limit>;
def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">,
Alias<export_dynamic_symbol>;

View File

@ -0,0 +1,26 @@
RUN: not ld.lld 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 \
RUN: 21 22 2>&1 | FileCheck -check-prefix=DEFAULT %s
DEFAULT: cannot open 01
DEFAULT: cannot open 20
DEFAULT-NEXT: too many errors emitted, stopping now
DEFAULT-NOT: cannot open 21
RUN: not ld.lld -error-limit=5 01 02 03 04 05 06 07 08 09 10 2>&1 \
RUN: | FileCheck -check-prefix=LIMIT5 %s
RUN: not ld.lld -error-limit 5 01 02 03 04 05 06 07 08 09 10 2>&1 \
RUN: | FileCheck -check-prefix=LIMIT5 %s
LIMIT5: cannot open 01
LIMIT5: cannot open 05
LIMIT5-NEXT: too many errors emitted, stopping now
LIMIT5-NOT: cannot open 06
RUN: not ld.lld -error-limit=0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \
RUN: 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=UNLIMITED %s
UNLIMITED: cannot open 01
UNLIMITED: cannot open 20
UNLIMITED: cannot open 21
UNLIMITED: cannot open 22
UNLIMITED-NOT: too many errors emitted, stopping now