mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
e07f8bd7b6
Summary: This splits `EDEN_BUG()` into three separate version. All three crash in debug mode builds, but in release builds they behave differently: - `EDEN_BUG()` throws an exception - `EDEN_BUG_FUTURE(Type)` returns a `folly::Future<Type>` that has been fulfilled with an exception. - `EDEN_BUG_EXCEPTION()` returns a `folly::exception_wrapper`. The main advantage of this is that this allows the compiler to detect that `EDEN_BUG()` can never return. Previously `EDEN_BUG()` was used for all 3 of these different cases, and its behavior depended on whether `toException()` was ever called. As a result we could not easily get the compiler to identify code paths where we know at compile time that it will never return. Reviewed By: chadaustin Differential Revision: D18652103 fbshipit-source-id: 070107c7520f51b05696905fa243de5f8df15958
67 lines
1.5 KiB
C++
67 lines
1.5 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#include "eden/fs/utils/Bug.h"
|
|
|
|
#include <folly/Conv.h>
|
|
#include <folly/ExceptionWrapper.h>
|
|
#include <folly/logging/xlog.h>
|
|
|
|
namespace {
|
|
static std::atomic<int> edenBugDisabledCount{0};
|
|
}
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
EdenBug::EdenBug(const char* file, int lineNumber)
|
|
: file_(file), lineNumber_(lineNumber), message_("!!BUG!! ") {}
|
|
|
|
EdenBug::EdenBug(EdenBug&& other) noexcept
|
|
: file_(other.file_),
|
|
lineNumber_(other.lineNumber_),
|
|
message_(std::move(other.message_)) {
|
|
other.processed_ = true;
|
|
}
|
|
|
|
EdenBug::~EdenBug() {
|
|
XCHECK(processed_);
|
|
}
|
|
|
|
folly::exception_wrapper EdenBug::toException() {
|
|
logError();
|
|
processed_ = true;
|
|
return folly::exception_wrapper(std::runtime_error(message_));
|
|
}
|
|
|
|
void EdenBug::throwException() {
|
|
toException().throw_exception();
|
|
}
|
|
|
|
void EdenBug::logError() {
|
|
XLOG(CRITICAL) << "EDEN_BUG at " << file_ << ":" << lineNumber_ << ": "
|
|
<< message_;
|
|
|
|
#ifndef NDEBUG
|
|
// Crash in debug builds.
|
|
// However, allow test code to disable crashing so that we can exercise
|
|
// EDEN_BUG() code paths in tests.
|
|
if (edenBugDisabledCount.load() == 0) {
|
|
XLOG(FATAL) << "crashing due to EDEN_BUG";
|
|
}
|
|
#endif
|
|
}
|
|
|
|
EdenBugDisabler::EdenBugDisabler() {
|
|
++edenBugDisabledCount;
|
|
}
|
|
|
|
EdenBugDisabler::~EdenBugDisabler() {
|
|
--edenBugDisabledCount;
|
|
}
|
|
} // namespace eden
|
|
} // namespace facebook
|