Index: lld/Common/ErrorHandler.cpp =================================================================== --- lld/Common/ErrorHandler.cpp +++ lld/Common/ErrorHandler.cpp @@ -109,6 +109,8 @@ if (hasContext()) lld::errorHandler().flushStreams(); + if (::getenv("LLD_FORCE_CRASH")) + __builtin_trap(); // When running inside safeLldMain(), restore the control flow back to the // CrashRecoveryContext. Otherwise simply use _exit(), meanning no cleanup, // since we want to avoid further crashes on shutdown. Index: lld/test/ELF/force-crash.s =================================================================== --- /dev/null +++ lld/test/ELF/force-crash.s @@ -0,0 +1,7 @@ +RUN: not ld.lld 2>&1 | FileCheck %s +CHECK: error: no input files +CHECK-NOT: PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. + +RUN: LLD_FORCE_CRASH=1 not --crash ld.lld 2>&1 | FileCheck %s --check-prefix=CRASH +CRASH: error: no input files +CRASH: PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. Index: lld/tools/lld/lld.cpp =================================================================== --- lld/tools/lld/lld.cpp +++ lld/tools/lld/lld.cpp @@ -214,29 +214,34 @@ InitLLVM x(argc, argv); sys::Process::UseANSIEscapeCodes(true); - // Not running in lit tests, just take the shortest codepath with global - // exception handling and no memory cleanup on exit. - if (!inTestVerbosity()) - return lldMain(argc, argv, llvm::outs(), llvm::errs()); - - Optional mainRet; - CrashRecoveryContext::Enable(); - - for (unsigned i = inTestVerbosity(); i > 0; --i) { - // Disable stdout/stderr for all iterations but the last one. - inTestOutputDisabled = (i != 1); - - // Execute one iteration. - auto r = safeLldMain(argc, argv, llvm::outs(), llvm::errs()); - if (!r.canRunAgain) - exitLld(r.ret); // Exit now, can't re-execute again. - - if (!mainRet) { - mainRet = r.ret; - } else if (r.ret != *mainRet) { - // Exit now, to fail the tests if the result is different between runs. - return r.ret; + int ret = [argc, argv] { + // Not running in lit tests, just take the shortest codepath with global + // exception handling and no memory cleanup on exit. + if (!inTestVerbosity()) + return lldMain(argc, argv, llvm::outs(), llvm::errs()); + + Optional mainRet; + CrashRecoveryContext::Enable(); + + for (unsigned i = inTestVerbosity(); i > 0; --i) { + // Disable stdout/stderr for all iterations but the last one. + inTestOutputDisabled = (i != 1); + + // Execute one iteration. + auto r = safeLldMain(argc, argv, llvm::outs(), llvm::errs()); + if (!r.canRunAgain) + exitLld(r.ret); // Exit now, can't re-execute again. + + if (!mainRet) { + mainRet = r.ret; + } else if (r.ret != *mainRet) { + // Exit now, to fail the tests if the result is different between runs. + return r.ret; + } } - } - return *mainRet; + return *mainRet; + }(); + if (::getenv("LLD_FORCE_CRASH")) + __builtin_trap(); + return ret; }