84 lines · cpp
1//===- not.cpp - The 'not' testing tool -----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// Usage:9// not cmd10// Will return true if cmd doesn't crash and returns false.11// not --crash cmd12// Will return true if cmd crashes (e.g. for testing crash reporting).13 14#include "llvm/Support/Process.h"15#include "llvm/Support/Program.h"16#include "llvm/Support/WithColor.h"17#include "llvm/Support/raw_ostream.h"18 19#ifdef _WIN3220#include <windows.h>21#endif22 23using namespace llvm;24 25int main(int argc, const char **argv) {26 bool ExpectCrash = false;27 28 ++argv;29 --argc;30 31 if (argc > 0 && StringRef(argv[0]) == "--crash") {32 ++argv;33 --argc;34 ExpectCrash = true;35 36 // Crash is expected, so disable crash report and symbolization to reduce37 // output and avoid potentially slow symbolization.38#ifdef _WIN3239 SetEnvironmentVariableA("LLVM_DISABLE_CRASH_REPORT", "1");40 SetEnvironmentVariableA("LLVM_DISABLE_SYMBOLIZATION", "1");41#else42 setenv("LLVM_DISABLE_CRASH_REPORT", "1", 0);43 setenv("LLVM_DISABLE_SYMBOLIZATION", "1", 0);44#endif45 // Try to disable coredumps for expected crashes as well since this can46 // noticeably slow down running the test suite.47 sys::Process::PreventCoreFiles();48 }49 50 if (argc == 0)51 return 1;52 53 auto Program = sys::findProgramByName(argv[0]);54 if (!Program) {55 WithColor::error() << "unable to find `" << argv[0]56 << "' in PATH: " << Program.getError().message() << "\n";57 return 1;58 }59 60 SmallVector<StringRef> Argv(ArrayRef(argv, argc));61 std::string ErrMsg;62 int Result =63 sys::ExecuteAndWait(*Program, Argv, std::nullopt, {}, 0, 0, &ErrMsg);64#ifdef _WIN3265 // Handle abort() in msvcrt -- It has exit code as 3. abort(), aka66 // unreachable, should be recognized as a crash. However, some binaries use67 // exit code 3 on non-crash failure paths, so only do this if we expect a68 // crash.69 if (ExpectCrash && Result == 3)70 Result = -3;71#endif72 if (Result < 0) {73 WithColor::error() << ErrMsg << "\n";74 if (ExpectCrash)75 return 0;76 return 1;77 }78 79 if (ExpectCrash)80 return 1;81 82 return Result == 0;83}84