tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

log_message.cc (27994B)


      1 //
      2 // Copyright 2022 The Abseil Authors.
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      https://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 
     16 #include "absl/log/internal/log_message.h"
     17 
     18 #include <stddef.h>
     19 #include <stdint.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 
     23 #ifndef _WIN32
     24 #include <unistd.h>
     25 #endif
     26 
     27 #include <algorithm>
     28 #include <array>
     29 #include <atomic>
     30 #include <ios>
     31 #include <memory>
     32 #include <ostream>
     33 #include <string>
     34 #include <tuple>
     35 
     36 #include "absl/base/attributes.h"
     37 #include "absl/base/config.h"
     38 #include "absl/base/internal/raw_logging.h"
     39 #include "absl/base/internal/strerror.h"
     40 #include "absl/base/internal/sysinfo.h"
     41 #include "absl/base/log_severity.h"
     42 #include "absl/base/nullability.h"
     43 #include "absl/container/inlined_vector.h"
     44 #include "absl/debugging/internal/examine_stack.h"
     45 #include "absl/log/globals.h"
     46 #include "absl/log/internal/append_truncated.h"
     47 #include "absl/log/internal/globals.h"
     48 #include "absl/log/internal/log_format.h"
     49 #include "absl/log/internal/log_sink_set.h"
     50 #include "absl/log/internal/proto.h"
     51 #include "absl/log/internal/structured_proto.h"
     52 #include "absl/log/log_entry.h"
     53 #include "absl/log/log_sink.h"
     54 #include "absl/log/log_sink_registry.h"
     55 #include "absl/memory/memory.h"
     56 #include "absl/strings/string_view.h"
     57 #include "absl/time/clock.h"
     58 #include "absl/time/time.h"
     59 #include "absl/types/span.h"
     60 
     61 extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
     62    AbslInternalOnFatalLogMessage)(const absl::LogEntry&) {
     63  // Default - Do nothing
     64 }
     65 
     66 namespace absl {
     67 ABSL_NAMESPACE_BEGIN
     68 namespace log_internal {
     69 
     70 namespace {
     71 // message `logging.proto.Event`
     72 enum EventTag : uint8_t {
     73  kFileName = 2,
     74  kFileLine = 3,
     75  kTimeNsecs = 4,
     76  kSeverity = 5,
     77  kThreadId = 6,
     78  kValue = 7,
     79  kSequenceNumber = 9,
     80  kThreadName = 10,
     81 };
     82 
     83 // message `logging.proto.Value`
     84 enum ValueTag : uint8_t {
     85  kString = 1,
     86  kStringLiteral = 6,
     87 };
     88 
     89 // Decodes a `logging.proto.Value` from `buf` and writes a string representation
     90 // into `dst`.  The string representation will be truncated if `dst` is not
     91 // large enough to hold it.  Returns false if `dst` has size zero or one (i.e.
     92 // sufficient only for a nul-terminator) and no decoded data could be written.
     93 // This function may or may not write a nul-terminator into `dst`, and it may or
     94 // may not truncate the data it writes in order to do make space for that nul
     95 // terminator.  In any case, `dst` will be advanced to point at the byte where
     96 // subsequent writes should begin.
     97 bool PrintValue(absl::Span<char>& dst, absl::Span<const char> buf) {
     98  if (dst.size() <= 1) return false;
     99  ProtoField field;
    100  while (field.DecodeFrom(&buf)) {
    101    switch (field.tag()) {
    102      case ValueTag::kString:
    103      case ValueTag::kStringLiteral:
    104        if (field.type() == WireType::kLengthDelimited)
    105          if (log_internal::AppendTruncated(field.string_value(), dst) <
    106              field.string_value().size())
    107            return false;
    108    }
    109  }
    110  return true;
    111 }
    112 
    113 // See `logging.proto.Severity`
    114 int32_t ProtoSeverity(absl::LogSeverity severity, int verbose_level) {
    115  switch (severity) {
    116    case absl::LogSeverity::kInfo:
    117      if (verbose_level == absl::LogEntry::kNoVerbosityLevel) return 800;
    118      return 600 - verbose_level;
    119    case absl::LogSeverity::kWarning:
    120      return 900;
    121    case absl::LogSeverity::kError:
    122      return 950;
    123    case absl::LogSeverity::kFatal:
    124      return 1100;
    125    default:
    126      return 800;
    127  }
    128 }
    129 
    130 absl::string_view Basename(absl::string_view filepath) {
    131 #ifdef _WIN32
    132  size_t path = filepath.find_last_of("/\\");
    133 #else
    134  size_t path = filepath.find_last_of('/');
    135 #endif
    136  if (path != filepath.npos) filepath.remove_prefix(path + 1);
    137  return filepath;
    138 }
    139 
    140 void WriteToString(const char* data, void* str) {
    141  reinterpret_cast<std::string*>(str)->append(data);
    142 }
    143 void WriteToStream(const char* data, void* os) {
    144  auto* cast_os = static_cast<std::ostream*>(os);
    145  *cast_os << data;
    146 }
    147 }  // namespace
    148 
    149 struct LogMessage::LogMessageData final {
    150  LogMessageData(absl::Nonnull<const char*> file, int line,
    151                 absl::LogSeverity severity, absl::Time timestamp);
    152  LogMessageData(const LogMessageData&) = delete;
    153  LogMessageData& operator=(const LogMessageData&) = delete;
    154 
    155  // `LogEntry` sent to `LogSink`s; contains metadata.
    156  absl::LogEntry entry;
    157 
    158  // true => this was first fatal msg
    159  bool first_fatal;
    160  // true => all failures should be quiet
    161  bool fail_quietly;
    162  // true => PLOG was requested
    163  bool is_perror;
    164 
    165  // Extra `LogSink`s to log to, in addition to `global_sinks`.
    166  absl::InlinedVector<absl::Nonnull<absl::LogSink*>, 16> extra_sinks;
    167  // If true, log to `extra_sinks` but not to `global_sinks` or hardcoded
    168  // non-sink targets (e.g. stderr, log files).
    169  bool extra_sinks_only;
    170 
    171  std::ostream manipulated;  // ostream with IO manipulators applied
    172 
    173  // A `logging.proto.Event` proto message is built into `encoded_buf`.
    174  std::array<char, kLogMessageBufferSize> encoded_buf;
    175  // `encoded_remaining()` is the suffix of `encoded_buf` that has not been
    176  // filled yet.  If a datum to be encoded does not fit into
    177  // `encoded_remaining()` and cannot be truncated to fit, the size of
    178  // `encoded_remaining()` will be zeroed to prevent encoding of any further
    179  // data.  Note that in this case its `data()` pointer will not point past the
    180  // end of `encoded_buf`.
    181  // The first use of `encoded_remaining()` is our chance to record metadata
    182  // after any modifications (e.g. by `AtLocation()`) but before any data have
    183  // been recorded.  We want to record metadata before data so that data are
    184  // preferentially truncated if we run out of buffer.
    185  absl::Span<char>& encoded_remaining() {
    186    if (encoded_remaining_actual_do_not_use_directly.data() == nullptr) {
    187      encoded_remaining_actual_do_not_use_directly =
    188          absl::MakeSpan(encoded_buf);
    189      InitializeEncodingAndFormat();
    190    }
    191    return encoded_remaining_actual_do_not_use_directly;
    192  }
    193  absl::Span<char> encoded_remaining_actual_do_not_use_directly;
    194 
    195  // A formatted string message is built in `string_buf`.
    196  std::array<char, kLogMessageBufferSize> string_buf;
    197 
    198  void InitializeEncodingAndFormat();
    199  void FinalizeEncodingAndFormat();
    200 };
    201 
    202 LogMessage::LogMessageData::LogMessageData(absl::Nonnull<const char*> file,
    203                                           int line, absl::LogSeverity severity,
    204                                           absl::Time timestamp)
    205    : extra_sinks_only(false), manipulated(nullptr) {
    206  // Legacy defaults for LOG's ostream:
    207  manipulated.setf(std::ios_base::showbase | std::ios_base::boolalpha);
    208  entry.full_filename_ = file;
    209  entry.base_filename_ = Basename(file);
    210  entry.line_ = line;
    211  entry.prefix_ = absl::ShouldPrependLogPrefix();
    212  entry.severity_ = absl::NormalizeLogSeverity(severity);
    213  entry.verbose_level_ = absl::LogEntry::kNoVerbosityLevel;
    214  entry.timestamp_ = timestamp;
    215  entry.tid_ = absl::base_internal::GetCachedTID();
    216 }
    217 
    218 void LogMessage::LogMessageData::InitializeEncodingAndFormat() {
    219  EncodeStringTruncate(EventTag::kFileName, entry.source_filename(),
    220                       &encoded_remaining());
    221  EncodeVarint(EventTag::kFileLine, entry.source_line(), &encoded_remaining());
    222  EncodeVarint(EventTag::kTimeNsecs, absl::ToUnixNanos(entry.timestamp()),
    223               &encoded_remaining());
    224  EncodeVarint(EventTag::kSeverity,
    225               ProtoSeverity(entry.log_severity(), entry.verbosity()),
    226               &encoded_remaining());
    227  EncodeVarint(EventTag::kThreadId, entry.tid(), &encoded_remaining());
    228 }
    229 
    230 void LogMessage::LogMessageData::FinalizeEncodingAndFormat() {
    231  // Note that `encoded_remaining()` may have zero size without pointing past
    232  // the end of `encoded_buf`, so the difference between `data()` pointers is
    233  // used to compute the size of `encoded_data`.
    234  absl::Span<const char> encoded_data(
    235      encoded_buf.data(),
    236      static_cast<size_t>(encoded_remaining().data() - encoded_buf.data()));
    237  // `string_remaining` is the suffix of `string_buf` that has not been filled
    238  // yet.
    239  absl::Span<char> string_remaining(string_buf);
    240  // We may need to write a newline and nul-terminator at the end of the decoded
    241  // string data.  Rather than worry about whether those should overwrite the
    242  // end of the string (if the buffer is full) or be appended, we avoid writing
    243  // into the last two bytes so we always have space to append.
    244  string_remaining.remove_suffix(2);
    245  entry.prefix_len_ =
    246      entry.prefix() ? log_internal::FormatLogPrefix(
    247                           entry.log_severity(), entry.timestamp(), entry.tid(),
    248                           entry.source_basename(), entry.source_line(),
    249                           log_internal::ThreadIsLoggingToLogSink()
    250                               ? PrefixFormat::kRaw
    251                               : PrefixFormat::kNotRaw,
    252                           string_remaining)
    253                     : 0;
    254  // Decode data from `encoded_buf` until we run out of data or we run out of
    255  // `string_remaining`.
    256  ProtoField field;
    257  while (field.DecodeFrom(&encoded_data)) {
    258    switch (field.tag()) {
    259      case EventTag::kValue:
    260        if (field.type() != WireType::kLengthDelimited) continue;
    261        if (PrintValue(string_remaining, field.bytes_value())) continue;
    262        break;
    263    }
    264  }
    265  auto chars_written =
    266      static_cast<size_t>(string_remaining.data() - string_buf.data());
    267    string_buf[chars_written++] = '\n';
    268  string_buf[chars_written++] = '\0';
    269  entry.text_message_with_prefix_and_newline_and_nul_ =
    270      absl::MakeSpan(string_buf).subspan(0, chars_written);
    271 }
    272 
    273 LogMessage::LogMessage(absl::Nonnull<const char*> file, int line,
    274                       absl::LogSeverity severity)
    275    : data_(absl::make_unique<LogMessageData>(file, line, severity,
    276                                              absl::Now())) {
    277  data_->first_fatal = false;
    278  data_->is_perror = false;
    279  data_->fail_quietly = false;
    280 
    281  // This logs a backtrace even if the location is subsequently changed using
    282  // AtLocation.  This quirk, and the behavior when AtLocation is called twice,
    283  // are fixable but probably not worth fixing.
    284  LogBacktraceIfNeeded();
    285 }
    286 
    287 LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, InfoTag)
    288    : LogMessage(file, line, absl::LogSeverity::kInfo) {}
    289 LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, WarningTag)
    290    : LogMessage(file, line, absl::LogSeverity::kWarning) {}
    291 LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, ErrorTag)
    292    : LogMessage(file, line, absl::LogSeverity::kError) {}
    293 
    294 // This cannot go in the header since LogMessageData is defined in this file.
    295 LogMessage::~LogMessage() = default;
    296 
    297 LogMessage& LogMessage::AtLocation(absl::string_view file, int line) {
    298  data_->entry.full_filename_ = file;
    299  data_->entry.base_filename_ = Basename(file);
    300  data_->entry.line_ = line;
    301  LogBacktraceIfNeeded();
    302  return *this;
    303 }
    304 
    305 LogMessage& LogMessage::NoPrefix() {
    306  data_->entry.prefix_ = false;
    307  return *this;
    308 }
    309 
    310 LogMessage& LogMessage::WithVerbosity(int verbose_level) {
    311  if (verbose_level == absl::LogEntry::kNoVerbosityLevel) {
    312    data_->entry.verbose_level_ = absl::LogEntry::kNoVerbosityLevel;
    313  } else {
    314    data_->entry.verbose_level_ = std::max(0, verbose_level);
    315  }
    316  return *this;
    317 }
    318 
    319 LogMessage& LogMessage::WithTimestamp(absl::Time timestamp) {
    320  data_->entry.timestamp_ = timestamp;
    321  return *this;
    322 }
    323 
    324 LogMessage& LogMessage::WithThreadID(absl::LogEntry::tid_t tid) {
    325  data_->entry.tid_ = tid;
    326  return *this;
    327 }
    328 
    329 LogMessage& LogMessage::WithMetadataFrom(const absl::LogEntry& entry) {
    330  data_->entry.full_filename_ = entry.full_filename_;
    331  data_->entry.base_filename_ = entry.base_filename_;
    332  data_->entry.line_ = entry.line_;
    333  data_->entry.prefix_ = entry.prefix_;
    334  data_->entry.severity_ = entry.severity_;
    335  data_->entry.verbose_level_ = entry.verbose_level_;
    336  data_->entry.timestamp_ = entry.timestamp_;
    337  data_->entry.tid_ = entry.tid_;
    338  return *this;
    339 }
    340 
    341 LogMessage& LogMessage::WithPerror() {
    342  data_->is_perror = true;
    343  return *this;
    344 }
    345 
    346 LogMessage& LogMessage::ToSinkAlso(absl::Nonnull<absl::LogSink*> sink) {
    347  ABSL_INTERNAL_CHECK(sink, "null LogSink*");
    348  data_->extra_sinks.push_back(sink);
    349  return *this;
    350 }
    351 
    352 LogMessage& LogMessage::ToSinkOnly(absl::Nonnull<absl::LogSink*> sink) {
    353  ABSL_INTERNAL_CHECK(sink, "null LogSink*");
    354  data_->extra_sinks.clear();
    355  data_->extra_sinks.push_back(sink);
    356  data_->extra_sinks_only = true;
    357  return *this;
    358 }
    359 
    360 #ifdef __ELF__
    361 extern "C" void __gcov_dump() ABSL_ATTRIBUTE_WEAK;
    362 extern "C" void __gcov_flush() ABSL_ATTRIBUTE_WEAK;
    363 #endif
    364 
    365 void LogMessage::FailWithoutStackTrace() {
    366  // Now suppress repeated trace logging:
    367  log_internal::SetSuppressSigabortTrace(true);
    368 #if defined _DEBUG && defined COMPILER_MSVC
    369  // When debugging on windows, avoid the obnoxious dialog.
    370  __debugbreak();
    371 #endif
    372 
    373 #ifdef __ELF__
    374  // For b/8737634, flush coverage if we are in coverage mode.
    375  if (&__gcov_dump != nullptr) {
    376    __gcov_dump();
    377  } else if (&__gcov_flush != nullptr) {
    378    __gcov_flush();
    379  }
    380 #endif
    381 
    382  abort();
    383 }
    384 
    385 void LogMessage::FailQuietly() {
    386  // _exit. Calling abort() would trigger all sorts of death signal handlers
    387  // and a detailed stack trace. Calling exit() would trigger the onexit
    388  // handlers, including the heap-leak checker, which is guaranteed to fail in
    389  // this case: we probably just new'ed the std::string that we logged.
    390  // Anyway, if you're calling Fail or FailQuietly, you're trying to bail out
    391  // of the program quickly, and it doesn't make much sense for FailQuietly to
    392  // offer different guarantees about exit behavior than Fail does. (And as a
    393  // consequence for QCHECK and CHECK to offer different exit behaviors)
    394  _exit(1);
    395 }
    396 
    397 LogMessage& LogMessage::operator<<(const std::string& v) {
    398  CopyToEncodedBuffer<StringType::kNotLiteral>(v);
    399  return *this;
    400 }
    401 
    402 LogMessage& LogMessage::operator<<(absl::string_view v) {
    403  CopyToEncodedBuffer<StringType::kNotLiteral>(v);
    404  return *this;
    405 }
    406 LogMessage& LogMessage::operator<<(std::ostream& (*m)(std::ostream& os)) {
    407  OstreamView view(*data_);
    408  data_->manipulated << m;
    409  return *this;
    410 }
    411 LogMessage& LogMessage::operator<<(std::ios_base& (*m)(std::ios_base& os)) {
    412  OstreamView view(*data_);
    413  data_->manipulated << m;
    414  return *this;
    415 }
    416 // NOLINTBEGIN(runtime/int)
    417 // NOLINTBEGIN(google-runtime-int)
    418 template LogMessage& LogMessage::operator<<(const char& v);
    419 template LogMessage& LogMessage::operator<<(const signed char& v);
    420 template LogMessage& LogMessage::operator<<(const unsigned char& v);
    421 template LogMessage& LogMessage::operator<<(const short& v);
    422 template LogMessage& LogMessage::operator<<(const unsigned short& v);
    423 template LogMessage& LogMessage::operator<<(const int& v);
    424 template LogMessage& LogMessage::operator<<(const unsigned int& v);
    425 template LogMessage& LogMessage::operator<<(const long& v);
    426 template LogMessage& LogMessage::operator<<(const unsigned long& v);
    427 template LogMessage& LogMessage::operator<<(const long long& v);
    428 template LogMessage& LogMessage::operator<<(const unsigned long long& v);
    429 template LogMessage& LogMessage::operator<<(void* const& v);
    430 template LogMessage& LogMessage::operator<<(const void* const& v);
    431 template LogMessage& LogMessage::operator<<(const float& v);
    432 template LogMessage& LogMessage::operator<<(const double& v);
    433 template LogMessage& LogMessage::operator<<(const bool& v);
    434 // NOLINTEND(google-runtime-int)
    435 // NOLINTEND(runtime/int)
    436 
    437 void LogMessage::Flush() {
    438  if (data_->entry.log_severity() < absl::MinLogLevel()) return;
    439 
    440  if (data_->is_perror) {
    441    InternalStream() << ": " << absl::base_internal::StrError(errno_saver_())
    442                     << " [" << errno_saver_() << "]";
    443  }
    444 
    445  // Have we already seen a fatal message?
    446  ABSL_CONST_INIT static std::atomic<bool> seen_fatal(false);
    447  if (data_->entry.log_severity() == absl::LogSeverity::kFatal &&
    448      absl::log_internal::ExitOnDFatal()) {
    449    // Exactly one LOG(FATAL) message is responsible for aborting the process,
    450    // even if multiple threads LOG(FATAL) concurrently.
    451    bool expected_seen_fatal = false;
    452    if (seen_fatal.compare_exchange_strong(expected_seen_fatal, true,
    453                                           std::memory_order_relaxed)) {
    454      data_->first_fatal = true;
    455    }
    456  }
    457 
    458  data_->FinalizeEncodingAndFormat();
    459  data_->entry.encoding_ =
    460      absl::string_view(data_->encoded_buf.data(),
    461                        static_cast<size_t>(data_->encoded_remaining().data() -
    462                                            data_->encoded_buf.data()));
    463  SendToLog();
    464 }
    465 
    466 void LogMessage::SetFailQuietly() { data_->fail_quietly = true; }
    467 
    468 LogMessage::OstreamView::OstreamView(LogMessageData& message_data)
    469    : data_(message_data), encoded_remaining_copy_(data_.encoded_remaining()) {
    470  // This constructor sets the `streambuf` up so that streaming into an attached
    471  // ostream encodes string data in-place.  To do that, we write appropriate
    472  // headers into the buffer using a copy of the buffer view so that we can
    473  // decide not to keep them later if nothing is ever streamed in.  We don't
    474  // know how much data we'll get, but we can use the size of the remaining
    475  // buffer as an upper bound and fill in the right size once we know it.
    476  message_start_ =
    477      EncodeMessageStart(EventTag::kValue, encoded_remaining_copy_.size(),
    478                         &encoded_remaining_copy_);
    479  string_start_ =
    480      EncodeMessageStart(ValueTag::kString, encoded_remaining_copy_.size(),
    481                         &encoded_remaining_copy_);
    482  setp(encoded_remaining_copy_.data(),
    483       encoded_remaining_copy_.data() + encoded_remaining_copy_.size());
    484  data_.manipulated.rdbuf(this);
    485 }
    486 
    487 LogMessage::OstreamView::~OstreamView() {
    488  data_.manipulated.rdbuf(nullptr);
    489  if (!string_start_.data()) {
    490    // The second field header didn't fit.  Whether the first one did or not, we
    491    // shouldn't commit `encoded_remaining_copy_`, and we also need to zero the
    492    // size of `data_->encoded_remaining()` so that no more data are encoded.
    493    data_.encoded_remaining().remove_suffix(data_.encoded_remaining().size());
    494    return;
    495  }
    496  const absl::Span<const char> contents(pbase(),
    497                                        static_cast<size_t>(pptr() - pbase()));
    498  if (contents.empty()) return;
    499  encoded_remaining_copy_.remove_prefix(contents.size());
    500  EncodeMessageLength(string_start_, &encoded_remaining_copy_);
    501  EncodeMessageLength(message_start_, &encoded_remaining_copy_);
    502  data_.encoded_remaining() = encoded_remaining_copy_;
    503 }
    504 
    505 std::ostream& LogMessage::OstreamView::stream() { return data_.manipulated; }
    506 
    507 bool LogMessage::IsFatal() const {
    508  return data_->entry.log_severity() == absl::LogSeverity::kFatal &&
    509         absl::log_internal::ExitOnDFatal();
    510 }
    511 
    512 void LogMessage::PrepareToDie() {
    513  // If we log a FATAL message, flush all the log destinations, then toss
    514  // a signal for others to catch. We leave the logs in a state that
    515  // someone else can use them (as long as they flush afterwards)
    516  if (data_->first_fatal) {
    517    // Notify observers about the upcoming fatal error.
    518    ABSL_INTERNAL_C_SYMBOL(AbslInternalOnFatalLogMessage)(data_->entry);
    519  }
    520 
    521  if (!data_->fail_quietly) {
    522    // Log the message first before we start collecting stack trace.
    523    log_internal::LogToSinks(data_->entry, absl::MakeSpan(data_->extra_sinks),
    524                             data_->extra_sinks_only);
    525 
    526    // `DumpStackTrace` generates an empty string under MSVC.
    527    // Adding the constant prefix here simplifies testing.
    528    data_->entry.stacktrace_ = "*** Check failure stack trace: ***\n";
    529    debugging_internal::DumpStackTrace(
    530        0, log_internal::MaxFramesInLogStackTrace(),
    531        log_internal::ShouldSymbolizeLogStackTrace(), WriteToString,
    532        &data_->entry.stacktrace_);
    533  }
    534 }
    535 
    536 void LogMessage::Die() {
    537  absl::FlushLogSinks();
    538 
    539  if (data_->fail_quietly) {
    540    FailQuietly();
    541  } else {
    542    FailWithoutStackTrace();
    543  }
    544 }
    545 
    546 void LogMessage::SendToLog() {
    547  if (IsFatal()) PrepareToDie();
    548  // Also log to all registered sinks, even if OnlyLogToStderr() is set.
    549  log_internal::LogToSinks(data_->entry, absl::MakeSpan(data_->extra_sinks),
    550                           data_->extra_sinks_only);
    551  if (IsFatal()) Die();
    552 }
    553 
    554 void LogMessage::LogBacktraceIfNeeded() {
    555  if (!absl::log_internal::IsInitialized()) return;
    556 
    557  if (!absl::log_internal::ShouldLogBacktraceAt(data_->entry.source_basename(),
    558                                                data_->entry.source_line()))
    559    return;
    560  OstreamView view(*data_);
    561  view.stream() << " (stacktrace:\n";
    562  debugging_internal::DumpStackTrace(
    563      1, log_internal::MaxFramesInLogStackTrace(),
    564      log_internal::ShouldSymbolizeLogStackTrace(), WriteToStream,
    565      &view.stream());
    566  view.stream() << ") ";
    567 }
    568 
    569 // Encodes into `data_->encoded_remaining()` a partial `logging.proto.Event`
    570 // containing the specified string data using a `Value` field appropriate to
    571 // `str_type`.  Truncates `str` if necessary, but emits nothing and marks the
    572 // buffer full if  even the field headers do not fit.
    573 template <LogMessage::StringType str_type>
    574 void LogMessage::CopyToEncodedBuffer(absl::string_view str) {
    575  auto encoded_remaining_copy = data_->encoded_remaining();
    576  constexpr uint8_t tag_value = str_type == StringType::kLiteral
    577                                    ? ValueTag::kStringLiteral
    578                                    : ValueTag::kString;
    579  auto start = EncodeMessageStart(
    580      EventTag::kValue,
    581      BufferSizeFor(tag_value, WireType::kLengthDelimited) + str.size(),
    582      &encoded_remaining_copy);
    583  // If the `logging.proto.Event.value` field header did not fit,
    584  // `EncodeMessageStart` will have zeroed `encoded_remaining_copy`'s size and
    585  // `EncodeStringTruncate` will fail too.
    586  if (EncodeStringTruncate(tag_value, str, &encoded_remaining_copy)) {
    587    // The string may have been truncated, but the field header fit.
    588    EncodeMessageLength(start, &encoded_remaining_copy);
    589    data_->encoded_remaining() = encoded_remaining_copy;
    590  } else {
    591    // The field header(s) did not fit; zero `encoded_remaining()` so we don't
    592    // write anything else later.
    593    data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
    594  }
    595 }
    596 template void LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(
    597    absl::string_view str);
    598 template void LogMessage::CopyToEncodedBuffer<
    599    LogMessage::StringType::kNotLiteral>(absl::string_view str);
    600 template <LogMessage::StringType str_type>
    601 void LogMessage::CopyToEncodedBuffer(char ch, size_t num) {
    602  auto encoded_remaining_copy = data_->encoded_remaining();
    603  constexpr uint8_t tag_value = str_type == StringType::kLiteral
    604                                    ? ValueTag::kStringLiteral
    605                                    : ValueTag::kString;
    606  auto value_start = EncodeMessageStart(
    607      EventTag::kValue,
    608      BufferSizeFor(tag_value, WireType::kLengthDelimited) + num,
    609      &encoded_remaining_copy);
    610  auto str_start = EncodeMessageStart(tag_value, num, &encoded_remaining_copy);
    611  if (str_start.data()) {
    612    // The field headers fit.
    613    log_internal::AppendTruncated(ch, num, encoded_remaining_copy);
    614    EncodeMessageLength(str_start, &encoded_remaining_copy);
    615    EncodeMessageLength(value_start, &encoded_remaining_copy);
    616    data_->encoded_remaining() = encoded_remaining_copy;
    617  } else {
    618    // The field header(s) did not fit; zero `encoded_remaining()` so we don't
    619    // write anything else later.
    620    data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
    621  }
    622 }
    623 template void LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(
    624    char ch, size_t num);
    625 template void LogMessage::CopyToEncodedBuffer<
    626    LogMessage::StringType::kNotLiteral>(char ch, size_t num);
    627 
    628 template void LogMessage::CopyToEncodedBufferWithStructuredProtoField<
    629    LogMessage::StringType::kLiteral>(StructuredProtoField field,
    630                                      absl::string_view str);
    631 template void LogMessage::CopyToEncodedBufferWithStructuredProtoField<
    632    LogMessage::StringType::kNotLiteral>(StructuredProtoField field,
    633                                         absl::string_view str);
    634 
    635 template <LogMessage::StringType str_type>
    636 void LogMessage::CopyToEncodedBufferWithStructuredProtoField(
    637    StructuredProtoField field, absl::string_view str) {
    638  auto encoded_remaining_copy = data_->encoded_remaining();
    639  size_t encoded_field_size = BufferSizeForStructuredProtoField(field);
    640  constexpr uint8_t tag_value = str_type == StringType::kLiteral
    641                                    ? ValueTag::kStringLiteral
    642                                    : ValueTag::kString;
    643  auto start = EncodeMessageStart(
    644      EventTag::kValue,
    645      encoded_field_size +
    646          BufferSizeFor(tag_value, WireType::kLengthDelimited) + str.size(),
    647      &encoded_remaining_copy);
    648 
    649  // Write the encoded proto field.
    650  if (!EncodeStructuredProtoField(field, encoded_remaining_copy)) {
    651    // The header / field will not fit; zero `encoded_remaining()` so we
    652    // don't write anything else later.
    653    data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
    654    return;
    655  }
    656 
    657  // Write the string, truncating if necessary.
    658  if (!EncodeStringTruncate(ValueTag::kString, str, &encoded_remaining_copy)) {
    659    // The length of the string itself did not fit; zero `encoded_remaining()`
    660    // so the value is not encoded at all.
    661    data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
    662    return;
    663  }
    664 
    665  EncodeMessageLength(start, &encoded_remaining_copy);
    666  data_->encoded_remaining() = encoded_remaining_copy;
    667 }
    668 
    669 // We intentionally don't return from these destructors. Disable MSVC's warning
    670 // about the destructor never returning as we do so intentionally here.
    671 #if defined(_MSC_VER) && !defined(__clang__)
    672 #pragma warning(push)
    673 #pragma warning(disable : 4722)
    674 #endif
    675 
    676 LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line)
    677    : LogMessage(file, line, absl::LogSeverity::kFatal) {}
    678 
    679 LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line,
    680                                 absl::Nonnull<const char*> failure_msg)
    681    : LogMessage(file, line, absl::LogSeverity::kFatal) {
    682  *this << "Check failed: " << failure_msg << " ";
    683 }
    684 
    685 LogMessageFatal::~LogMessageFatal() {
    686  FailWithoutStackTrace();
    687 }
    688 
    689 LogMessageDebugFatal::LogMessageDebugFatal(absl::Nonnull<const char*> file,
    690                                           int line)
    691    : LogMessage(file, line, absl::LogSeverity::kFatal) {}
    692 
    693 LogMessageDebugFatal::~LogMessageDebugFatal() {
    694  FailWithoutStackTrace();
    695 }
    696 
    697 LogMessageQuietlyDebugFatal::LogMessageQuietlyDebugFatal(
    698    absl::Nonnull<const char*> file, int line)
    699    : LogMessage(file, line, absl::LogSeverity::kFatal) {
    700  SetFailQuietly();
    701 }
    702 
    703 LogMessageQuietlyDebugFatal::~LogMessageQuietlyDebugFatal() {
    704  FailQuietly();
    705 }
    706 
    707 LogMessageQuietlyFatal::LogMessageQuietlyFatal(absl::Nonnull<const char*> file,
    708                                               int line)
    709    : LogMessage(file, line, absl::LogSeverity::kFatal) {
    710  SetFailQuietly();
    711 }
    712 
    713 LogMessageQuietlyFatal::LogMessageQuietlyFatal(
    714    absl::Nonnull<const char*> file, int line,
    715    absl::Nonnull<const char*> failure_msg)
    716    : LogMessageQuietlyFatal(file, line) {
    717  *this << "Check failed: " << failure_msg << " ";
    718 }
    719 
    720 LogMessageQuietlyFatal::~LogMessageQuietlyFatal() {
    721  FailQuietly();
    722 }
    723 #if defined(_MSC_VER) && !defined(__clang__)
    724 #pragma warning(pop)
    725 #endif
    726 
    727 }  // namespace log_internal
    728 
    729 ABSL_NAMESPACE_END
    730 }  // namespace absl