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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // Usage: 9 // not cmd 10 // Will return true if cmd doesn't crash and returns false. 11 // not --crash cmd 12 // Will return true if cmd crashes (e.g. for testing crash reporting). 13 14 #include "llvm/Support/Program.h" 15 #include "llvm/Support/WithColor.h" 16 #include "llvm/Support/raw_ostream.h" 17 18 #ifdef _WIN32 19 #include <windows.h> 20 #endif 21 22 using namespace llvm; 23 24 int main(int argc, const char **argv) { 25 bool ExpectCrash = false; 26 27 ++argv; 28 --argc; 29 30 if (argc > 0 && StringRef(argv[0]) == "--crash") { 31 ++argv; 32 --argc; 33 ExpectCrash = true; 34 35 // Crash is expected, so disable crash report and symbolization to reduce 36 // output and avoid potentially slow symbolization. 37 #ifdef _WIN32 38 SetEnvironmentVariableA("LLVM_DISABLE_CRASH_REPORT", "1"); 39 SetEnvironmentVariableA("LLVM_DISABLE_SYMBOLIZATION", "1"); 40 #else 41 setenv("LLVM_DISABLE_CRASH_REPORT", "1", 0); 42 setenv("LLVM_DISABLE_SYMBOLIZATION", "1", 0); 43 #endif 44 } 45 46 if (argc == 0) 47 return 1; 48 49 auto Program = sys::findProgramByName(argv[0]); 50 if (!Program) { 51 WithColor::error() << "unable to find `" << argv[0] 52 << "' in PATH: " << Program.getError().message() << "\n"; 53 return 1; 54 } 55 56 std::vector<StringRef> Argv; 57 Argv.reserve(argc); 58 for (int i = 0; i < argc; ++i) 59 Argv.push_back(argv[i]); 60 std::string ErrMsg; 61 int Result = sys::ExecuteAndWait(*Program, Argv, None, {}, 0, 0, &ErrMsg); 62 #ifdef _WIN32 63 // Handle abort() in msvcrt -- It has exit code as 3. abort(), aka 64 // unreachable, should be recognized as a crash. However, some binaries use 65 // exit code 3 on non-crash failure paths, so only do this if we expect a 66 // crash. 67 if (ExpectCrash && Result == 3) 68 Result = -3; 69 #endif 70 if (Result < 0) { 71 WithColor::error() << ErrMsg << "\n"; 72 if (ExpectCrash) 73 return 0; 74 return 1; 75 } 76 77 if (ExpectCrash) 78 return 1; 79 80 return Result == 0; 81 } 82