• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors
2 // 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_NOTREACHED_H_
6 #define BASE_NOTREACHED_H_
7 
8 #include "base/base_export.h"
9 #include "base/check.h"
10 #include "base/dcheck_is_on.h"
11 #include "base/logging_buildflags.h"
12 
13 namespace logging {
14 
15 // NOTREACHED() annotates should-be unreachable code. Under the
16 // kNotReachedIsFatal experiment all NOTREACHED()s that happen after FeatureList
17 // initialization are fatal. As of 2023-06-06 this experiment is disabled
18 // everywhere.
19 //
20 // For paths that are intended to eventually be NOTREACHED() but are not yet
21 // ready for migration (stability risk, known pre-existing failures), consider
22 // the DUMP_WILL_BE_NOTREACHED_NORETURN() macro below.
23 //
24 // Outside the kNotReachedIsFatal experiment behavior is as follows:
25 //
26 // On DCHECK builds NOTREACHED() match the fatality of DCHECKs. When DCHECKs are
27 // non-FATAL a crash report will be generated for the first NOTREACHED() that
28 // hits per process.
29 //
30 // Outside DCHECK builds NOTREACHED() will LOG(ERROR) and also upload a crash
31 // report without crashing in order to weed out prevalent NOTREACHED()s in the
32 // wild before always turning NOTREACHED()s FATAL.
33 //
34 // TODO(crbug.com/851128): Migrate NOTREACHED() callers to NOTREACHED_NORETURN()
35 // which is [[noreturn]] and always FATAL. Once that's done, rename
36 // NOTREACHED_NORETURN() back to NOTREACHED() and remove the non-FATAL version.
37 // This migration will likely happen through the kNotReachedIsFatal experiment
38 // for most code as we'll be able to avoid stability issues for pre-existing
39 // failures.
40 #if CHECK_WILL_STREAM() || BUILDFLAG(ENABLE_LOG_ERROR_NOT_REACHED)
41 #define NOTREACHED() \
42   LOGGING_CHECK_FUNCTION_IMPL(::logging::NotReachedError::NotReached(), false)
43 #else
44 #define NOTREACHED()                                       \
45   (true) ? ::logging::NotReachedError::TriggerNotReached() \
46          : EAT_CHECK_STREAM_PARAMS()
47 #endif
48 
49 // NOTREACHED_NORETURN() annotates paths that are supposed to be unreachable.
50 // They crash if they are ever hit.
51 // TODO(crbug.com/851128): Rename back to NOTREACHED() once there are no callers
52 // of the old non-CHECK-fatal macro.
53 #if CHECK_WILL_STREAM()
54 #define NOTREACHED_NORETURN() ::logging::NotReachedNoreturnError()
55 #else
56 // This function is used to be able to detect NOTREACHED() failures in stack
57 // traces where this symbol is preserved (even if inlined). Its implementation
58 // matches logging::CheckFailure() but intentionally uses a different signature.
59 [[noreturn]] IMMEDIATE_CRASH_ALWAYS_INLINE void NotReachedFailure() {
60   base::ImmediateCrash();
61 }
62 
63 #define NOTREACHED_NORETURN() \
64   (true) ? ::logging::NotReachedFailure() : EAT_CHECK_STREAM_PARAMS()
65 #endif
66 
67 // The DUMP_WILL_BE_NOTREACHED_NORETURN() macro provides a convenient way to
68 // non-fatally dump in official builds if ever hit. See DUMP_WILL_BE_CHECK for
69 // suggested usage.
70 #define DUMP_WILL_BE_NOTREACHED_NORETURN() \
71   ::logging::CheckError::DumpWillBeNotReachedNoreturn()
72 
73 // The NOTIMPLEMENTED() macro annotates codepaths which have not been
74 // implemented yet. If output spam is a serious concern,
75 // NOTIMPLEMENTED_LOG_ONCE() can be used.
76 #if DCHECK_IS_ON()
77 #define NOTIMPLEMENTED() \
78   ::logging::CheckError::NotImplemented(__PRETTY_FUNCTION__)
79 
80 // The lambda returns false the first time it is run, and true every other time.
81 #define NOTIMPLEMENTED_LOG_ONCE()                                \
82   LOGGING_CHECK_FUNCTION_IMPL(NOTIMPLEMENTED(), []() {           \
83     bool old_value = true;                                       \
84     [[maybe_unused]] static const bool call_once = [](bool* b) { \
85       *b = false;                                                \
86       return true;                                               \
87     }(&old_value);                                               \
88     return old_value;                                            \
89   }())
90 
91 #else
92 #define NOTIMPLEMENTED() EAT_CHECK_STREAM_PARAMS()
93 #define NOTIMPLEMENTED_LOG_ONCE() EAT_CHECK_STREAM_PARAMS()
94 #endif
95 
96 }  // namespace logging
97 
98 #endif  // BASE_NOTREACHED_H_
99