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