blob: 96f17b9847e8ae36ecd1f3e830d5bccabfdd514c [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2020 The Chromium Authors
Hans Wennborg12aea3e2020-04-14 15:29:002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_CHECK_H_
6#define BASE_CHECK_H_
7
8#include <iosfwd>
mikt2db0a942024-02-27 05:19:549#include <memory>
Hans Wennborg12aea3e2020-04-14 15:29:0010
11#include "base/base_export.h"
12#include "base/compiler_specific.h"
Hans Wennborg944479f2020-06-25 21:39:2513#include "base/dcheck_is_on.h"
Hans Wennborg12aea3e2020-04-14 15:29:0014#include "base/immediate_crash.h"
Peter Boströmd4ec69f22023-04-04 17:46:5515#include "base/location.h"
Peter Boström25052092023-12-09 00:27:2416#include "base/macros/if.h"
17#include "base/macros/is_empty.h"
18#include "base/not_fatal_until.h"
Hans Wennborg12aea3e2020-04-14 15:29:0019
20// This header defines the CHECK, DCHECK, and DPCHECK macros.
21//
22// CHECK dies with a fatal error if its condition is not true. It is not
23// controlled by NDEBUG, so the check will be executed regardless of compilation
24// mode.
25//
26// DCHECK, the "debug mode" check, is enabled depending on NDEBUG and
27// DCHECK_ALWAYS_ON, and its severity depends on DCHECK_IS_CONFIGURABLE.
28//
29// (D)PCHECK is like (D)CHECK, but includes the system error code (c.f.
30// perror(3)).
31//
32// Additional information can be streamed to these macros and will be included
33// in the log output if the condition doesn't hold (you may need to include
34// <ostream>):
35//
36// CHECK(condition) << "Additional info.";
37//
38// The condition is evaluated exactly once. Even in build modes where e.g.
39// DCHECK is disabled, the condition and any stream arguments are still
40// referenced to avoid warnings about unused variables and functions.
41//
Peter Boström25052092023-12-09 00:27:2442// An optional base::NotFatalUntil argument can be provided to make the
43// instance non-fatal (dumps without crashing) before a provided milestone. That
44// is: CHECK(false, base::NotFatalUntil::M120); starts crashing in M120. CHECKs
45// with a milestone argument preserve logging even in official builds, and
46// will upload the CHECK's log message in crash reports for remote diagnostics.
47// This is recommended for use in situations that are not flag guarded, or where
48// we have low pre-stable coverage. Using this lets us probe for would-be CHECK
49// failures for a milestone or two before rolling out a CHECK.
50//
Hans Wennborg12aea3e2020-04-14 15:29:0051// For the (D)CHECK_EQ, etc. macros, see base/check_op.h. However, that header
52// is *significantly* larger than check.h, so try to avoid including it in
53// header files.
54
55namespace logging {
56
Peter Boströmc9dda6492022-11-03 22:27:2657// Class used to explicitly ignore an ostream, and optionally a boolean value.
58class VoidifyStream {
59 public:
60 VoidifyStream() = default;
Brett Brothertonf161a06a2022-11-11 18:20:2461 explicit VoidifyStream(bool) {}
Peter Boströmc9dda6492022-11-03 22:27:2662
Adam Ricece0a8f952023-11-17 00:32:0063 // Binary & has lower precedence than << but higher than ?:
Peter Boströmc9dda6492022-11-03 22:27:2664 void operator&(std::ostream&) {}
65};
Hans Wennborg12aea3e2020-04-14 15:29:0066
67// Macro which uses but does not evaluate expr and any stream parameters.
68#define EAT_CHECK_STREAM_PARAMS(expr) \
69 true ? (void)0 \
70 : ::logging::VoidifyStream(expr) & (*::logging::g_swallow_stream)
71BASE_EXPORT extern std::ostream* g_swallow_stream;
72
Hans Wennborg12aea3e2020-04-14 15:29:0073class LogMessage;
74
75// Class used for raising a check error upon destruction.
76class BASE_EXPORT CheckError {
77 public:
Peter Boströmce41a1e982025-03-12 04:36:4678 // Takes ownership of `log_message`.
79 explicit CheckError(LogMessage* log_message);
80
Peter Boström5f34e2f2024-12-19 01:07:5481 // All instances that take a base::Location should use
82 // base::Location::CurrentWithoutFunctionName() by default since we
83 // immediately pass file_name() and line_number() to LogMessage's constructor
84 // and discard the function_name() anyways. This saves ~23k on the Android
85 // size bots (as of 2024-12-17) but that's the official build that barely uses
86 // these for CHECKs. The size gains are believed to be significantly larger on
87 // developer builds and official+DCHECK where all CHECK failures generate
88 // logs.
89
Peter Boströmce41a1e982025-03-12 04:36:4690 // TODO(pbos): Make all static methods that currently return some version of
91 // CheckError return LogMessage*.
Peter Boström5f34e2f2024-12-19 01:07:5492 static CheckError Check(const char* condition,
93 base::NotFatalUntil fatal_milestone,
94 const base::Location& location =
95 base::Location::CurrentWithoutFunctionName());
Peter Boströme7a8bbd2023-05-12 06:59:1796 // Takes ownership over (free()s after using) `log_message_str`, for use with
97 // CHECK_op macros.
Peter Boströmce41a1e982025-03-12 04:36:4698 static LogMessage* CheckOp(char* log_message_str,
99 base::NotFatalUntil fatal_milestone,
100 const base::Location& location =
101 base::Location::CurrentWithoutFunctionName());
Hans Wennborg12aea3e2020-04-14 15:29:00102
Peter Boström5f34e2f2024-12-19 01:07:54103 static CheckError DCheck(const char* condition,
104 const base::Location& location =
105 base::Location::CurrentWithoutFunctionName());
Peter Boströme7a8bbd2023-05-12 06:59:17106 // Takes ownership over (free()s after using) `log_message_str`, for use with
107 // DCHECK_op macros.
Peter Boströmce41a1e982025-03-12 04:36:46108 static LogMessage* DCheckOp(char* log_message_str,
109 const base::Location& location =
110 base::Location::CurrentWithoutFunctionName());
Hans Wennborg12aea3e2020-04-14 15:29:00111
Peter Boströmbc4629d2023-05-09 03:21:38112 static CheckError DumpWillBeCheck(
113 const char* condition,
Peter Boström5f34e2f2024-12-19 01:07:54114 const base::Location& location =
115 base::Location::CurrentWithoutFunctionName());
Peter Boströmbf475822023-05-17 17:17:50116 // Takes ownership over (free()s after using) `log_message_str`, for use with
117 // DUMP_WILL_BE_CHECK_op macros.
Peter Boströmce41a1e982025-03-12 04:36:46118 static LogMessage* DumpWillBeCheckOp(
Peter Boströmbf475822023-05-17 17:17:50119 char* log_message_str,
Peter Boström5f34e2f2024-12-19 01:07:54120 const base::Location& location =
121 base::Location::CurrentWithoutFunctionName());
Peter Boströmbc4629d2023-05-09 03:21:38122
Peter Boström5f34e2f2024-12-19 01:07:54123 static CheckError DPCheck(const char* condition,
124 const base::Location& location =
125 base::Location::CurrentWithoutFunctionName());
Hans Wennborg12aea3e2020-04-14 15:29:00126
Peter Boström7c561ce32023-05-11 22:18:01127 static CheckError NotImplemented(
128 const char* function,
Peter Boström5f34e2f2024-12-19 01:07:54129 const base::Location& location =
130 base::Location::CurrentWithoutFunctionName());
Hans Wennborg0472f8c2020-04-23 19:27:27131
Hans Wennborg12aea3e2020-04-14 15:29:00132 // Stream for adding optional details to the error message.
133 std::ostream& stream();
134
Peter Boströma1021e12023-01-19 04:02:40135 // Try really hard to get the call site and callee as separate stack frames in
136 // crash reports.
137 NOMERGE NOINLINE NOT_TAIL_CALLED ~CheckError();
Hans Wennborg12aea3e2020-04-14 15:29:00138
Peter Boström67c8f16d2022-06-23 21:58:29139 CheckError(const CheckError&) = delete;
140 CheckError& operator=(const CheckError&) = delete;
Hans Wennborg12aea3e2020-04-14 15:29:00141
Peter Boström2b2875bb2022-10-28 23:50:15142 template <typename T>
Peter Boströmabe94942025-03-10 21:51:10143 CheckError& operator<<(T&& streamed_type) {
144 stream() << streamed_type;
145 return *this;
Peter Boström2b2875bb2022-10-28 23:50:15146 }
147
Peter Boström92cdf19b2023-02-06 18:52:29148 protected:
mikt2db0a942024-02-27 05:19:54149 std::unique_ptr<LogMessage> log_message_;
Hans Wennborg12aea3e2020-04-14 15:29:00150};
151
Peter Boström7b1ecd862024-11-28 02:50:40152// Used for NOTREACHED(), its destructor is importantly [[noreturn]].
153class BASE_EXPORT CheckNoreturnError : public CheckError {
154 public:
155 [[noreturn]] NOMERGE NOINLINE NOT_TAIL_CALLED ~CheckNoreturnError();
156
157 static CheckNoreturnError Check(
158 const char* condition,
Peter Boström5f34e2f2024-12-19 01:07:54159 const base::Location& location =
160 base::Location::CurrentWithoutFunctionName());
Peter Boström7b1ecd862024-11-28 02:50:40161 // Takes ownership over (free()s after using) `log_message_str`, for use with
162 // CHECK_op macros.
Peter Boströmce41a1e982025-03-12 04:36:46163 static LogMessage* CheckOp(char* log_message_str,
164 const base::Location& location =
165 base::Location::CurrentWithoutFunctionName());
Peter Boström7b1ecd862024-11-28 02:50:40166
167 static CheckNoreturnError PCheck(
168 const char* condition,
Peter Boström5f34e2f2024-12-19 01:07:54169 const base::Location& location =
170 base::Location::CurrentWithoutFunctionName());
Peter Boström7b1ecd862024-11-28 02:50:40171 static CheckNoreturnError PCheck(
Peter Boström5f34e2f2024-12-19 01:07:54172 const base::Location& location =
173 base::Location::CurrentWithoutFunctionName());
Taiyo Mizuhashiba9a0c42024-12-18 18:39:35174
175 private:
176 using CheckError::CheckError;
Peter Boström7b1ecd862024-11-28 02:50:40177};
178
179// Used for NOTREACHED(base::NotFatalUntil) and DUMP_WILL_BE_NOTREACHED().
Peter Boströmd7df6242022-12-13 18:05:40180class BASE_EXPORT NotReachedError : public CheckError {
181 public:
Peter Boströmd4ec69f22023-04-04 17:46:55182 static NotReachedError NotReached(
Peter Boströme2384622024-11-15 00:46:51183 base::NotFatalUntil fatal_milestone,
Peter Boström5f34e2f2024-12-19 01:07:54184 const base::Location& location =
185 base::Location::CurrentWithoutFunctionName());
Peter Boströmd7df6242022-12-13 18:05:40186
Peter Boström7b1ecd862024-11-28 02:50:40187 static NotReachedError DumpWillBeNotReached(
Peter Boström5f34e2f2024-12-19 01:07:54188 const base::Location& location =
189 base::Location::CurrentWithoutFunctionName());
Peter Boström7b1ecd862024-11-28 02:50:40190
Peter Boströma1021e12023-01-19 04:02:40191 NOMERGE NOINLINE NOT_TAIL_CALLED ~NotReachedError();
Peter Boströmd7df6242022-12-13 18:05:40192
193 private:
194 using CheckError::CheckError;
195};
196
Peter Boströme2384622024-11-15 00:46:51197// Used for NOTREACHED(), its destructor is importantly [[noreturn]].
Peter Boström92cdf19b2023-02-06 18:52:29198class BASE_EXPORT NotReachedNoreturnError : public CheckError {
199 public:
Peter Boström7c561ce32023-05-11 22:18:01200 explicit NotReachedNoreturnError(
Peter Boström5f34e2f2024-12-19 01:07:54201 const base::Location& location =
202 base::Location::CurrentWithoutFunctionName());
Peter Boström92cdf19b2023-02-06 18:52:29203
204 [[noreturn]] NOMERGE NOINLINE NOT_TAIL_CALLED ~NotReachedNoreturnError();
205};
206
Daniel Cheng27f4a25f2023-06-07 00:20:51207// A helper macro for checks that log to streams that makes it easier for the
208// compiler to identify and warn about dead code, e.g.:
209//
210// return 2;
Peter Boström8c29f4a2024-05-08 01:12:11211// NOTREACHED_IN_MIGRATION();
Daniel Cheng27f4a25f2023-06-07 00:20:51212//
Peter Boströmc9dda6492022-11-03 22:27:26213// The 'switch' is used to prevent the 'else' from being ambiguous when the
214// macro is used in an 'if' clause such as:
215// if (a == 1)
216// CHECK(Foo());
217//
Peter Boströmf9d97ed92024-11-26 19:12:30218// The weird ternary is to still generate an "is not contextually convertible to
219// 'bool' when provided weird parameters (regardless of ANALYZER_ASSUME_TRUE's
220// implementation). See base/check_nocompile.nc.
Peter Boström7a747d82025-02-25 03:38:23221//
222// The lambda is here to here permit the compiler to out-of-line much of the
223// CHECK-failure path and optimize better for the fast path.
Peter Boströmf9d97ed92024-11-26 19:12:30224#define LOGGING_CHECK_FUNCTION_IMPL(check_stream, condition) \
225 switch (0) \
226 case 0: \
227 default: \
228 if (ANALYZER_ASSUME_TRUE((condition) ? true : false)) \
229 [[likely]]; \
230 else \
Peter Boström7a747d82025-02-25 03:38:23231 [&]() { return (check_stream); }()
Peter Boström2f8318f2022-10-12 03:28:29232
Peter Boströmf9d97ed92024-11-26 19:12:30233// A helper macro like LOGGING_CHECK_FUNCTION_IMPL above but discarding any
234// log-stream parameters rather than evaluate them on failure.
235#define DISCARDING_CHECK_FUNCTION_IMPL(check_failure, condition) \
236 switch (0) \
237 case 0: \
238 default: \
239 if (!ANALYZER_ASSUME_TRUE((condition) ? true : false)) \
240 check_failure; \
241 else [[likely]] \
242 EAT_CHECK_STREAM_PARAMS()
243
Peter Boströmd0a383c2022-10-29 04:09:12244#if defined(OFFICIAL_BUILD) && !defined(NDEBUG)
245#error "Debug builds are not expected to be optimized as official builds."
246#endif // defined(OFFICIAL_BUILD) && !defined(NDEBUG)
Hans Wennborg12aea3e2020-04-14 15:29:00247
Peter Boströmd0a383c2022-10-29 04:09:12248#if defined(OFFICIAL_BUILD) && !DCHECK_IS_ON()
Peter Boströmb010f7b2024-11-12 02:57:16249
250// Official non-DCHECK builds do not preserve CHECK() logging (including
251// evaluation of logging arguments). This generates more compact code which is
252// good for both speed and binary size.
253#define CHECK_WILL_STREAM() false
254
Peter Boströmb30544d2022-10-21 00:17:58255// Note that this uses IMMEDIATE_CRASH_ALWAYS_INLINE to force-inline in debug
256// mode as well. See LoggingTest.CheckCausesDistinctBreakpoints.
Peter Boström7c6383002024-09-10 11:15:35257[[noreturn]] NOMERGE IMMEDIATE_CRASH_ALWAYS_INLINE void CheckFailure() {
Peter Boström25c6ec72022-11-02 23:25:19258 base::ImmediateCrash();
Peter Boströmb30544d2022-10-21 00:17:58259}
260
Peter Boström25052092023-12-09 00:27:24261// Discard log strings to reduce code bloat when there is no NotFatalUntil
262// argument (which temporarily preserves logging both locally and in crash
263// reports).
Peter Boströmd20dbbd2024-11-27 01:29:57264#define CHECK_INTERNAL_IMPL(cond) \
265 DISCARDING_CHECK_FUNCTION_IMPL(::logging::CheckFailure(), cond)
Hans Wennborg12aea3e2020-04-14 15:29:00266
267#else
268
Peter Boströmb010f7b2024-11-12 02:57:16269// Generate logging versions of CHECKs to help diagnosing failures.
Gabriel Charettefe051042022-01-19 09:27:29270#define CHECK_WILL_STREAM() true
271
Peter Boströmd20dbbd2024-11-27 01:29:57272#define CHECK_INTERNAL_IMPL(cond) \
Peter Boström7b1ecd862024-11-28 02:50:40273 LOGGING_CHECK_FUNCTION_IMPL(::logging::CheckNoreturnError::Check(#cond), cond)
Hans Wennborg12aea3e2020-04-14 15:29:00274
275#endif
276
Peter Boströmd20dbbd2024-11-27 01:29:57277#define CHECK(cond, ...) \
278 BASE_IF(BASE_IS_EMPTY(__VA_ARGS__), CHECK_INTERNAL_IMPL(cond), \
279 LOGGING_CHECK_FUNCTION_IMPL( \
280 logging::CheckError::Check(#cond, __VA_ARGS__), cond))
281
282// Strip the conditional string based on CHECK_WILL_STREAM()
Peter Boström7b1ecd862024-11-28 02:50:40283#define PCHECK(cond) \
284 LOGGING_CHECK_FUNCTION_IMPL( \
285 BASE_IF(CHECK_WILL_STREAM(), \
286 ::logging::CheckNoreturnError::PCheck(#cond), \
287 ::logging::CheckNoreturnError::PCheck()), \
Peter Boströmd20dbbd2024-11-27 01:29:57288 cond)
289
Hans Wennborg12aea3e2020-04-14 15:29:00290#if DCHECK_IS_ON()
291
Daniel Cheng27f4a25f2023-06-07 00:20:51292#define DCHECK(condition) \
293 LOGGING_CHECK_FUNCTION_IMPL(::logging::CheckError::DCheck(#condition), \
294 condition)
295#define DPCHECK(condition) \
296 LOGGING_CHECK_FUNCTION_IMPL(::logging::CheckError::DPCheck(#condition), \
297 condition)
Hans Wennborg12aea3e2020-04-14 15:29:00298
299#else
300
301#define DCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
302#define DPCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
303
Peter Boströmbc4629d2023-05-09 03:21:38304#endif // DCHECK_IS_ON()
305
306// The DUMP_WILL_BE_CHECK() macro provides a convenient way to non-fatally dump
307// in official builds if a condition is false. This is used to more cautiously
308// roll out a new CHECK() (or upgrade a DCHECK) where the caller isn't entirely
309// sure that something holds true in practice (but asserts that it should). This
310// is especially useful for platforms that have a low pre-stable population and
311// code areas that are rarely exercised.
312//
313// On DCHECK builds this macro matches DCHECK behavior.
314//
315// This macro isn't optimized (preserves filename, line number and log messages
316// in official builds), as they are expected to be in product temporarily. When
317// using this macro, leave a TODO(crbug.com/nnnn) entry referring to a bug
318// related to its rollout. Then put a NextAction on the bug to come back and
319// clean this up (replace with a CHECK). A DUMP_WILL_BE_CHECK() that's been left
320// untouched for a long time without bug updates suggests that issues that
321// would've prevented enabling this CHECK have either not been discovered or
322// have been resolved.
323//
324// Using this macro is preferred over direct base::debug::DumpWithoutCrashing()
325// invocations as it communicates intent to eventually end up as a CHECK. It
326// also preserves the log message so setting crash keys to get additional debug
327// info isn't required as often.
Peter Boström25052092023-12-09 00:27:24328#define DUMP_WILL_BE_CHECK(condition, ...) \
329 LOGGING_CHECK_FUNCTION_IMPL(::logging::CheckError::DumpWillBeCheck( \
330 #condition __VA_OPT__(, ) __VA_ARGS__), \
331 condition)
Hans Wennborg12aea3e2020-04-14 15:29:00332
333// Async signal safe checking mechanism.
Peter Boströmefa8c002023-04-28 02:33:53334[[noreturn]] BASE_EXPORT void RawCheckFailure(const char* message);
335#define RAW_CHECK(condition) \
336 do { \
Peter Kastingfa488992024-08-06 07:48:14337 if (!(condition)) [[unlikely]] { \
Peter Boströmefa8c002023-04-28 02:33:53338 ::logging::RawCheckFailure("Check failed: " #condition "\n"); \
339 } \
Hans Wennborg12aea3e2020-04-14 15:29:00340 } while (0)
341
342} // namespace logging
343
344#endif // BASE_CHECK_H_