/src/abseil-cpp/absl/log/internal/log_message.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2022 The Abseil Authors. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | // |
15 | | // ----------------------------------------------------------------------------- |
16 | | // File: log/internal/log_message.h |
17 | | // ----------------------------------------------------------------------------- |
18 | | // |
19 | | // This file declares `class absl::log_internal::LogMessage`. This class more or |
20 | | // less represents a particular log message. LOG/CHECK macros create a temporary |
21 | | // instance of `LogMessage` and then stream values to it. At the end of the |
22 | | // LOG/CHECK statement, the LogMessage is voidified by operator&&, and `Flush()` |
23 | | // directs the message to the registered log sinks. Heap-allocation of |
24 | | // `LogMessage` is unsupported. Construction outside of a `LOG` macro is |
25 | | // unsupported. |
26 | | |
27 | | #ifndef ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |
28 | | #define ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |
29 | | |
30 | | #include <wchar.h> |
31 | | |
32 | | #include <cstddef> |
33 | | #include <ios> |
34 | | #include <memory> |
35 | | #include <ostream> |
36 | | #include <streambuf> |
37 | | #include <string> |
38 | | #include <string_view> |
39 | | #include <type_traits> |
40 | | |
41 | | #include "absl/base/attributes.h" |
42 | | #include "absl/base/config.h" |
43 | | #include "absl/base/internal/errno_saver.h" |
44 | | #include "absl/base/log_severity.h" |
45 | | #include "absl/base/nullability.h" |
46 | | #include "absl/log/internal/nullguard.h" |
47 | | #include "absl/log/internal/structured_proto.h" |
48 | | #include "absl/log/log_entry.h" |
49 | | #include "absl/log/log_sink.h" |
50 | | #include "absl/strings/has_absl_stringify.h" |
51 | | #include "absl/strings/string_view.h" |
52 | | #include "absl/time/time.h" |
53 | | |
54 | | namespace absl { |
55 | | ABSL_NAMESPACE_BEGIN |
56 | | namespace log_internal { |
57 | | constexpr int kLogMessageBufferSize = 15000; |
58 | | |
59 | | enum class StructuredStringType; |
60 | | |
61 | | class LogMessage { |
62 | | public: |
63 | | struct InfoTag {}; |
64 | | struct WarningTag {}; |
65 | | struct ErrorTag {}; |
66 | | |
67 | | // Used for `LOG`. |
68 | | LogMessage(const char* absl_nonnull file, int line, |
69 | | absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD; |
70 | | // These constructors are slightly smaller/faster to call; the severity is |
71 | | // curried into the function pointer. |
72 | | LogMessage(const char* absl_nonnull file, int line, |
73 | | InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
74 | | LogMessage(const char* absl_nonnull file, int line, |
75 | | WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
76 | | LogMessage(const char* absl_nonnull file, int line, |
77 | | ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
78 | | LogMessage(const LogMessage&) = delete; |
79 | | LogMessage& operator=(const LogMessage&) = delete; |
80 | | ~LogMessage() ABSL_ATTRIBUTE_COLD; |
81 | | |
82 | | // Overrides the location inferred from the callsite. The string pointed to |
83 | | // by `file` must be valid until the end of the statement. |
84 | | LogMessage& AtLocation(absl::string_view file, int line); |
85 | | // Omits the prefix from this line. The prefix includes metadata about the |
86 | | // logged data such as source code location and timestamp. |
87 | | LogMessage& NoPrefix(); |
88 | | // Sets the verbosity field of the logged message as if it was logged by |
89 | | // `VLOG(verbose_level)`. Unlike `VLOG`, this method does not affect |
90 | | // evaluation of the statement when the specified `verbose_level` has been |
91 | | // disabled. The only effect is on `absl::LogSink` implementations which |
92 | | // make use of the `absl::LogSink::verbosity()` value. The value |
93 | | // `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message |
94 | | // not verbose. |
95 | | LogMessage& WithVerbosity(int verbose_level); |
96 | | // Uses the specified timestamp instead of one collected in the constructor. |
97 | | LogMessage& WithTimestamp(absl::Time timestamp); |
98 | | // Uses the specified thread ID instead of one collected in the constructor. |
99 | | LogMessage& WithThreadID(absl::LogEntry::tid_t tid); |
100 | | // Copies all metadata (but no data) from the specified `absl::LogEntry`. |
101 | | LogMessage& WithMetadataFrom(const absl::LogEntry& entry); |
102 | | // Appends to the logged message a colon, a space, a textual description of |
103 | | // the current value of `errno` (as by strerror(3)), and the numerical value |
104 | | // of `errno`. |
105 | | LogMessage& WithPerror(); |
106 | | // Sends this message to `*sink` in addition to whatever other sinks it would |
107 | | // otherwise have been sent to. |
108 | | LogMessage& ToSinkAlso(absl::LogSink* absl_nonnull sink); |
109 | | // Sends this message to `*sink` and no others. |
110 | | LogMessage& ToSinkOnly(absl::LogSink* absl_nonnull sink); |
111 | | |
112 | | // Don't call this method from outside this library. |
113 | 0 | LogMessage& InternalStream() { return *this; } |
114 | | |
115 | | // By-value overloads for small, common types let us overlook common failures |
116 | | // to define globals and static data members (i.e. in a .cc file). |
117 | | // NOLINTBEGIN(runtime/int) |
118 | | // NOLINTBEGIN(google-runtime-int) |
119 | | // clang-format off: The CUDA toolchain cannot handle these <<<'s |
120 | 0 | LogMessage& operator<<(char v) { return operator<< <char>(v); } |
121 | 0 | LogMessage& operator<<(signed char v) { return operator<< <signed char>(v); } |
122 | 0 | LogMessage& operator<<(unsigned char v) { |
123 | 0 | return operator<< <unsigned char>(v); |
124 | 0 | } |
125 | 0 | LogMessage& operator<<(signed short v) { |
126 | 0 | return operator<< <signed short>(v); |
127 | 0 | } |
128 | 0 | LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); } |
129 | 0 | LogMessage& operator<<(signed long v) { |
130 | 0 | return operator<< <signed long>(v); |
131 | 0 | } |
132 | 0 | LogMessage& operator<<(signed long long v) { |
133 | 0 | return operator<< <signed long long>(v); |
134 | 0 | } |
135 | 0 | LogMessage& operator<<(unsigned short v) { |
136 | 0 | return operator<< <unsigned short>(v); |
137 | 0 | } |
138 | 0 | LogMessage& operator<<(unsigned int v) { |
139 | 0 | return operator<< <unsigned int>(v); |
140 | 0 | } |
141 | 0 | LogMessage& operator<<(unsigned long v) { |
142 | 0 | return operator<< <unsigned long>(v); |
143 | 0 | } |
144 | 0 | LogMessage& operator<<(unsigned long long v) { |
145 | 0 | return operator<< <unsigned long long>(v); |
146 | 0 | } |
147 | 0 | LogMessage& operator<<(void* absl_nullable v) { |
148 | 0 | return operator<< <void*>(v); |
149 | 0 | } |
150 | 0 | LogMessage& operator<<(const void* absl_nullable v) { |
151 | 0 | return operator<< <const void*>(v); |
152 | 0 | } |
153 | 0 | LogMessage& operator<<(float v) { return operator<< <float>(v); } |
154 | 0 | LogMessage& operator<<(double v) { return operator<< <double>(v); } |
155 | 0 | LogMessage& operator<<(bool v) { return operator<< <bool>(v); } |
156 | | // clang-format on |
157 | | // NOLINTEND(google-runtime-int) |
158 | | // NOLINTEND(runtime/int) |
159 | | |
160 | | // These overloads are more efficient since no `ostream` is involved. |
161 | | LogMessage& operator<<(const std::string& v); |
162 | | LogMessage& operator<<(absl::string_view v); |
163 | | |
164 | | // Wide string overloads (since std::ostream does not provide them). |
165 | | LogMessage& operator<<(const std::wstring& v); |
166 | | LogMessage& operator<<(std::wstring_view v); |
167 | | // `const wchar_t*` is handled by `operator<< <const wchar_t*>`. |
168 | | LogMessage& operator<<(wchar_t* absl_nullable v); |
169 | | LogMessage& operator<<(wchar_t v); |
170 | | |
171 | | // Handle stream manipulators e.g. std::endl. |
172 | | LogMessage& operator<<(std::ostream& (*absl_nonnull m)(std::ostream& os)); |
173 | | LogMessage& operator<<(std::ios_base& (*absl_nonnull m)(std::ios_base& os)); |
174 | | |
175 | | // Literal strings. This allows us to record C string literals as literals in |
176 | | // the logging.proto.Value. |
177 | | // |
178 | | // Allow this overload to be inlined to prevent generating instantiations of |
179 | | // this template for every value of `SIZE` encountered in each source code |
180 | | // file. That significantly increases linker input sizes. Inlining is cheap |
181 | | // because the argument to this overload is almost always a string literal so |
182 | | // the call to `strlen` can be replaced at compile time. The overloads for |
183 | | // `char[]`/`wchar_t[]` below should not be inlined. The compiler typically |
184 | | // does not have the string at compile time and cannot replace the call to |
185 | | // `strlen` so inlining it increases the binary size. See the discussion on |
186 | | // cl/107527369. |
187 | | template <int SIZE> |
188 | | LogMessage& operator<<(const char (&buf)[SIZE]); |
189 | | template <int SIZE> |
190 | | LogMessage& operator<<(const wchar_t (&buf)[SIZE]); |
191 | | |
192 | | // This prevents non-const `char[]` arrays from looking like literals. |
193 | | template <int SIZE> |
194 | | LogMessage& operator<<(char (&buf)[SIZE]) ABSL_ATTRIBUTE_NOINLINE; |
195 | | // `wchar_t[SIZE]` is handled by `operator<< <const wchar_t*>`. |
196 | | |
197 | | // Types that support `AbslStringify()` are serialized that way. |
198 | | // Types that don't support `AbslStringify()` but do support streaming into a |
199 | | // `std::ostream&` are serialized that way. |
200 | | template <typename T> |
201 | | LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE; |
202 | | |
203 | | // Dispatches the completed `absl::LogEntry` to applicable `absl::LogSink`s. |
204 | | void Flush(); |
205 | | |
206 | | // Note: We explicitly do not support `operator<<` for non-const references |
207 | | // because it breaks logging of non-integer bitfield types (i.e., enums). |
208 | | |
209 | | protected: |
210 | | // Call `abort()` or similar to perform `LOG(FATAL)` crash. It is assumed |
211 | | // that the caller has already generated and written the trace as appropriate. |
212 | | [[noreturn]] static void FailWithoutStackTrace(); |
213 | | |
214 | | // Similar to `FailWithoutStackTrace()`, but without `abort()`. Terminates |
215 | | // the process with an error exit code. |
216 | | [[noreturn]] static void FailQuietly(); |
217 | | |
218 | | // After this is called, failures are done as quiet as possible for this log |
219 | | // message. |
220 | | void SetFailQuietly(); |
221 | | |
222 | | private: |
223 | | struct LogMessageData; // Opaque type containing message state |
224 | | friend class AsLiteralImpl; |
225 | | friend class StringifySink; |
226 | | template <StructuredStringType str_type> |
227 | | friend class AsStructuredStringTypeImpl; |
228 | | template <typename T> |
229 | | friend class AsStructuredValueImpl; |
230 | | |
231 | | // This streambuf writes directly into the structured logging buffer so that |
232 | | // arbitrary types can be encoded as string data (using |
233 | | // `operator<<(std::ostream &, ...)` without any extra allocation or copying. |
234 | | // Space is reserved before the data to store the length field, which is |
235 | | // filled in by `~OstreamView`. |
236 | | class OstreamView final : public std::streambuf { |
237 | | public: |
238 | | explicit OstreamView(LogMessageData& message_data); |
239 | | ~OstreamView() override; |
240 | | OstreamView(const OstreamView&) = delete; |
241 | | OstreamView& operator=(const OstreamView&) = delete; |
242 | | std::ostream& stream(); |
243 | | |
244 | | private: |
245 | | LogMessageData& data_; |
246 | | absl::Span<char> encoded_remaining_copy_; |
247 | | absl::Span<char> message_start_; |
248 | | absl::Span<char> string_start_; |
249 | | }; |
250 | | |
251 | | enum class StringType { |
252 | | kLiteral, |
253 | | kNotLiteral, |
254 | | }; |
255 | | template <StringType str_type> |
256 | | void CopyToEncodedBuffer(absl::string_view str) ABSL_ATTRIBUTE_NOINLINE; |
257 | | template <StringType str_type> |
258 | | void CopyToEncodedBuffer(char ch, size_t num) ABSL_ATTRIBUTE_NOINLINE; |
259 | | template <StringType str_type> |
260 | | void CopyToEncodedBuffer(std::wstring_view str) ABSL_ATTRIBUTE_NOINLINE; |
261 | | |
262 | | // Copies `field` to the encoded buffer, then appends `str` after it |
263 | | // (truncating `str` if necessary to fit). |
264 | | template <StringType str_type> |
265 | | void CopyToEncodedBufferWithStructuredProtoField(StructuredProtoField field, |
266 | | absl::string_view str) |
267 | | ABSL_ATTRIBUTE_NOINLINE; |
268 | | |
269 | | // Returns `true` if the message is fatal or enabled debug-fatal. |
270 | | bool IsFatal() const; |
271 | | |
272 | | // Records some tombstone-type data in anticipation of `Die`. |
273 | | void PrepareToDie(); |
274 | | void Die(); |
275 | | |
276 | | void SendToLog(); |
277 | | |
278 | | // Checks `FLAGS_log_backtrace_at` and appends a backtrace if appropriate. |
279 | | void LogBacktraceIfNeeded(); |
280 | | |
281 | | // This should be the first data member so that its initializer captures errno |
282 | | // before any other initializers alter it (e.g. with calls to new) and so that |
283 | | // no other destructors run afterward an alter it (e.g. with calls to delete). |
284 | | absl::base_internal::ErrnoSaver errno_saver_; |
285 | | |
286 | | // We keep the data in a separate struct so that each instance of `LogMessage` |
287 | | // uses less stack space. |
288 | | absl_nonnull std::unique_ptr<LogMessageData> data_; |
289 | | }; |
290 | | |
291 | | // Explicitly specializes the generic operator<< for `const wchar_t*` |
292 | | // arguments. |
293 | | // |
294 | | // This method is used instead of a non-template `const wchar_t*` overload, |
295 | | // as the latter was found to take precedence over the array template |
296 | | // (`operator<<(const wchar_t(&)[SIZE])`) when handling string literals. |
297 | | // This specialization ensures the array template now correctly processes |
298 | | // literals. |
299 | | template <> |
300 | | LogMessage& LogMessage::operator<< <const wchar_t*>( |
301 | | const wchar_t* absl_nullable const& v); |
302 | | |
303 | 0 | inline LogMessage& LogMessage::operator<<(wchar_t* absl_nullable v) { |
304 | 0 | return operator<<(const_cast<const wchar_t*>(v)); |
305 | 0 | } |
306 | | |
307 | | // Helper class so that `AbslStringify()` can modify the LogMessage. |
308 | | class StringifySink final { |
309 | | public: |
310 | 0 | explicit StringifySink(LogMessage& message) : message_(message) {} |
311 | | |
312 | 0 | void Append(size_t count, char ch) { |
313 | 0 | message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(ch, |
314 | 0 | count); |
315 | 0 | } |
316 | | |
317 | 0 | void Append(absl::string_view v) { |
318 | 0 | message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(v); |
319 | 0 | } |
320 | | |
321 | | // For types that implement `AbslStringify` using `absl::Format()`. |
322 | | friend void AbslFormatFlush(StringifySink* absl_nonnull sink, |
323 | 0 | absl::string_view v) { |
324 | 0 | sink->Append(v); |
325 | 0 | } |
326 | | |
327 | | private: |
328 | | LogMessage& message_; |
329 | | }; |
330 | | |
331 | | // Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE` |
332 | | template <typename T> |
333 | 0 | LogMessage& LogMessage::operator<<(const T& v) { |
334 | | if constexpr (absl::HasAbslStringify<T>::value) { |
335 | | StringifySink sink(*this); |
336 | | // Replace with public API. |
337 | | AbslStringify(sink, v); |
338 | 0 | } else { |
339 | 0 | OstreamView view(*data_); |
340 | 0 | view.stream() << log_internal::NullGuard<T>().Guard(v); |
341 | 0 | } |
342 | 0 | return *this; |
343 | 0 | } Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <char>(char const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <signed char>(signed char const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned char>(unsigned char const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <short>(short const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned short>(unsigned short const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <int>(int const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned int>(unsigned int const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <long>(long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned long>(unsigned long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <long long>(long long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned long long>(unsigned long long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <void*>(void* const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <void const*>(void const* const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <float>(float const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <double>(double const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <bool>(bool const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <char const*>(char const* const&) |
344 | | |
345 | | template <int SIZE> |
346 | 0 | LogMessage& LogMessage::operator<<(const char (&buf)[SIZE]) { |
347 | 0 | CopyToEncodedBuffer<StringType::kLiteral>(buf); |
348 | 0 | return *this; |
349 | 0 | } Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <3>(char const (&) [3]) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <2>(char const (&) [2]) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <15>(char const (&) [15]) |
350 | | |
351 | | template <int SIZE> |
352 | | LogMessage& LogMessage::operator<<(const wchar_t (&buf)[SIZE]) { |
353 | | CopyToEncodedBuffer<StringType::kLiteral>(buf); |
354 | | return *this; |
355 | | } |
356 | | |
357 | | // Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE` |
358 | | template <int SIZE> |
359 | | LogMessage& LogMessage::operator<<(char (&buf)[SIZE]) { |
360 | | CopyToEncodedBuffer<StringType::kNotLiteral>(buf); |
361 | | return *this; |
362 | | } |
363 | | // We instantiate these specializations in the library's TU to save space in |
364 | | // other TUs. Since the template is marked `ABSL_ATTRIBUTE_NOINLINE` we will be |
365 | | // emitting a function call either way. |
366 | | // NOLINTBEGIN(runtime/int) |
367 | | // NOLINTBEGIN(google-runtime-int) |
368 | | extern template LogMessage& LogMessage::operator<<(const char& v); |
369 | | extern template LogMessage& LogMessage::operator<<(const signed char& v); |
370 | | extern template LogMessage& LogMessage::operator<<(const unsigned char& v); |
371 | | extern template LogMessage& LogMessage::operator<<(const short& v); |
372 | | extern template LogMessage& LogMessage::operator<<(const unsigned short& v); |
373 | | extern template LogMessage& LogMessage::operator<<(const int& v); |
374 | | extern template LogMessage& LogMessage::operator<<(const unsigned int& v); |
375 | | extern template LogMessage& LogMessage::operator<<(const long& v); |
376 | | extern template LogMessage& LogMessage::operator<<(const unsigned long& v); |
377 | | extern template LogMessage& LogMessage::operator<<(const long long& v); |
378 | | extern template LogMessage& LogMessage::operator<<(const unsigned long long& v); |
379 | | extern template LogMessage& LogMessage::operator<<( |
380 | | void* absl_nullable const& v); |
381 | | extern template LogMessage& LogMessage::operator<<( |
382 | | const void* absl_nullable const& v); |
383 | | extern template LogMessage& LogMessage::operator<<(const float& v); |
384 | | extern template LogMessage& LogMessage::operator<<(const double& v); |
385 | | extern template LogMessage& LogMessage::operator<<(const bool& v); |
386 | | // NOLINTEND(google-runtime-int) |
387 | | // NOLINTEND(runtime/int) |
388 | | |
389 | | extern template void LogMessage::CopyToEncodedBuffer< |
390 | | LogMessage::StringType::kLiteral>(absl::string_view str); |
391 | | extern template void LogMessage::CopyToEncodedBuffer< |
392 | | LogMessage::StringType::kNotLiteral>(absl::string_view str); |
393 | | extern template void |
394 | | LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(char ch, |
395 | | size_t num); |
396 | | extern template void LogMessage::CopyToEncodedBuffer< |
397 | | LogMessage::StringType::kNotLiteral>(char ch, size_t num); |
398 | | extern template void LogMessage::CopyToEncodedBuffer< |
399 | | LogMessage::StringType::kLiteral>(std::wstring_view str); |
400 | | extern template void LogMessage::CopyToEncodedBuffer< |
401 | | LogMessage::StringType::kNotLiteral>(std::wstring_view str); |
402 | | |
403 | | // `LogMessageFatal` ensures the process will exit in failure after logging this |
404 | | // message. |
405 | | class LogMessageFatal final : public LogMessage { |
406 | | public: |
407 | | LogMessageFatal(const char* absl_nonnull file, int line) ABSL_ATTRIBUTE_COLD; |
408 | | LogMessageFatal(const char* absl_nonnull file, int line, |
409 | | const char* absl_nonnull failure_msg) ABSL_ATTRIBUTE_COLD; |
410 | | [[noreturn]] ~LogMessageFatal(); |
411 | | }; |
412 | | |
413 | | // `LogMessageDebugFatal` ensures the process will exit in failure after logging |
414 | | // this message. It matches LogMessageFatal but is not [[noreturn]] as it's used |
415 | | // for DLOG(FATAL) variants. |
416 | | class LogMessageDebugFatal final : public LogMessage { |
417 | | public: |
418 | | LogMessageDebugFatal(const char* absl_nonnull file, |
419 | | int line) ABSL_ATTRIBUTE_COLD; |
420 | | ~LogMessageDebugFatal(); |
421 | | }; |
422 | | |
423 | | class LogMessageQuietlyDebugFatal final : public LogMessage { |
424 | | public: |
425 | | // DLOG(QFATAL) calls this instead of LogMessageQuietlyFatal to make sure the |
426 | | // destructor is not [[noreturn]] even if this is always FATAL as this is only |
427 | | // invoked when DLOG() is enabled. |
428 | | LogMessageQuietlyDebugFatal(const char* absl_nonnull file, |
429 | | int line) ABSL_ATTRIBUTE_COLD; |
430 | | ~LogMessageQuietlyDebugFatal(); |
431 | | }; |
432 | | |
433 | | // Used for LOG(QFATAL) to make sure it's properly understood as [[noreturn]]. |
434 | | class LogMessageQuietlyFatal final : public LogMessage { |
435 | | public: |
436 | | LogMessageQuietlyFatal(const char* absl_nonnull file, |
437 | | int line) ABSL_ATTRIBUTE_COLD; |
438 | | LogMessageQuietlyFatal(const char* absl_nonnull file, int line, |
439 | | const char* absl_nonnull failure_msg) |
440 | | ABSL_ATTRIBUTE_COLD; |
441 | | [[noreturn]] ~LogMessageQuietlyFatal(); |
442 | | }; |
443 | | |
444 | | } // namespace log_internal |
445 | | ABSL_NAMESPACE_END |
446 | | } // namespace absl |
447 | | |
448 | | extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL( |
449 | | AbslInternalOnFatalLogMessage)(const absl::LogEntry&); |
450 | | |
451 | | #endif // ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |