checks.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. /*
  2. * Copyright 2006 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef RTC_BASE_CHECKS_H_
  11. #define RTC_BASE_CHECKS_H_
  12. // If you for some reson need to know if DCHECKs are on, test the value of
  13. // RTC_DCHECK_IS_ON. (Test its value, not if it's defined; it'll always be
  14. // defined, to either a true or a false value.)
  15. #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  16. #define RTC_DCHECK_IS_ON 1
  17. #else
  18. #define RTC_DCHECK_IS_ON 0
  19. #endif
  20. // Annotate a function that will not return control flow to the caller.
  21. #if defined(_MSC_VER)
  22. #define RTC_NORETURN __declspec(noreturn)
  23. #elif defined(__GNUC__)
  24. #define RTC_NORETURN __attribute__((__noreturn__))
  25. #else
  26. #define RTC_NORETURN
  27. #endif
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. RTC_NORETURN void rtc_FatalMessage(const char* file, int line, const char* msg);
  32. #ifdef __cplusplus
  33. } // extern "C"
  34. #endif
  35. #ifdef RTC_DISABLE_CHECK_MSG
  36. #define RTC_CHECK_MSG_ENABLED 0
  37. #else
  38. #define RTC_CHECK_MSG_ENABLED 1
  39. #endif
  40. #if RTC_CHECK_MSG_ENABLED
  41. #define RTC_CHECK_EVAL_MESSAGE(message) message
  42. #else
  43. #define RTC_CHECK_EVAL_MESSAGE(message) ""
  44. #endif
  45. #ifdef __cplusplus
  46. // C++ version.
  47. #include <string>
  48. #include "absl/meta/type_traits.h"
  49. #include "absl/strings/string_view.h"
  50. #include "rtc_base/numerics/safe_compare.h"
  51. #include "rtc_base/system/inline.h"
  52. #include "rtc_base/system/rtc_export.h"
  53. // The macros here print a message to stderr and abort under various
  54. // conditions. All will accept additional stream messages. For example:
  55. // RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar.";
  56. //
  57. // - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't,
  58. // it's better to terminate the process than to continue. During development,
  59. // the reason that it's better to terminate might simply be that the error
  60. // handling code isn't in place yet; in production, the reason might be that
  61. // the author of the code truly believes that x will always be true, but that
  62. // they recognizes that if they are wrong, abrupt and unpleasant process
  63. // termination is still better than carrying on with the assumption violated.
  64. //
  65. // RTC_CHECK always evaluates its argument, so it's OK for x to have side
  66. // effects.
  67. //
  68. // - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always
  69. // true---except that x will only be evaluated in debug builds; in production
  70. // builds, x is simply assumed to be true. This is useful if evaluating x is
  71. // expensive and the expected cost of failing to detect the violated
  72. // assumption is acceptable. You should not handle cases where a production
  73. // build fails to spot a violated condition, even those that would result in
  74. // crashes. If the code needs to cope with the error, make it cope, but don't
  75. // call RTC_DCHECK; if the condition really can't occur, but you'd sleep
  76. // better at night knowing that the process will suicide instead of carrying
  77. // on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK.
  78. //
  79. // RTC_DCHECK only evaluates its argument in debug builds, so if x has visible
  80. // side effects, you need to write e.g.
  81. // bool w = x; RTC_DCHECK(w);
  82. //
  83. // - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are
  84. // specialized variants of RTC_CHECK and RTC_DCHECK that print prettier
  85. // messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and
  86. // RTC_DCHECK.
  87. //
  88. // - FATAL() aborts unconditionally.
  89. namespace rtc {
  90. namespace webrtc_checks_impl {
  91. enum class CheckArgType : int8_t {
  92. kEnd = 0,
  93. kInt,
  94. kLong,
  95. kLongLong,
  96. kUInt,
  97. kULong,
  98. kULongLong,
  99. kDouble,
  100. kLongDouble,
  101. kCharP,
  102. kStdString,
  103. kStringView,
  104. kVoidP,
  105. // kCheckOp doesn't represent an argument type. Instead, it is sent as the
  106. // first argument from RTC_CHECK_OP to make FatalLog use the next two
  107. // arguments to build the special CHECK_OP error message
  108. // (the "a == b (1 vs. 2)" bit).
  109. kCheckOp,
  110. };
  111. #if RTC_CHECK_MSG_ENABLED
  112. RTC_NORETURN RTC_EXPORT void FatalLog(const char* file,
  113. int line,
  114. const char* message,
  115. const CheckArgType* fmt,
  116. ...);
  117. #else
  118. RTC_NORETURN RTC_EXPORT void FatalLog(const char* file, int line);
  119. #endif
  120. // Wrapper for log arguments. Only ever make values of this type with the
  121. // MakeVal() functions.
  122. template <CheckArgType N, typename T>
  123. struct Val {
  124. static constexpr CheckArgType Type() { return N; }
  125. T GetVal() const { return val; }
  126. T val;
  127. };
  128. // Case for when we need to construct a temp string and then print that.
  129. // (We can't use Val<CheckArgType::kStdString, const std::string*>
  130. // because we need somewhere to store the temp string.)
  131. struct ToStringVal {
  132. static constexpr CheckArgType Type() { return CheckArgType::kStdString; }
  133. const std::string* GetVal() const { return &val; }
  134. std::string val;
  135. };
  136. inline Val<CheckArgType::kInt, int> MakeVal(int x) {
  137. return {x};
  138. }
  139. inline Val<CheckArgType::kLong, long> MakeVal(long x) {
  140. return {x};
  141. }
  142. inline Val<CheckArgType::kLongLong, long long> MakeVal(long long x) {
  143. return {x};
  144. }
  145. inline Val<CheckArgType::kUInt, unsigned int> MakeVal(unsigned int x) {
  146. return {x};
  147. }
  148. inline Val<CheckArgType::kULong, unsigned long> MakeVal(unsigned long x) {
  149. return {x};
  150. }
  151. inline Val<CheckArgType::kULongLong, unsigned long long> MakeVal(
  152. unsigned long long x) {
  153. return {x};
  154. }
  155. inline Val<CheckArgType::kDouble, double> MakeVal(double x) {
  156. return {x};
  157. }
  158. inline Val<CheckArgType::kLongDouble, long double> MakeVal(long double x) {
  159. return {x};
  160. }
  161. inline Val<CheckArgType::kCharP, const char*> MakeVal(const char* x) {
  162. return {x};
  163. }
  164. inline Val<CheckArgType::kStdString, const std::string*> MakeVal(
  165. const std::string& x) {
  166. return {&x};
  167. }
  168. inline Val<CheckArgType::kStringView, const absl::string_view*> MakeVal(
  169. const absl::string_view& x) {
  170. return {&x};
  171. }
  172. inline Val<CheckArgType::kVoidP, const void*> MakeVal(const void* x) {
  173. return {x};
  174. }
  175. // The enum class types are not implicitly convertible to arithmetic types.
  176. template <typename T,
  177. absl::enable_if_t<std::is_enum<T>::value &&
  178. !std::is_arithmetic<T>::value>* = nullptr>
  179. inline decltype(MakeVal(std::declval<absl::underlying_type_t<T>>())) MakeVal(
  180. T x) {
  181. return {static_cast<absl::underlying_type_t<T>>(x)};
  182. }
  183. template <typename T, decltype(ToLogString(std::declval<T>()))* = nullptr>
  184. ToStringVal MakeVal(const T& x) {
  185. return {ToLogString(x)};
  186. }
  187. // Ephemeral type that represents the result of the logging << operator.
  188. template <typename... Ts>
  189. class LogStreamer;
  190. // Base case: Before the first << argument.
  191. template <>
  192. class LogStreamer<> final {
  193. public:
  194. template <typename U,
  195. typename V = decltype(MakeVal(std::declval<U>())),
  196. absl::enable_if_t<std::is_arithmetic<U>::value ||
  197. std::is_enum<U>::value>* = nullptr>
  198. RTC_FORCE_INLINE LogStreamer<V> operator<<(U arg) const {
  199. return LogStreamer<V>(MakeVal(arg), this);
  200. }
  201. template <typename U,
  202. typename V = decltype(MakeVal(std::declval<U>())),
  203. absl::enable_if_t<!std::is_arithmetic<U>::value &&
  204. !std::is_enum<U>::value>* = nullptr>
  205. RTC_FORCE_INLINE LogStreamer<V> operator<<(const U& arg) const {
  206. return LogStreamer<V>(MakeVal(arg), this);
  207. }
  208. #if RTC_CHECK_MSG_ENABLED
  209. template <typename... Us>
  210. RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file,
  211. const int line,
  212. const char* message,
  213. const Us&... args) {
  214. static constexpr CheckArgType t[] = {Us::Type()..., CheckArgType::kEnd};
  215. FatalLog(file, line, message, t, args.GetVal()...);
  216. }
  217. template <typename... Us>
  218. RTC_NORETURN RTC_FORCE_INLINE static void CallCheckOp(const char* file,
  219. const int line,
  220. const char* message,
  221. const Us&... args) {
  222. static constexpr CheckArgType t[] = {CheckArgType::kCheckOp, Us::Type()...,
  223. CheckArgType::kEnd};
  224. FatalLog(file, line, message, t, args.GetVal()...);
  225. }
  226. #else
  227. template <typename... Us>
  228. RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file,
  229. const int line) {
  230. FatalLog(file, line);
  231. }
  232. #endif
  233. };
  234. // Inductive case: We've already seen at least one << argument. The most recent
  235. // one had type `T`, and the earlier ones had types `Ts`.
  236. template <typename T, typename... Ts>
  237. class LogStreamer<T, Ts...> final {
  238. public:
  239. RTC_FORCE_INLINE LogStreamer(T arg, const LogStreamer<Ts...>* prior)
  240. : arg_(arg), prior_(prior) {}
  241. template <typename U,
  242. typename V = decltype(MakeVal(std::declval<U>())),
  243. absl::enable_if_t<std::is_arithmetic<U>::value ||
  244. std::is_enum<U>::value>* = nullptr>
  245. RTC_FORCE_INLINE LogStreamer<V, T, Ts...> operator<<(U arg) const {
  246. return LogStreamer<V, T, Ts...>(MakeVal(arg), this);
  247. }
  248. template <typename U,
  249. typename V = decltype(MakeVal(std::declval<U>())),
  250. absl::enable_if_t<!std::is_arithmetic<U>::value &&
  251. !std::is_enum<U>::value>* = nullptr>
  252. RTC_FORCE_INLINE LogStreamer<V, T, Ts...> operator<<(const U& arg) const {
  253. return LogStreamer<V, T, Ts...>(MakeVal(arg), this);
  254. }
  255. #if RTC_CHECK_MSG_ENABLED
  256. template <typename... Us>
  257. RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file,
  258. const int line,
  259. const char* message,
  260. const Us&... args) const {
  261. prior_->Call(file, line, message, arg_, args...);
  262. }
  263. template <typename... Us>
  264. RTC_NORETURN RTC_FORCE_INLINE void CallCheckOp(const char* file,
  265. const int line,
  266. const char* message,
  267. const Us&... args) const {
  268. prior_->CallCheckOp(file, line, message, arg_, args...);
  269. }
  270. #else
  271. template <typename... Us>
  272. RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file,
  273. const int line) const {
  274. prior_->Call(file, line);
  275. }
  276. #endif
  277. private:
  278. // The most recent argument.
  279. T arg_;
  280. // Earlier arguments.
  281. const LogStreamer<Ts...>* prior_;
  282. };
  283. template <bool isCheckOp>
  284. class FatalLogCall final {
  285. public:
  286. FatalLogCall(const char* file, int line, const char* message)
  287. : file_(file), line_(line), message_(message) {}
  288. // This can be any binary operator with precedence lower than <<.
  289. template <typename... Ts>
  290. RTC_NORETURN RTC_FORCE_INLINE void operator&(
  291. const LogStreamer<Ts...>& streamer) {
  292. #if RTC_CHECK_MSG_ENABLED
  293. isCheckOp ? streamer.CallCheckOp(file_, line_, message_)
  294. : streamer.Call(file_, line_, message_);
  295. #else
  296. streamer.Call(file_, line_);
  297. #endif
  298. }
  299. private:
  300. const char* file_;
  301. int line_;
  302. const char* message_;
  303. };
  304. } // namespace webrtc_checks_impl
  305. // The actual stream used isn't important. We reference |ignored| in the code
  306. // but don't evaluate it; this is to avoid "unused variable" warnings (we do so
  307. // in a particularly convoluted way with an extra ?: because that appears to be
  308. // the simplest construct that keeps Visual Studio from complaining about
  309. // condition being unused).
  310. #define RTC_EAT_STREAM_PARAMETERS(ignored) \
  311. (true ? true : ((void)(ignored), true)) \
  312. ? static_cast<void>(0) \
  313. : ::rtc::webrtc_checks_impl::FatalLogCall<false>("", 0, "") & \
  314. ::rtc::webrtc_checks_impl::LogStreamer<>()
  315. // Call RTC_EAT_STREAM_PARAMETERS with an argument that fails to compile if
  316. // values of the same types as |a| and |b| can't be compared with the given
  317. // operation, and that would evaluate |a| and |b| if evaluated.
  318. #define RTC_EAT_STREAM_PARAMETERS_OP(op, a, b) \
  319. RTC_EAT_STREAM_PARAMETERS(((void)::rtc::Safe##op(a, b)))
  320. // RTC_CHECK dies with a fatal error if condition is not true. It is *not*
  321. // controlled by NDEBUG or anything else, so the check will be executed
  322. // regardless of compilation mode.
  323. //
  324. // We make sure RTC_CHECK et al. always evaluates |condition|, as
  325. // doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom.
  326. //
  327. // RTC_CHECK_OP is a helper macro for binary operators.
  328. // Don't use this macro directly in your code, use RTC_CHECK_EQ et al below.
  329. #if RTC_CHECK_MSG_ENABLED
  330. #define RTC_CHECK(condition) \
  331. (condition) ? static_cast<void>(0) \
  332. : ::rtc::webrtc_checks_impl::FatalLogCall<false>( \
  333. __FILE__, __LINE__, #condition) & \
  334. ::rtc::webrtc_checks_impl::LogStreamer<>()
  335. #define RTC_CHECK_OP(name, op, val1, val2) \
  336. ::rtc::Safe##name((val1), (val2)) \
  337. ? static_cast<void>(0) \
  338. : ::rtc::webrtc_checks_impl::FatalLogCall<true>( \
  339. __FILE__, __LINE__, #val1 " " #op " " #val2) & \
  340. ::rtc::webrtc_checks_impl::LogStreamer<>() << (val1) << (val2)
  341. #else
  342. #define RTC_CHECK(condition) \
  343. (condition) \
  344. ? static_cast<void>(0) \
  345. : true ? ::rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, \
  346. __LINE__, "") & \
  347. ::rtc::webrtc_checks_impl::LogStreamer<>() \
  348. : ::rtc::webrtc_checks_impl::FatalLogCall<false>("", 0, "") & \
  349. ::rtc::webrtc_checks_impl::LogStreamer<>()
  350. #define RTC_CHECK_OP(name, op, val1, val2) \
  351. ::rtc::Safe##name((val1), (val2)) \
  352. ? static_cast<void>(0) \
  353. : true ? ::rtc::webrtc_checks_impl::FatalLogCall<true>(__FILE__, \
  354. __LINE__, "") & \
  355. ::rtc::webrtc_checks_impl::LogStreamer<>() \
  356. : ::rtc::webrtc_checks_impl::FatalLogCall<false>("", 0, "") & \
  357. ::rtc::webrtc_checks_impl::LogStreamer<>()
  358. #endif
  359. #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2)
  360. #define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2)
  361. #define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(Le, <=, val1, val2)
  362. #define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(Lt, <, val1, val2)
  363. #define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(Ge, >=, val1, val2)
  364. #define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(Gt, >, val1, val2)
  365. // The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates
  366. // code in debug builds. It does reference the condition parameter in all cases,
  367. // though, so callers won't risk getting warnings about unused variables.
  368. #if RTC_DCHECK_IS_ON
  369. #define RTC_DCHECK(condition) RTC_CHECK(condition)
  370. #define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2)
  371. #define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2)
  372. #define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2)
  373. #define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2)
  374. #define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2)
  375. #define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2)
  376. #else
  377. #define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition)
  378. #define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Eq, v1, v2)
  379. #define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ne, v1, v2)
  380. #define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Le, v1, v2)
  381. #define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Lt, v1, v2)
  382. #define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ge, v1, v2)
  383. #define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Gt, v1, v2)
  384. #endif
  385. #define RTC_UNREACHABLE_CODE_HIT false
  386. #define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT)
  387. // TODO(bugs.webrtc.org/8454): Add an RTC_ prefix or rename differently.
  388. #define FATAL() \
  389. ::rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, __LINE__, \
  390. "FATAL()") & \
  391. ::rtc::webrtc_checks_impl::LogStreamer<>()
  392. // Performs the integer division a/b and returns the result. CHECKs that the
  393. // remainder is zero.
  394. template <typename T>
  395. inline T CheckedDivExact(T a, T b) {
  396. RTC_CHECK_EQ(a % b, 0) << a << " is not evenly divisible by " << b;
  397. return a / b;
  398. }
  399. } // namespace rtc
  400. #else // __cplusplus not defined
  401. // C version. Lacks many features compared to the C++ version, but usage
  402. // guidelines are the same.
  403. #define RTC_CHECK(condition) \
  404. do { \
  405. if (!(condition)) { \
  406. rtc_FatalMessage(__FILE__, __LINE__, \
  407. RTC_CHECK_EVAL_MESSAGE("CHECK failed: " #condition)); \
  408. } \
  409. } while (0)
  410. #define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b))
  411. #define RTC_CHECK_NE(a, b) RTC_CHECK((a) != (b))
  412. #define RTC_CHECK_LE(a, b) RTC_CHECK((a) <= (b))
  413. #define RTC_CHECK_LT(a, b) RTC_CHECK((a) < (b))
  414. #define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b))
  415. #define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b))
  416. #define RTC_DCHECK(condition) \
  417. do { \
  418. if (RTC_DCHECK_IS_ON && !(condition)) { \
  419. rtc_FatalMessage(__FILE__, __LINE__, \
  420. RTC_CHECK_EVAL_MESSAGE("DCHECK failed: " #condition)); \
  421. } \
  422. } while (0)
  423. #define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b))
  424. #define RTC_DCHECK_NE(a, b) RTC_DCHECK((a) != (b))
  425. #define RTC_DCHECK_LE(a, b) RTC_DCHECK((a) <= (b))
  426. #define RTC_DCHECK_LT(a, b) RTC_DCHECK((a) < (b))
  427. #define RTC_DCHECK_GE(a, b) RTC_DCHECK((a) >= (b))
  428. #define RTC_DCHECK_GT(a, b) RTC_DCHECK((a) > (b))
  429. #endif // __cplusplus
  430. #endif // RTC_BASE_CHECKS_H_