log_message.cc 28 KB

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