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);