Take failure_message as const char* instead of string_view in LogMessageFatal and friends. This saves an instruction at every callsite and costs at most one strlen per process. Okay, maybe a couple if two threads crash at once... https://godbolt.org/z/vsqd35YaM PiperOrigin-RevId: 698522200 Change-Id: I77735f0d650b029ca4b3e02b4f8027dfe0f3de4c
diff --git a/absl/log/CMakeLists.txt b/absl/log/CMakeLists.txt index fb17149..56e2626 100644 --- a/absl/log/CMakeLists.txt +++ b/absl/log/CMakeLists.txt
@@ -46,6 +46,7 @@ DEPS absl::config absl::core_headers + absl::leak_check absl::log_internal_nullguard absl::log_internal_nullstream absl::log_internal_strip
diff --git a/absl/log/internal/BUILD.bazel b/absl/log/internal/BUILD.bazel index 982fffb..fef7f27 100644 --- a/absl/log/internal/BUILD.bazel +++ b/absl/log/internal/BUILD.bazel
@@ -64,6 +64,7 @@ "//absl/base:config", "//absl/base:core_headers", "//absl/base:nullability", + "//absl/debugging:leak_check", "//absl/strings", ], )
diff --git a/absl/log/internal/check_op.cc b/absl/log/internal/check_op.cc index 23c4a3b..cec9421 100644 --- a/absl/log/internal/check_op.cc +++ b/absl/log/internal/check_op.cc
@@ -14,10 +14,15 @@ #include "absl/log/internal/check_op.h" -#include <string.h> - +#include <cstring> #include <ostream> +#include <string> +#include <utility> +#include "absl/base/config.h" +#include "absl/base/nullability.h" +#include "absl/debugging/leak_check.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #ifdef _MSC_VER @@ -26,18 +31,13 @@ #include <strings.h> // for strcasecmp, but msvc does not have this header #endif -#include <sstream> -#include <string> - -#include "absl/base/config.h" -#include "absl/strings/str_cat.h" - namespace absl { ABSL_NAMESPACE_BEGIN namespace log_internal { #define ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(x) \ - template std::string* MakeCheckOpString(x, x, const char*) + template absl::Nonnull<const char*> MakeCheckOpString( \ + x, x, absl::Nonnull<const char*>) ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(bool); ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(int64_t); ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(uint64_t); @@ -53,7 +53,8 @@ ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const void*); #undef ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING -CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext) { +CheckOpMessageBuilder::CheckOpMessageBuilder( + absl::Nonnull<const char*> exprtext) { stream_ << exprtext << " ("; } @@ -62,9 +63,10 @@ return stream_; } -std::string* CheckOpMessageBuilder::NewString() { +absl::Nonnull<const char*> CheckOpMessageBuilder::NewString() { stream_ << ")"; - return new std::string(stream_.str()); + // There's no need to free this string since the process is crashing. + return absl::IgnoreLeak(new std::string(std::move(stream_).str()))->c_str(); } void MakeCheckOpValueString(std::ostream& os, const char v) { @@ -100,16 +102,19 @@ } // Helper functions for string comparisons. -#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ - std::string* Check##func##expected##Impl(const char* s1, const char* s2, \ - const char* exprtext) { \ - bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ - if (equal == expected) { \ - return nullptr; \ - } else { \ - return new std::string( \ - absl::StrCat(exprtext, " (", s1, " vs. ", s2, ")")); \ - } \ +#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ + absl::Nullable<const char*> Check##func##expected##Impl( \ + absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, \ + absl::Nonnull<const char*> exprtext) { \ + bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ + if (equal == expected) { \ + return nullptr; \ + } else { \ + /* There's no need to free this string since the process is crashing. */ \ + return absl::IgnoreLeak(new std::string(absl::StrCat(exprtext, " (", s1, \ + " vs. ", s2, ")"))) \ + ->c_str(); \ + } \ } DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
diff --git a/absl/log/internal/check_op.h b/absl/log/internal/check_op.h index 98b6c5a..8cf72b2 100644 --- a/absl/log/internal/check_op.h +++ b/absl/log/internal/check_op.h
@@ -63,7 +63,7 @@ #endif #define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \ - while (::std::string* absl_log_internal_check_op_result \ + while (absl::Nullable<const char*> absl_log_internal_check_op_result \ ABSL_LOG_INTERNAL_ATTRIBUTE_UNUSED_IF_STRIP_LOG = \ ::absl::log_internal::name##Impl( \ ::absl::log_internal::GetReferenceableValue(val1), \ @@ -71,36 +71,35 @@ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \ val1_text " " #op " " val2_text))) \ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \ - ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_op_result).InternalStream() -#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \ - val2_text) \ - while (::std::string* absl_log_internal_qcheck_op_result = \ - ::absl::log_internal::name##Impl( \ - ::absl::log_internal::GetReferenceableValue(val1), \ - ::absl::log_internal::GetReferenceableValue(val2), \ - ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \ - val1_text " " #op " " val2_text))) \ - ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \ - ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_op_result).InternalStream() + ABSL_LOG_INTERNAL_CHECK(absl_log_internal_check_op_result).InternalStream() +#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \ + val2_text) \ + while (absl::Nullable<const char*> absl_log_internal_qcheck_op_result = \ + ::absl::log_internal::name##Impl( \ + ::absl::log_internal::GetReferenceableValue(val1), \ + ::absl::log_internal::GetReferenceableValue(val2), \ + ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \ + val1_text " " #op " " val2_text))) \ + ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \ + ABSL_LOG_INTERNAL_QCHECK(absl_log_internal_qcheck_op_result).InternalStream() #define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \ s2_text) \ - while (::std::string* absl_log_internal_check_strop_result = \ + while (absl::Nullable<const char*> absl_log_internal_check_strop_result = \ ::absl::log_internal::Check##func##expected##Impl( \ (s1), (s2), \ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \ " " s2_text))) \ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \ - ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_strop_result) \ - .InternalStream() + ABSL_LOG_INTERNAL_CHECK(absl_log_internal_check_strop_result).InternalStream() #define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \ s2_text) \ - while (::std::string* absl_log_internal_qcheck_strop_result = \ + while (absl::Nullable<const char*> absl_log_internal_qcheck_strop_result = \ ::absl::log_internal::Check##func##expected##Impl( \ (s1), (s2), \ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \ " " s2_text))) \ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \ - ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_strop_result) \ + ABSL_LOG_INTERNAL_QCHECK(absl_log_internal_qcheck_strop_result) \ .InternalStream() // This one is tricky: // * We must evaluate `val` exactly once, yet we need to do two things with it: @@ -127,7 +126,8 @@ // strip the call to stringify the non-ok `Status` as long as we don't log it; // dropping the `Status`'s message text is out of scope. #define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text) \ - for (::std::pair<const ::absl::Status*, ::std::string*> \ + for (::std::pair<absl::Nonnull<const ::absl::Status*>, \ + absl::Nullable<const char*>> \ absl_log_internal_check_ok_goo; \ absl_log_internal_check_ok_goo.first = \ ::absl::log_internal::AsStatus(val), \ @@ -140,10 +140,11 @@ " is OK")), \ !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \ - ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_ok_goo.second) \ + ABSL_LOG_INTERNAL_CHECK(absl_log_internal_check_ok_goo.second) \ .InternalStream() #define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) \ - for (::std::pair<const ::absl::Status*, ::std::string*> \ + for (::std::pair<absl::Nonnull<const ::absl::Status*>, \ + absl::Nullable<const char*>> \ absl_log_internal_qcheck_ok_goo; \ absl_log_internal_qcheck_ok_goo.first = \ ::absl::log_internal::AsStatus(val), \ @@ -156,7 +157,7 @@ " is OK")), \ !ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok());) \ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \ - ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_ok_goo.second) \ + ABSL_LOG_INTERNAL_QCHECK(absl_log_internal_qcheck_ok_goo.second) \ .InternalStream() namespace absl { @@ -167,7 +168,7 @@ class StatusOr; namespace status_internal { -ABSL_ATTRIBUTE_PURE_FUNCTION absl::Nonnull<std::string*> MakeCheckFailString( +ABSL_ATTRIBUTE_PURE_FUNCTION absl::Nonnull<const char*> MakeCheckFailString( absl::Nonnull<const absl::Status*> status, absl::Nonnull<const char*> prefix); } // namespace status_internal @@ -177,9 +178,11 @@ // Convert a Status or a StatusOr to its underlying status value. // // (This implementation does not require a dep on absl::Status to work.) -inline const absl::Status* AsStatus(const absl::Status& s) { return &s; } +inline absl::Nonnull<const absl::Status*> AsStatus(const absl::Status& s) { + return &s; +} template <typename T> -const absl::Status* AsStatus(const absl::StatusOr<T>& s) { +absl::Nonnull<const absl::Status*> AsStatus(const absl::StatusOr<T>& s) { return &s.status(); } @@ -188,14 +191,14 @@ class CheckOpMessageBuilder final { public: // Inserts `exprtext` and ` (` to the stream. - explicit CheckOpMessageBuilder(const char* exprtext); + explicit CheckOpMessageBuilder(absl::Nonnull<const char*> exprtext); ~CheckOpMessageBuilder() = default; // For inserting the first variable. std::ostream& ForVar1() { return stream_; } // For inserting the second variable (adds an intermediate ` vs. `). std::ostream& ForVar2(); // Get the result (inserts the closing `)`). - std::string* NewString(); + absl::Nonnull<const char*> NewString(); private: std::ostringstream stream_; @@ -338,11 +341,12 @@ // Build the error message string. Specify no inlining for code size. template <typename T1, typename T2> -ABSL_ATTRIBUTE_RETURNS_NONNULL std::string* MakeCheckOpString( - T1 v1, T2 v2, const char* exprtext) ABSL_ATTRIBUTE_NOINLINE; +ABSL_ATTRIBUTE_RETURNS_NONNULL absl::Nonnull<const char*> MakeCheckOpString( + T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) ABSL_ATTRIBUTE_NOINLINE; template <typename T1, typename T2> -std::string* MakeCheckOpString(T1 v1, T2 v2, const char* exprtext) { +absl::Nonnull<const char*> MakeCheckOpString( + T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) { CheckOpMessageBuilder comb(exprtext); MakeCheckOpValueString(comb.ForVar1(), v1); MakeCheckOpValueString(comb.ForVar2(), v2); @@ -352,7 +356,8 @@ // Add a few commonly used instantiations as extern to reduce size of objects // files. #define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(x) \ - extern template std::string* MakeCheckOpString(x, x, const char*) + extern template absl::Nonnull<const char*> MakeCheckOpString( \ + x, x, absl::Nonnull<const char*>) ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(bool); ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(int64_t); ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(uint64_t); @@ -376,7 +381,7 @@ ((::absl::LogSeverity::kFatal >= \ static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL)) \ ? MakeCheckOpString<U1, U2>(v1, v2, exprtext) \ - : new std::string()) + : "") #else #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \ MakeCheckOpString<U1, U2>(v1, v2, exprtext) @@ -388,8 +393,8 @@ // type. #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL(name, op) \ template <typename T1, typename T2> \ - inline constexpr ::std::string* name##Impl(const T1& v1, const T2& v2, \ - const char* exprtext) { \ + inline constexpr absl::Nullable<const char*> name##Impl( \ + const T1& v1, const T2& v2, absl::Nonnull<const char*> exprtext) { \ using U1 = CheckOpStreamType<T1>; \ using U2 = CheckOpStreamType<T2>; \ return ABSL_PREDICT_TRUE(v1 op v2) \ @@ -397,8 +402,8 @@ : ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, U1(v1), \ U2(v2), exprtext); \ } \ - inline constexpr ::std::string* name##Impl(int v1, int v2, \ - const char* exprtext) { \ + inline constexpr absl::Nullable<const char*> name##Impl( \ + int v1, int v2, absl::Nonnull<const char*> exprtext) { \ return name##Impl<int, int>(v1, v2, exprtext); \ } @@ -411,14 +416,18 @@ #undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT #undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL -std::string* CheckstrcmptrueImpl(const char* s1, const char* s2, - const char* exprtext); -std::string* CheckstrcmpfalseImpl(const char* s1, const char* s2, - const char* exprtext); -std::string* CheckstrcasecmptrueImpl(const char* s1, const char* s2, - const char* exprtext); -std::string* CheckstrcasecmpfalseImpl(const char* s1, const char* s2, - const char* exprtext); +absl::Nullable<const char*> CheckstrcmptrueImpl( + absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, + absl::Nonnull<const char*> exprtext); +absl::Nullable<const char*> CheckstrcmpfalseImpl( + absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, + absl::Nonnull<const char*> exprtext); +absl::Nullable<const char*> CheckstrcasecmptrueImpl( + absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, + absl::Nonnull<const char*> exprtext); +absl::Nullable<const char*> CheckstrcasecmpfalseImpl( + absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, + absl::Nonnull<const char*> exprtext); // `CHECK_EQ` and friends want to pass their arguments by reference, however // this winds up exposing lots of cases where people have defined and @@ -426,6 +435,8 @@ // file), meaning they are not referenceable. This function avoids that problem // for integers (the most common cases) by overloading for every primitive // integer type, even the ones we discourage, and returning them by value. +// NOLINTBEGIN(runtime/int) +// NOLINTBEGIN(google-runtime-int) template <typename T> inline constexpr const T& GetReferenceableValue(const T& t) { return t; @@ -435,27 +446,25 @@ return t; } inline constexpr signed char GetReferenceableValue(signed char t) { return t; } -inline constexpr short GetReferenceableValue(short t) { return t; } // NOLINT -inline constexpr unsigned short GetReferenceableValue( // NOLINT - unsigned short t) { // NOLINT +inline constexpr short GetReferenceableValue(short t) { return t; } +inline constexpr unsigned short GetReferenceableValue(unsigned short t) { return t; } inline constexpr int GetReferenceableValue(int t) { return t; } inline constexpr unsigned int GetReferenceableValue(unsigned int t) { return t; } -inline constexpr long GetReferenceableValue(long t) { return t; } // NOLINT -inline constexpr unsigned long GetReferenceableValue( // NOLINT - unsigned long t) { // NOLINT +inline constexpr long GetReferenceableValue(long t) { return t; } +inline constexpr unsigned long GetReferenceableValue(unsigned long t) { return t; } -inline constexpr long long GetReferenceableValue(long long t) { // NOLINT +inline constexpr long long GetReferenceableValue(long long t) { return t; } +inline constexpr unsigned long long GetReferenceableValue( + unsigned long long t) { return t; } -inline constexpr unsigned long long GetReferenceableValue( // NOLINT - unsigned long long t) { // NOLINT - return t; -} +// NOLINTEND(google-runtime-int) +// NOLINTEND(runtime/int) } // namespace log_internal ABSL_NAMESPACE_END
diff --git a/absl/log/internal/log_message.cc b/absl/log/internal/log_message.cc index 402883a..51961fd 100644 --- a/absl/log/internal/log_message.cc +++ b/absl/log/internal/log_message.cc
@@ -39,6 +39,7 @@ #include "absl/base/internal/strerror.h" #include "absl/base/internal/sysinfo.h" #include "absl/base/log_severity.h" +#include "absl/base/nullability.h" #include "absl/container/inlined_vector.h" #include "absl/debugging/internal/examine_stack.h" #include "absl/log/globals.h" @@ -145,8 +146,8 @@ } // namespace struct LogMessage::LogMessageData final { - LogMessageData(const char* file, int line, absl::LogSeverity severity, - absl::Time timestamp); + LogMessageData(absl::Nonnull<const char*> file, int line, + absl::LogSeverity severity, absl::Time timestamp); LogMessageData(const LogMessageData&) = delete; LogMessageData& operator=(const LogMessageData&) = delete; @@ -161,7 +162,7 @@ bool is_perror; // Extra `LogSink`s to log to, in addition to `global_sinks`. - absl::InlinedVector<absl::LogSink*, 16> extra_sinks; + absl::InlinedVector<absl::Nonnull<absl::LogSink*>, 16> extra_sinks; // If true, log to `extra_sinks` but not to `global_sinks` or hardcoded // non-sink targets (e.g. stderr, log files). bool extra_sinks_only; @@ -197,8 +198,8 @@ void FinalizeEncodingAndFormat(); }; -LogMessage::LogMessageData::LogMessageData(const char* file, int line, - absl::LogSeverity severity, +LogMessage::LogMessageData::LogMessageData(absl::Nonnull<const char*> file, + int line, absl::LogSeverity severity, absl::Time timestamp) : extra_sinks_only(false), manipulated(nullptr) { // Legacy defaults for LOG's ostream: @@ -268,7 +269,8 @@ absl::MakeSpan(string_buf).subspan(0, chars_written); } -LogMessage::LogMessage(const char* file, int line, absl::LogSeverity severity) +LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, + absl::LogSeverity severity) : data_(absl::make_unique<LogMessageData>(file, line, severity, absl::Now())) { data_->first_fatal = false; @@ -281,11 +283,11 @@ LogBacktraceIfNeeded(); } -LogMessage::LogMessage(const char* file, int line, InfoTag) +LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, InfoTag) : LogMessage(file, line, absl::LogSeverity::kInfo) {} -LogMessage::LogMessage(const char* file, int line, WarningTag) +LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, WarningTag) : LogMessage(file, line, absl::LogSeverity::kWarning) {} -LogMessage::LogMessage(const char* file, int line, ErrorTag) +LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, ErrorTag) : LogMessage(file, line, absl::LogSeverity::kError) {} LogMessage::~LogMessage() { @@ -348,13 +350,13 @@ return *this; } -LogMessage& LogMessage::ToSinkAlso(absl::LogSink* sink) { +LogMessage& LogMessage::ToSinkAlso(absl::Nonnull<absl::LogSink*> sink) { ABSL_INTERNAL_CHECK(sink, "null LogSink*"); data_->extra_sinks.push_back(sink); return *this; } -LogMessage& LogMessage::ToSinkOnly(absl::LogSink* sink) { +LogMessage& LogMessage::ToSinkOnly(absl::Nonnull<absl::LogSink*> sink) { ABSL_INTERNAL_CHECK(sink, "null LogSink*"); data_->extra_sinks.clear(); data_->extra_sinks.push_back(sink); @@ -637,11 +639,11 @@ #pragma warning(disable : 4722) #endif -LogMessageFatal::LogMessageFatal(const char* file, int line) +LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line) : LogMessage(file, line, absl::LogSeverity::kFatal) {} -LogMessageFatal::LogMessageFatal(const char* file, int line, - absl::string_view failure_msg) +LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line, + absl::Nonnull<const char*> failure_msg) : LogMessage(file, line, absl::LogSeverity::kFatal) { *this << "Check failed: " << failure_msg << " "; } @@ -651,7 +653,8 @@ FailWithoutStackTrace(); } -LogMessageDebugFatal::LogMessageDebugFatal(const char* file, int line) +LogMessageDebugFatal::LogMessageDebugFatal(absl::Nonnull<const char*> file, + int line) : LogMessage(file, line, absl::LogSeverity::kFatal) {} LogMessageDebugFatal::~LogMessageDebugFatal() { @@ -659,8 +662,8 @@ FailWithoutStackTrace(); } -LogMessageQuietlyDebugFatal::LogMessageQuietlyDebugFatal(const char* file, - int line) +LogMessageQuietlyDebugFatal::LogMessageQuietlyDebugFatal( + absl::Nonnull<const char*> file, int line) : LogMessage(file, line, absl::LogSeverity::kFatal) { SetFailQuietly(); } @@ -670,15 +673,17 @@ FailQuietly(); } -LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line) +LogMessageQuietlyFatal::LogMessageQuietlyFatal(absl::Nonnull<const char*> file, + int line) : LogMessage(file, line, absl::LogSeverity::kFatal) { SetFailQuietly(); } -LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line, - absl::string_view failure_msg) +LogMessageQuietlyFatal::LogMessageQuietlyFatal( + absl::Nonnull<const char*> file, int line, + absl::Nonnull<const char*> failure_msg) : LogMessageQuietlyFatal(file, line) { - *this << "Check failed: " << failure_msg << " "; + *this << "Check failed: " << failure_msg << " "; } LogMessageQuietlyFatal::~LogMessageQuietlyFatal() {
diff --git a/absl/log/internal/log_message.h b/absl/log/internal/log_message.h index e8bca65..474d1da 100644 --- a/absl/log/internal/log_message.h +++ b/absl/log/internal/log_message.h
@@ -367,7 +367,7 @@ LogMessageFatal(absl::Nonnull<const char*> file, int line) ABSL_ATTRIBUTE_COLD; LogMessageFatal(absl::Nonnull<const char*> file, int line, - absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD; + absl::Nonnull<const char*> failure_msg) ABSL_ATTRIBUTE_COLD; [[noreturn]] ~LogMessageFatal(); }; @@ -397,7 +397,8 @@ LogMessageQuietlyFatal(absl::Nonnull<const char*> file, int line) ABSL_ATTRIBUTE_COLD; LogMessageQuietlyFatal(absl::Nonnull<const char*> file, int line, - absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD; + absl::Nonnull<const char*> failure_msg) + ABSL_ATTRIBUTE_COLD; [[noreturn]] ~LogMessageQuietlyFatal(); };
diff --git a/absl/status/BUILD.bazel b/absl/status/BUILD.bazel index 8822e0f..db99548 100644 --- a/absl/status/BUILD.bazel +++ b/absl/status/BUILD.bazel
@@ -58,6 +58,7 @@ "//absl/base:raw_logging_internal", "//absl/base:strerror", "//absl/container:inlined_vector", + "//absl/debugging:leak_check", "//absl/debugging:stacktrace", "//absl/debugging:symbolize", "//absl/functional:function_ref",
diff --git a/absl/status/CMakeLists.txt b/absl/status/CMakeLists.txt index 24c01e7..e140365 100644 --- a/absl/status/CMakeLists.txt +++ b/absl/status/CMakeLists.txt
@@ -35,6 +35,7 @@ absl::core_headers absl::function_ref absl::inlined_vector + absl::leak_check absl::memory absl::no_destructor absl::nullability @@ -42,8 +43,8 @@ absl::raw_logging_internal absl::span absl::stacktrace - absl::strerror absl::str_format + absl::strerror absl::strings absl::symbolize PUBLIC
diff --git a/absl/status/internal/status_internal.cc b/absl/status/internal/status_internal.cc index a915675..99bf8fa 100644 --- a/absl/status/internal/status_internal.cc +++ b/absl/status/internal/status_internal.cc
@@ -28,6 +28,7 @@ #include "absl/base/config.h" #include "absl/base/macros.h" #include "absl/base/nullability.h" +#include "absl/debugging/leak_check.h" #include "absl/debugging/stacktrace.h" #include "absl/debugging/symbolize.h" #include "absl/memory/memory.h" @@ -234,12 +235,15 @@ } } -absl::Nonnull<std::string*> MakeCheckFailString( +absl::Nonnull<const char*> MakeCheckFailString( absl::Nonnull<const absl::Status*> status, absl::Nonnull<const char*> prefix) { - return new std::string( - absl::StrCat(prefix, " (", - status->ToString(StatusToStringMode::kWithEverything), ")")); + // There's no need to free this string since the process is crashing. + return absl::IgnoreLeak( + new std::string(absl::StrCat( + prefix, " (", + status->ToString(StatusToStringMode::kWithEverything), ")"))) + ->c_str(); } } // namespace status_internal
diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h index c9f4383..fe335b0 100644 --- a/absl/status/internal/status_internal.h +++ b/absl/status/internal/status_internal.h
@@ -120,7 +120,7 @@ // // This is an internal implementation detail for Abseil logging. ABSL_ATTRIBUTE_PURE_FUNCTION -absl::Nonnull<std::string*> MakeCheckFailString( +absl::Nonnull<const char*> MakeCheckFailString( absl::Nonnull<const absl::Status*> status, absl::Nonnull<const char*> prefix);