-
Notifications
You must be signed in to change notification settings - Fork 409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
*: improve RUNTIME_CHECK and RUNTIME_ASSERT #5434
Merged
Merged
Changes from 9 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
aa5da11
update
fuzhe1989 10b20d5
Merge branch 'master' into fuzhe/runtime_check
fuzhe1989 0542517
Merge branch 'master' into fuzhe/runtime_check
JaySon-Huang 791f343
Update Exception.h
fuzhe1989 cbcf5a4
Merge branch 'master' into fuzhe/runtime_check
SeaRise 21f84b2
Merge branch 'master' into fuzhe/runtime_check
fuzhe1989 2b49ec4
update
fuzhe1989 831314f
update
fuzhe1989 02c3824
update
fuzhe1989 709cd71
update
fuzhe1989 3420729
Merge branch 'master' into fuzhe/runtime_check
ti-chi-bot cbe91ab
Merge branch 'master' into fuzhe/runtime_check
ti-chi-bot d3bc80d
Merge branch 'master' into fuzhe/runtime_check
ti-chi-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,26 +14,17 @@ | |
|
||
#pragma once | ||
|
||
#include <Common/Logger.h> | ||
#include <Common/StackTrace.h> | ||
#include <Poco/Exception.h> | ||
#include <fmt/format.h> | ||
#include <common/defines.h> | ||
|
||
#include <cerrno> | ||
#include <memory> | ||
#include <vector> | ||
|
||
|
||
namespace Poco | ||
{ | ||
class Logger; | ||
} | ||
|
||
|
||
namespace DB | ||
{ | ||
class Logger; | ||
using LoggerPtr = std::shared_ptr<Logger>; | ||
|
||
class Exception : public Poco::Exception | ||
{ | ||
public: | ||
|
@@ -73,8 +64,8 @@ class Exception : public Poco::Exception | |
StackTrace trace; | ||
}; | ||
|
||
|
||
/// Contains an additional member `saved_errno`. See the throwFromErrno function. | ||
/// Contains an additional member `saved_errno`. See the throwFromErrno | ||
/// function. | ||
class ErrnoException : public Exception | ||
{ | ||
public: | ||
|
@@ -97,46 +88,48 @@ class ErrnoException : public Exception | |
int saved_errno; | ||
}; | ||
|
||
|
||
using Exceptions = std::vector<std::exception_ptr>; | ||
|
||
|
||
[[noreturn]] void throwFromErrno(const std::string & s, int code = 0, int e = errno); | ||
|
||
|
||
/** Try to write an exception to the log (and forget about it). | ||
* Can be used in destructors in the catch-all block. | ||
*/ | ||
void tryLogCurrentException(const char * log_name, const std::string & start_of_message = ""); | ||
void tryLogCurrentException(const LoggerPtr & logger, const std::string & start_of_message = ""); | ||
void tryLogCurrentException(Poco::Logger * logger, const std::string & start_of_message = ""); | ||
|
||
* Can be used in destructors in the catch-all block. | ||
*/ | ||
void tryLogCurrentException(const char * log_name, | ||
const std::string & start_of_message = ""); | ||
void tryLogCurrentException(const LoggerPtr & logger, | ||
const std::string & start_of_message = ""); | ||
void tryLogCurrentException(Poco::Logger * logger, | ||
const std::string & start_of_message = ""); | ||
|
||
/** Prints current exception in canonical format. | ||
* with_stacktrace - prints stack trace for DB::Exception. | ||
* check_embedded_stacktrace - if DB::Exception has embedded stacktrace then | ||
* only this stack trace will be printed. | ||
*/ | ||
std::string getCurrentExceptionMessage(bool with_stacktrace, bool check_embedded_stacktrace = false); | ||
* with_stacktrace - prints stack trace for DB::Exception. | ||
* check_embedded_stacktrace - if DB::Exception has embedded stacktrace then | ||
* only this stack trace will be printed. | ||
*/ | ||
std::string getCurrentExceptionMessage(bool with_stacktrace, | ||
bool check_embedded_stacktrace = false); | ||
|
||
/// Returns error code from ErrorCodes | ||
int getCurrentExceptionCode(); | ||
|
||
|
||
/// An execution status of any piece of code, contains return code and optional error | ||
/// An execution status of any piece of code, contains return code and optional | ||
/// error | ||
struct ExecutionStatus | ||
{ | ||
int code = 0; | ||
std::string message; | ||
|
||
ExecutionStatus() = default; | ||
|
||
explicit ExecutionStatus(int return_code, const std::string & exception_message = "") | ||
explicit ExecutionStatus(int return_code, | ||
const std::string & exception_message = "") | ||
: code(return_code) | ||
, message(exception_message) | ||
{} | ||
|
||
static ExecutionStatus fromCurrentException(const std::string & start_of_message = ""); | ||
static ExecutionStatus | ||
fromCurrentException(const std::string & start_of_message = ""); | ||
|
||
std::string serializeText() const; | ||
|
||
|
@@ -145,14 +138,11 @@ struct ExecutionStatus | |
bool tryDeserializeText(const std::string & data); | ||
}; | ||
|
||
|
||
std::string getExceptionMessage(const Exception & e, bool with_stacktrace, bool check_embedded_stacktrace = false); | ||
std::string getExceptionMessage(std::exception_ptr e, bool with_stacktrace); | ||
|
||
|
||
void rethrowFirstException(const Exceptions & exceptions); | ||
|
||
|
||
template <typename T> | ||
std::enable_if_t<std::is_pointer_v<T>, T> exception_cast(std::exception_ptr e) | ||
{ | ||
|
@@ -172,28 +162,98 @@ std::enable_if_t<std::is_pointer_v<T>, T> exception_cast(std::exception_ptr e) | |
|
||
namespace exception_details | ||
{ | ||
inline std::string generateFormattedMessage(const char * condition) | ||
{ | ||
return fmt::format("Assert {} fail!", condition); | ||
} | ||
|
||
template <typename T, typename... Args> | ||
inline std::string generateLogMessage(const char * condition, T && fmt_str, Args &&... args) | ||
inline std::string generateFormattedMessage(const char * condition, T && fmt_str, Args &&... args) | ||
{ | ||
return FmtBuffer().fmtAppend("Assert {} fail! ", condition).fmtAppend(fmt_str, std::forward<Args>(args)...).toString(); | ||
} | ||
|
||
template <typename... Args> | ||
inline Poco::Message generateLogMessage(const std::string & logger_name, const char * filename, int lineno, const char * condition, Args &&... args) | ||
{ | ||
return Poco::Message( | ||
logger_name, | ||
generateFormattedMessage(condition, std::forward<Args>(args)...), | ||
Poco::Message::PRIO_FATAL, | ||
filename, | ||
lineno); | ||
} | ||
|
||
const LoggerPtr & getDefaultFatalLogger(); | ||
|
||
inline void log(const char * filename, int lineno, const char * condition, const LoggerPtr & logger) | ||
{ | ||
if (likely(logger->fatal())) | ||
{ | ||
auto message = generateLogMessage(logger->name(), filename, lineno, condition); | ||
logger->log(message); | ||
} | ||
} | ||
|
||
inline void log(const char * filename, int lineno, const char * condition) | ||
{ | ||
log(filename, lineno, condition, getDefaultFatalLogger()); | ||
} | ||
|
||
template <typename... Args> | ||
inline void log(const char * filename, int lineno, const char * condition, const LoggerPtr & logger, const char * fmt_str, Args &&... args) | ||
{ | ||
if (logger->fatal()) | ||
{ | ||
auto message = generateLogMessage( | ||
logger->name(), | ||
filename, | ||
lineno, | ||
condition, | ||
fmt_str, | ||
std::forward<Args>(args)...); | ||
logger->log(message); | ||
} | ||
} | ||
|
||
template <typename... Args> | ||
inline void log(const char * filename, int lineno, const char * condition, const char * fmt_str, Args &&... args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this |
||
{ | ||
return fmt::format(std::forward<T>(fmt_str), condition, std::forward<Args>(args)...); | ||
log(filename, lineno, condition, getDefaultFatalLogger(), fmt_str, std::forward<Args>(args)...); | ||
} | ||
} // namespace exception_details | ||
|
||
#define RUNTIME_CHECK(condition, ExceptionType, ...) \ | ||
do \ | ||
{ \ | ||
if (unlikely(!(condition))) \ | ||
throw ExceptionType(__VA_ARGS__); \ | ||
/// Usage: | ||
/// ``` | ||
/// RUNTIME_CHECK(a != b, Exception("{} does not equal to {}", a, b)); | ||
/// ``` | ||
#define RUNTIME_CHECK(condition, ExceptionGenerationCode) \ | ||
do \ | ||
{ \ | ||
if (unlikely(!(condition))) \ | ||
throw(ExceptionGenerationCode); \ | ||
} while (false) | ||
|
||
#define RUNTIME_ASSERT(condition, logger, ...) \ | ||
do \ | ||
{ \ | ||
if (unlikely(!(condition))) \ | ||
{ \ | ||
LOG_FATAL((logger), exception_details::generateLogMessage(#condition, "Assert {} fail! " __VA_ARGS__)); \ | ||
std::terminate(); \ | ||
} \ | ||
/// Usage: | ||
/// ``` | ||
/// RUNTIME_ASSERT(a != b); | ||
/// RUNTIME_ASSERT(a != b, "fail"); | ||
/// RUNTIME_ASSERT(a != b, "{} does not equal to {}", a, b); | ||
/// RUNTIME_ASSERT(a != b, logger); | ||
/// RUNTIME_ASSERT(a != b, logger, "{} does not equal to {}", a, b); | ||
/// ``` | ||
#define RUNTIME_ASSERT(condition, ...) \ | ||
do \ | ||
{ \ | ||
if (unlikely(!(condition))) \ | ||
{ \ | ||
exception_details::log( \ | ||
&__FILE__[LogFmtDetails::getFileNameOffset(__FILE__)], \ | ||
__LINE__, \ | ||
#condition, \ | ||
##__VA_ARGS__); \ | ||
std::terminate(); \ | ||
} \ | ||
} while (false) | ||
|
||
} // namespace DB |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about removing
const char * fmt_str
?If so,
inline void log(const char * filename, int lineno, const char * condition, const LoggerPtr & logger)
can be removed too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done