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