Files
revng-revng/tests/pipeline/BadBehaviorLibrary.cpp
Alessandro Di Federico 5820908675 Remove and ban \file
2025-12-16 17:41:55 +01:00

66 lines
1.6 KiB
C++

/// This file, when compiled into a library, crashes in a manner configured in
/// the environment variables.
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include <cassert>
#include <csignal>
#include <cstdlib>
#include <iostream>
#include <string>
#include <string_view>
#include "llvm/ADT/StringRef.h"
#include "revng/Support/Assert.h"
// Ugly way to bypass the check-conventions check that enforces the usage of
// revng_abort(). We specifically don't want to use it in this case.
#define sneaky_abort abort
int *SomeGlobalPointerNobodyWillInitialize;
static void printAndFlush(llvm::StringRef String) {
std::cout << String.str() << std::endl;
std::cout.flush();
}
static void doCrash() {
const char *CEnv = std::getenv("REVNG_CRASH_SIGNAL");
if (CEnv == nullptr) {
// But would this be a bug or a feature?
revng_abort("$REVNG_CRASH_SIGNAL not set");
}
std::string Env(CEnv);
int Signal = std::stoi(Env);
switch (Signal) {
case SIGILL:
printAndFlush("SIGILL via illegal instruction");
asm(".byte 0x0f, 0x0b");
break;
case SIGABRT:
printAndFlush("SIGABRT via abort");
sneaky_abort();
case SIGSEGV:
printAndFlush("SIGSEGV via write to uninitialized pointer");
*SomeGlobalPointerNobodyWillInitialize = 69;
break;
default:
std::cout << "Signal " << Signal << " via raise()" << std::endl;
std::cout.flush();
std::raise(Signal);
break;
}
revng_abort("This shouldn't be executed");
}
class WillCrash {
public:
WillCrash() { doCrash(); }
};
static WillCrash WillCrashInstance;