[libcxx-commits] [libcxx] DRAFT [libc++][hardening] In production hardening modes, trap rather than abort (PR #78561)
Konstantin Varlamov via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 18 23:37:12 PST 2024
================
@@ -90,55 +124,187 @@ struct AssertionInfoMatcher {
std::size_t found_at = got_msg.find(msg_);
if (found_at == std::string_view::npos)
return false;
- return found_at == 0 && got_msg.size() == msg_.size();
+ // Allow any match
+ return true;
}
+
private:
- bool is_empty_;
+ bool is_empty_ = true;
+ ;
std::string_view msg_;
std::string_view file_;
int line_;
};
static constexpr AssertionInfoMatcher AnyMatcher(AssertionInfoMatcher::any_msg);
-inline AssertionInfoMatcher& GlobalMatcher() {
- static AssertionInfoMatcher GMatch;
- return GMatch;
+enum class DeathCause {
+ // Valid causes
+ VerboseAbort = 1,
+ StdTerminate,
+ Trap,
+ // Invalid causes
+ DidNotDie,
+ SetupFailure,
+ Unknown
+};
+
+bool IsValidCause(DeathCause cause) {
+ switch (cause) {
+ case DeathCause::VerboseAbort:
+ case DeathCause::StdTerminate:
+ case DeathCause::Trap:
+ return true;
+ default:
+ return false;
+ }
}
-struct DeathTest {
- enum ResultKind {
- RK_DidNotDie, RK_MatchFound, RK_MatchFailure, RK_Terminate, RK_SetupFailure, RK_Unknown
- };
+std::string ToString(DeathCause cause) {
+ switch (cause) {
+ case DeathCause::VerboseAbort:
+ return "verbose abort";
+ case DeathCause::StdTerminate:
+ return "`std::terminate`";
+ case DeathCause::Trap:
+ return "trap";
+ case DeathCause::DidNotDie:
+ return "<invalid cause (did not die)>";
+ case DeathCause::SetupFailure:
+ return "<invalid cause (setup failure)>";
+ case DeathCause::Unknown:
+ return "<invalid cause (unknown)>";
+ }
+}
- static const char* ResultKindToString(ResultKind RK) {
-#define CASE(K) case K: return #K
- switch (RK) {
- CASE(RK_MatchFailure);
- CASE(RK_DidNotDie);
- CASE(RK_SetupFailure);
- CASE(RK_MatchFound);
- CASE(RK_Unknown);
- CASE(RK_Terminate);
- }
- return "not a result kind";
+TEST_NORETURN void StopChildProcess(DeathCause cause) { std::exit(static_cast<int>(cause)); }
+
+DeathCause ConvertToDeathCause(int val) {
+ if (val < static_cast<int>(DeathCause::VerboseAbort) || val > static_cast<int>(DeathCause::Unknown)) {
+ return DeathCause::Unknown;
}
+ return static_cast<DeathCause>(val);
+}
+
+enum class Outcome {
+ Success,
+ UnexpectedCause,
+ UnexpectedAbortMessage,
+ InvalidCause,
+};
+
+std::string ToString(Outcome outcome) {
+ switch (outcome) {
+ case Outcome::Success:
+ return "success";
+ case Outcome::UnexpectedCause:
+ return "unexpected death cause";
+ case Outcome::UnexpectedAbortMessage:
+ return "unexpected verbose abort message";
+ case Outcome::InvalidCause:
+ return "invalid death cause";
+ }
+}
+
+class DeathTestResult {
+public:
+ DeathTestResult() = default;
+ DeathTestResult(Outcome set_outcome, DeathCause set_cause, const std::string& set_failure_description = "")
+ : outcome_(set_outcome), cause_(set_cause), failure_description_(set_failure_description) {}
+
+ bool success() const { return outcome() == Outcome::Success; }
+ Outcome outcome() const { return outcome_; }
+ DeathCause cause() const { return cause_; }
+ const std::string& failure_description() const { return failure_description_; }
+
+private:
+ Outcome outcome_ = Outcome::Success;
+ DeathCause cause_ = DeathCause::Unknown;
+ std::string failure_description_;
+};
+
+class DeathTest {
+public:
+ DeathTest() = default;
+ DeathTest(DeathTest const&) = delete;
+ DeathTest& operator=(DeathTest const&) = delete;
+
+ template <class Func>
+ DeathTestResult Run(DeathCause expected_cause, Func&& func, const AssertionInfoMatcher& matcher) {
+ std::set_terminate([] { StopChildProcess(DeathCause::StdTerminate); });
+
+ DeathCause cause = Run(func);
+
+ auto DescribeDeathCauseMismatch = [](DeathCause expected, DeathCause actual) {
+ std::stringstream output;
+ output //
+ << "Child died, but with a different death cause\n" //
+ << "Expected cause: " << ToString(expected) << "\n" //
+ << "Actual cause: " << ToString(actual) << "\n";
+ return output.str();
+ };
+
+ switch (cause) {
+ case DeathCause::StdTerminate:
----------------
var-const wrote:
I like this!
https://github.com/llvm/llvm-project/pull/78561
More information about the libcxx-commits
mailing list