log_message.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  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. #include "absl/log/internal/log_message.h"
  16. #include <stddef.h>
  17. #include <stdint.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #ifndef _WIN32
  21. #include <unistd.h>
  22. #endif
  23. #include <algorithm>
  24. #include <array>
  25. #include <atomic>
  26. #include <memory>
  27. #include <ostream>
  28. #include <string>
  29. #include <tuple>
  30. #include "absl/base/attributes.h"
  31. #include "absl/base/config.h"
  32. #include "absl/base/internal/raw_logging.h"
  33. #include "absl/base/internal/strerror.h"
  34. #include "absl/base/internal/sysinfo.h"
  35. #include "absl/base/log_severity.h"
  36. #include "absl/container/inlined_vector.h"
  37. #include "absl/debugging/internal/examine_stack.h"
  38. #include "absl/log/globals.h"
  39. #include "absl/log/internal/append_truncated.h"
  40. #include "absl/log/internal/globals.h"
  41. #include "absl/log/internal/log_format.h"
  42. #include "absl/log/internal/log_sink_set.h"
  43. #include "absl/log/internal/proto.h"
  44. #include "absl/log/log_entry.h"
  45. #include "absl/log/log_sink.h"
  46. #include "absl/log/log_sink_registry.h"
  47. #include "absl/memory/memory.h"
  48. #include "absl/strings/string_view.h"
  49. #include "absl/time/clock.h"
  50. #include "absl/time/time.h"
  51. #include "absl/types/span.h"
  52. extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
  53. AbslInternalOnFatalLogMessage)(const absl::LogEntry&) {
  54. // Default - Do nothing
  55. }
  56. namespace absl {
  57. ABSL_NAMESPACE_BEGIN
  58. namespace log_internal {
  59. namespace {
  60. // message `logging.proto.Event`
  61. enum EventTag : uint8_t {
  62. kValue = 7,
  63. };
  64. // message `logging.proto.Value`
  65. enum ValueTag : uint8_t {
  66. kString = 1,
  67. kStringLiteral = 6,
  68. };
  69. // Decodes a `logging.proto.Value` from `buf` and writes a string representation
  70. // into `dst`. The string representation will be truncated if `dst` is not
  71. // large enough to hold it. Returns false if `dst` has size zero or one (i.e.
  72. // sufficient only for a nul-terminator) and no decoded data could be written.
  73. // This function may or may not write a nul-terminator into `dst`, and it may or
  74. // may not truncate the data it writes in order to do make space for that nul
  75. // terminator. In any case, `dst` will be advanced to point at the byte where
  76. // subsequent writes should begin.
  77. bool PrintValue(absl::Span<char>& dst, absl::Span<const char> buf) {
  78. if (dst.size() <= 1) return false;
  79. ProtoField field;
  80. while (field.DecodeFrom(&buf)) {
  81. switch (field.tag()) {
  82. case ValueTag::kString:
  83. case ValueTag::kStringLiteral:
  84. if (field.type() == WireType::kLengthDelimited)
  85. if (log_internal::AppendTruncated(field.string_value(), dst) <
  86. field.string_value().size())
  87. return false;
  88. }
  89. }
  90. return true;
  91. }
  92. absl::string_view Basename(absl::string_view filepath) {
  93. #ifdef _WIN32
  94. size_t path = filepath.find_last_of("/\\");
  95. #else
  96. size_t path = filepath.find_last_of('/');
  97. #endif
  98. if (path != filepath.npos) filepath.remove_prefix(path + 1);
  99. return filepath;
  100. }
  101. void WriteToString(const char* data, void* str) {
  102. reinterpret_cast<std::string*>(str)->append(data);
  103. }
  104. void WriteToStream(const char* data, void* os) {
  105. auto* cast_os = static_cast<std::ostream*>(os);
  106. *cast_os << data;
  107. }
  108. } // namespace
  109. struct LogMessage::LogMessageData final {
  110. LogMessageData(const char* file, int line, absl::LogSeverity severity,
  111. absl::Time timestamp);
  112. LogMessageData(const LogMessageData&) = delete;
  113. LogMessageData& operator=(const LogMessageData&) = delete;
  114. // `LogEntry` sent to `LogSink`s; contains metadata.
  115. absl::LogEntry entry;
  116. // true => this was first fatal msg
  117. bool first_fatal;
  118. // true => all failures should be quiet
  119. bool fail_quietly;
  120. // true => PLOG was requested
  121. bool is_perror;
  122. // Extra `LogSink`s to log to, in addition to `global_sinks`.
  123. absl::InlinedVector<absl::LogSink*, 16> extra_sinks;
  124. // If true, log to `extra_sinks` but not to `global_sinks` or hardcoded
  125. // non-sink targets (e.g. stderr, log files).
  126. bool extra_sinks_only;
  127. std::ostream manipulated; // ostream with IO manipulators applied
  128. // A `logging.proto.Event` proto message is built into `encoded_buf`.
  129. std::array<char, kLogMessageBufferSize> encoded_buf;
  130. // `encoded_remaining` is the suffix of `encoded_buf` that has not been filled
  131. // yet. If a datum to be encoded does not fit into `encoded_remaining` and
  132. // cannot be truncated to fit, the size of `encoded_remaining` will be zeroed
  133. // to prevent encoding of any further data. Note that in this case its data()
  134. // pointer will not point past the end of `encoded_buf`.
  135. absl::Span<char> encoded_remaining;
  136. // A formatted string message is built in `string_buf`.
  137. std::array<char, kLogMessageBufferSize> string_buf;
  138. void FinalizeEncodingAndFormat();
  139. };
  140. LogMessage::LogMessageData::LogMessageData(const char* file, int line,
  141. absl::LogSeverity severity,
  142. absl::Time timestamp)
  143. : extra_sinks_only(false),
  144. manipulated(nullptr),
  145. // This `absl::MakeSpan` silences spurious -Wuninitialized from GCC:
  146. encoded_remaining(absl::MakeSpan(encoded_buf)) {
  147. // Legacy defaults for LOG's ostream:
  148. manipulated.setf(std::ios_base::showbase | std::ios_base::boolalpha);
  149. entry.full_filename_ = file;
  150. entry.base_filename_ = Basename(file);
  151. entry.line_ = line;
  152. entry.prefix_ = absl::ShouldPrependLogPrefix();
  153. entry.severity_ = absl::NormalizeLogSeverity(severity);
  154. entry.verbose_level_ = absl::LogEntry::kNoVerbosityLevel;
  155. entry.timestamp_ = timestamp;
  156. entry.tid_ = absl::base_internal::GetCachedTID();
  157. }
  158. void LogMessage::LogMessageData::FinalizeEncodingAndFormat() {
  159. // Note that `encoded_remaining` may have zero size without pointing past the
  160. // end of `encoded_buf`, so the difference between `data()` pointers is used
  161. // to compute the size of `encoded_data`.
  162. absl::Span<const char> encoded_data(
  163. encoded_buf.data(),
  164. static_cast<size_t>(encoded_remaining.data() - encoded_buf.data()));
  165. // `string_remaining` is the suffix of `string_buf` that has not been filled
  166. // yet.
  167. absl::Span<char> string_remaining(string_buf);
  168. // We may need to write a newline and nul-terminator at the end of the decoded
  169. // string data. Rather than worry about whether those should overwrite the
  170. // end of the string (if the buffer is full) or be appended, we avoid writing
  171. // into the last two bytes so we always have space to append.
  172. string_remaining.remove_suffix(2);
  173. entry.prefix_len_ =
  174. entry.prefix() ? log_internal::FormatLogPrefix(
  175. entry.log_severity(), entry.timestamp(), entry.tid(),
  176. entry.source_basename(), entry.source_line(),
  177. log_internal::ThreadIsLoggingToLogSink()
  178. ? PrefixFormat::kRaw
  179. : PrefixFormat::kNotRaw,
  180. string_remaining)
  181. : 0;
  182. // Decode data from `encoded_buf` until we run out of data or we run out of
  183. // `string_remaining`.
  184. ProtoField field;
  185. while (field.DecodeFrom(&encoded_data)) {
  186. switch (field.tag()) {
  187. case EventTag::kValue:
  188. if (field.type() != WireType::kLengthDelimited) continue;
  189. if (PrintValue(string_remaining, field.bytes_value())) continue;
  190. break;
  191. }
  192. break;
  193. }
  194. auto chars_written =
  195. static_cast<size_t>(string_remaining.data() - string_buf.data());
  196. string_buf[chars_written++] = '\n';
  197. string_buf[chars_written++] = '\0';
  198. entry.text_message_with_prefix_and_newline_and_nul_ =
  199. absl::MakeSpan(string_buf).subspan(0, chars_written);
  200. }
  201. LogMessage::LogMessage(const char* file, int line, absl::LogSeverity severity)
  202. : data_(absl::make_unique<LogMessageData>(file, line, severity,
  203. absl::Now())) {
  204. data_->first_fatal = false;
  205. data_->is_perror = false;
  206. data_->fail_quietly = false;
  207. // This logs a backtrace even if the location is subsequently changed using
  208. // AtLocation. This quirk, and the behavior when AtLocation is called twice,
  209. // are fixable but probably not worth fixing.
  210. LogBacktraceIfNeeded();
  211. }
  212. LogMessage::~LogMessage() {
  213. #ifdef ABSL_MIN_LOG_LEVEL
  214. if (data_->entry.log_severity() <
  215. static_cast<absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) &&
  216. data_->entry.log_severity() < absl::LogSeverity::kFatal) {
  217. return;
  218. }
  219. #endif
  220. Flush();
  221. }
  222. LogMessage& LogMessage::AtLocation(absl::string_view file, int line) {
  223. data_->entry.full_filename_ = file;
  224. data_->entry.base_filename_ = Basename(file);
  225. data_->entry.line_ = line;
  226. LogBacktraceIfNeeded();
  227. return *this;
  228. }
  229. LogMessage& LogMessage::NoPrefix() {
  230. data_->entry.prefix_ = false;
  231. return *this;
  232. }
  233. LogMessage& LogMessage::WithVerbosity(int verbose_level) {
  234. if (verbose_level == absl::LogEntry::kNoVerbosityLevel) {
  235. data_->entry.verbose_level_ = absl::LogEntry::kNoVerbosityLevel;
  236. } else {
  237. data_->entry.verbose_level_ = std::max(0, verbose_level);
  238. }
  239. return *this;
  240. }
  241. LogMessage& LogMessage::WithTimestamp(absl::Time timestamp) {
  242. data_->entry.timestamp_ = timestamp;
  243. return *this;
  244. }
  245. LogMessage& LogMessage::WithThreadID(absl::LogEntry::tid_t tid) {
  246. data_->entry.tid_ = tid;
  247. return *this;
  248. }
  249. LogMessage& LogMessage::WithMetadataFrom(const absl::LogEntry& entry) {
  250. data_->entry.full_filename_ = entry.full_filename_;
  251. data_->entry.base_filename_ = entry.base_filename_;
  252. data_->entry.line_ = entry.line_;
  253. data_->entry.prefix_ = entry.prefix_;
  254. data_->entry.severity_ = entry.severity_;
  255. data_->entry.verbose_level_ = entry.verbose_level_;
  256. data_->entry.timestamp_ = entry.timestamp_;
  257. data_->entry.tid_ = entry.tid_;
  258. return *this;
  259. }
  260. LogMessage& LogMessage::WithPerror() {
  261. data_->is_perror = true;
  262. return *this;
  263. }
  264. LogMessage& LogMessage::ToSinkAlso(absl::LogSink* sink) {
  265. ABSL_INTERNAL_CHECK(sink, "null LogSink*");
  266. data_->extra_sinks.push_back(sink);
  267. return *this;
  268. }
  269. LogMessage& LogMessage::ToSinkOnly(absl::LogSink* sink) {
  270. ABSL_INTERNAL_CHECK(sink, "null LogSink*");
  271. data_->extra_sinks.clear();
  272. data_->extra_sinks.push_back(sink);
  273. data_->extra_sinks_only = true;
  274. return *this;
  275. }
  276. #ifdef __ELF__
  277. extern "C" void __gcov_dump() ABSL_ATTRIBUTE_WEAK;
  278. extern "C" void __gcov_flush() ABSL_ATTRIBUTE_WEAK;
  279. #endif
  280. void LogMessage::FailWithoutStackTrace() {
  281. // Now suppress repeated trace logging:
  282. log_internal::SetSuppressSigabortTrace(true);
  283. #if defined _DEBUG && defined COMPILER_MSVC
  284. // When debugging on windows, avoid the obnoxious dialog.
  285. __debugbreak();
  286. #endif
  287. #ifdef __ELF__
  288. // For b/8737634, flush coverage if we are in coverage mode.
  289. if (&__gcov_dump != nullptr) {
  290. __gcov_dump();
  291. } else if (&__gcov_flush != nullptr) {
  292. __gcov_flush();
  293. }
  294. #endif
  295. abort();
  296. }
  297. void LogMessage::FailQuietly() {
  298. // _exit. Calling abort() would trigger all sorts of death signal handlers
  299. // and a detailed stack trace. Calling exit() would trigger the onexit
  300. // handlers, including the heap-leak checker, which is guaranteed to fail in
  301. // this case: we probably just new'ed the std::string that we logged.
  302. // Anyway, if you're calling Fail or FailQuietly, you're trying to bail out
  303. // of the program quickly, and it doesn't make much sense for FailQuietly to
  304. // offer different guarantees about exit behavior than Fail does. (And as a
  305. // consequence for QCHECK and CHECK to offer different exit behaviors)
  306. _exit(1);
  307. }
  308. LogMessage& LogMessage::operator<<(const std::string& v) {
  309. CopyToEncodedBuffer(v, StringType::kNotLiteral);
  310. return *this;
  311. }
  312. LogMessage& LogMessage::operator<<(absl::string_view v) {
  313. CopyToEncodedBuffer(v, StringType::kNotLiteral);
  314. return *this;
  315. }
  316. LogMessage& LogMessage::operator<<(std::ostream& (*m)(std::ostream& os)) {
  317. OstreamView view(*data_);
  318. data_->manipulated << m;
  319. return *this;
  320. }
  321. LogMessage& LogMessage::operator<<(std::ios_base& (*m)(std::ios_base& os)) {
  322. OstreamView view(*data_);
  323. data_->manipulated << m;
  324. return *this;
  325. }
  326. template LogMessage& LogMessage::operator<<(const char& v);
  327. template LogMessage& LogMessage::operator<<(const signed char& v);
  328. template LogMessage& LogMessage::operator<<(const unsigned char& v);
  329. template LogMessage& LogMessage::operator<<(const short& v); // NOLINT
  330. template LogMessage& LogMessage::operator<<(const unsigned short& v); // NOLINT
  331. template LogMessage& LogMessage::operator<<(const int& v);
  332. template LogMessage& LogMessage::operator<<(const unsigned int& v);
  333. template LogMessage& LogMessage::operator<<(const long& v); // NOLINT
  334. template LogMessage& LogMessage::operator<<(const unsigned long& v); // NOLINT
  335. template LogMessage& LogMessage::operator<<(const long long& v); // NOLINT
  336. template LogMessage& LogMessage::operator<<(
  337. const unsigned long long& v); // NOLINT
  338. template LogMessage& LogMessage::operator<<(void* const& v);
  339. template LogMessage& LogMessage::operator<<(const void* const& v);
  340. template LogMessage& LogMessage::operator<<(const float& v);
  341. template LogMessage& LogMessage::operator<<(const double& v);
  342. template LogMessage& LogMessage::operator<<(const bool& v);
  343. void LogMessage::Flush() {
  344. if (data_->entry.log_severity() < absl::MinLogLevel())
  345. return;
  346. if (data_->is_perror) {
  347. InternalStream() << ": " << absl::base_internal::StrError(errno_saver_())
  348. << " [" << errno_saver_() << "]";
  349. }
  350. // Have we already seen a fatal message?
  351. ABSL_CONST_INIT static std::atomic<bool> seen_fatal(false);
  352. if (data_->entry.log_severity() == absl::LogSeverity::kFatal &&
  353. absl::log_internal::ExitOnDFatal()) {
  354. // Exactly one LOG(FATAL) message is responsible for aborting the process,
  355. // even if multiple threads LOG(FATAL) concurrently.
  356. bool expected_seen_fatal = false;
  357. if (seen_fatal.compare_exchange_strong(expected_seen_fatal, true,
  358. std::memory_order_relaxed)) {
  359. data_->first_fatal = true;
  360. }
  361. }
  362. data_->FinalizeEncodingAndFormat();
  363. data_->entry.encoding_ =
  364. absl::string_view(data_->encoded_buf.data(),
  365. static_cast<size_t>(data_->encoded_remaining.data() -
  366. data_->encoded_buf.data()));
  367. SendToLog();
  368. }
  369. void LogMessage::SetFailQuietly() { data_->fail_quietly = true; }
  370. LogMessage::OstreamView::OstreamView(LogMessageData& message_data)
  371. : data_(message_data), encoded_remaining_copy_(data_.encoded_remaining) {
  372. // This constructor sets the `streambuf` up so that streaming into an attached
  373. // ostream encodes string data in-place. To do that, we write appropriate
  374. // headers into the buffer using a copy of the buffer view so that we can
  375. // decide not to keep them later if nothing is ever streamed in. We don't
  376. // know how much data we'll get, but we can use the size of the remaining
  377. // buffer as an upper bound and fill in the right size once we know it.
  378. message_start_ =
  379. EncodeMessageStart(EventTag::kValue, encoded_remaining_copy_.size(),
  380. &encoded_remaining_copy_);
  381. string_start_ =
  382. EncodeMessageStart(ValueTag::kString, encoded_remaining_copy_.size(),
  383. &encoded_remaining_copy_);
  384. setp(encoded_remaining_copy_.data(),
  385. encoded_remaining_copy_.data() + encoded_remaining_copy_.size());
  386. data_.manipulated.rdbuf(this);
  387. }
  388. LogMessage::OstreamView::~OstreamView() {
  389. data_.manipulated.rdbuf(nullptr);
  390. if (!string_start_.data()) {
  391. // The second field header didn't fit. Whether the first one did or not, we
  392. // shouldn't commit `encoded_remaining_copy_`, and we also need to zero the
  393. // size of `data_->encoded_remaining` so that no more data are encoded.
  394. data_.encoded_remaining.remove_suffix(data_.encoded_remaining.size());
  395. return;
  396. }
  397. const absl::Span<const char> contents(pbase(),
  398. static_cast<size_t>(pptr() - pbase()));
  399. if (contents.empty()) return;
  400. encoded_remaining_copy_.remove_prefix(contents.size());
  401. EncodeMessageLength(string_start_, &encoded_remaining_copy_);
  402. EncodeMessageLength(message_start_, &encoded_remaining_copy_);
  403. data_.encoded_remaining = encoded_remaining_copy_;
  404. }
  405. std::ostream& LogMessage::OstreamView::stream() { return data_.manipulated; }
  406. bool LogMessage::IsFatal() const {
  407. return data_->entry.log_severity() == absl::LogSeverity::kFatal &&
  408. absl::log_internal::ExitOnDFatal();
  409. }
  410. void LogMessage::PrepareToDie() {
  411. // If we log a FATAL message, flush all the log destinations, then toss
  412. // a signal for others to catch. We leave the logs in a state that
  413. // someone else can use them (as long as they flush afterwards)
  414. if (data_->first_fatal) {
  415. // Notify observers about the upcoming fatal error.
  416. ABSL_INTERNAL_C_SYMBOL(AbslInternalOnFatalLogMessage)(data_->entry);
  417. }
  418. if (!data_->fail_quietly) {
  419. // Log the message first before we start collecting stack trace.
  420. log_internal::LogToSinks(data_->entry, absl::MakeSpan(data_->extra_sinks),
  421. data_->extra_sinks_only);
  422. // `DumpStackTrace` generates an empty string under MSVC.
  423. // Adding the constant prefix here simplifies testing.
  424. data_->entry.stacktrace_ = "*** Check failure stack trace: ***\n";
  425. debugging_internal::DumpStackTrace(
  426. 0, log_internal::MaxFramesInLogStackTrace(),
  427. log_internal::ShouldSymbolizeLogStackTrace(), WriteToString,
  428. &data_->entry.stacktrace_);
  429. }
  430. }
  431. void LogMessage::Die() {
  432. absl::FlushLogSinks();
  433. if (data_->fail_quietly) {
  434. FailQuietly();
  435. } else {
  436. FailWithoutStackTrace();
  437. }
  438. }
  439. void LogMessage::SendToLog() {
  440. if (IsFatal()) PrepareToDie();
  441. // Also log to all registered sinks, even if OnlyLogToStderr() is set.
  442. log_internal::LogToSinks(data_->entry, absl::MakeSpan(data_->extra_sinks),
  443. data_->extra_sinks_only);
  444. if (IsFatal()) Die();
  445. }
  446. void LogMessage::LogBacktraceIfNeeded() {
  447. if (!absl::log_internal::IsInitialized()) return;
  448. if (!absl::log_internal::ShouldLogBacktraceAt(data_->entry.source_basename(),
  449. data_->entry.source_line()))
  450. return;
  451. OstreamView view(*data_);
  452. view.stream() << " (stacktrace:\n";
  453. debugging_internal::DumpStackTrace(
  454. 1, log_internal::MaxFramesInLogStackTrace(),
  455. log_internal::ShouldSymbolizeLogStackTrace(), WriteToStream,
  456. &view.stream());
  457. view.stream() << ") ";
  458. }
  459. // Encodes into `data_->encoded_remaining` a partial `logging.proto.Event`
  460. // containing the specified string data using a `Value` field appropriate to
  461. // `str_type`. Truncates `str` if necessary, but emits nothing and marks the
  462. // buffer full if even the field headers do not fit.
  463. void LogMessage::CopyToEncodedBuffer(absl::string_view str,
  464. StringType str_type) {
  465. auto encoded_remaining_copy = data_->encoded_remaining;
  466. auto start = EncodeMessageStart(
  467. EventTag::kValue, BufferSizeFor(WireType::kLengthDelimited) + str.size(),
  468. &encoded_remaining_copy);
  469. // If the `logging.proto.Event.value` field header did not fit,
  470. // `EncodeMessageStart` will have zeroed `encoded_remaining_copy`'s size and
  471. // `EncodeStringTruncate` will fail too.
  472. if (EncodeStringTruncate(str_type == StringType::kLiteral
  473. ? ValueTag::kStringLiteral
  474. : ValueTag::kString,
  475. str, &encoded_remaining_copy)) {
  476. // The string may have been truncated, but the field header fit.
  477. EncodeMessageLength(start, &encoded_remaining_copy);
  478. data_->encoded_remaining = encoded_remaining_copy;
  479. } else {
  480. // The field header(s) did not fit; zero `encoded_remaining` so we don't
  481. // write anything else later.
  482. data_->encoded_remaining.remove_suffix(data_->encoded_remaining.size());
  483. }
  484. }
  485. void LogMessage::CopyToEncodedBuffer(char ch, size_t num, StringType str_type) {
  486. auto encoded_remaining_copy = data_->encoded_remaining;
  487. auto value_start = EncodeMessageStart(
  488. EventTag::kValue, BufferSizeFor(WireType::kLengthDelimited) + num,
  489. &encoded_remaining_copy);
  490. auto str_start = EncodeMessageStart(str_type == StringType::kLiteral
  491. ? ValueTag::kStringLiteral
  492. : ValueTag::kString,
  493. num, &encoded_remaining_copy);
  494. if (str_start.data()) {
  495. // The field headers fit.
  496. log_internal::AppendTruncated(ch, num, encoded_remaining_copy);
  497. EncodeMessageLength(str_start, &encoded_remaining_copy);
  498. EncodeMessageLength(value_start, &encoded_remaining_copy);
  499. data_->encoded_remaining = encoded_remaining_copy;
  500. } else {
  501. // The field header(s) did not fit; zero `encoded_remaining` so we don't
  502. // write anything else later.
  503. data_->encoded_remaining.remove_suffix(data_->encoded_remaining.size());
  504. }
  505. }
  506. LogMessageFatal::LogMessageFatal(const char* file, int line)
  507. : LogMessage(file, line, absl::LogSeverity::kFatal) {}
  508. LogMessageFatal::LogMessageFatal(const char* file, int line,
  509. absl::string_view failure_msg)
  510. : LogMessage(file, line, absl::LogSeverity::kFatal) {
  511. *this << "Check failed: " << failure_msg << " ";
  512. }
  513. // ABSL_ATTRIBUTE_NORETURN doesn't seem to work on destructors with msvc, so
  514. // disable msvc's warning about the d'tor never returning.
  515. #if defined(_MSC_VER) && !defined(__clang__)
  516. #pragma warning(push)
  517. #pragma warning(disable : 4722)
  518. #endif
  519. LogMessageFatal::~LogMessageFatal() {
  520. Flush();
  521. FailWithoutStackTrace();
  522. }
  523. #if defined(_MSC_VER) && !defined(__clang__)
  524. #pragma warning(pop)
  525. #endif
  526. LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line)
  527. : LogMessage(file, line, absl::LogSeverity::kFatal) {
  528. SetFailQuietly();
  529. }
  530. LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line,
  531. absl::string_view failure_msg)
  532. : LogMessage(file, line, absl::LogSeverity::kFatal) {
  533. SetFailQuietly();
  534. *this << "Check failed: " << failure_msg << " ";
  535. }
  536. // ABSL_ATTRIBUTE_NORETURN doesn't seem to work on destructors with msvc, so
  537. // disable msvc's warning about the d'tor never returning.
  538. #if defined(_MSC_VER) && !defined(__clang__)
  539. #pragma warning(push)
  540. #pragma warning(disable : 4722)
  541. #endif
  542. LogMessageQuietlyFatal::~LogMessageQuietlyFatal() {
  543. Flush();
  544. FailQuietly();
  545. }
  546. #if defined(_MSC_VER) && !defined(__clang__)
  547. #pragma warning(pop)
  548. #endif
  549. } // namespace log_internal
  550. ABSL_NAMESPACE_END
  551. } // namespace absl