Path: blob/main/SignalServiceKit/Debugging/OWSAsserts.h
1 views
//1// Copyright 2024 Signal Messenger, LLC2// SPDX-License-Identifier: AGPL-3.0-only3//45#import <SignalServiceKit/DebuggerUtils.h>6#import <SignalServiceKit/OWSLogs.h>78NS_ASSUME_NONNULL_BEGIN910#ifndef OWSAssert1112#define CONVERT_TO_STRING(X) #X13#define CONVERT_EXPR_TO_STRING(X) CONVERT_TO_STRING(X)1415#define OWSAssertDebugUnlessRunningTests(X) \16do { \17if (!CurrentAppContext().isRunningTests) { \18OWSAssertDebug(X); \19} \20} while (NO)2122#ifdef DEBUG2324#define USE_ASSERTS2526// OWSAssertDebug() and OWSFailDebug() should be used in Obj-C methods.27// OWSCAssertDebug() and OWSCFailDebug() should be used in free functions.2829#define OWSAssertDebug(X) \30do { \31if (!(X)) { \32OWSLogError(@"Assertion failed: %s", CONVERT_EXPR_TO_STRING(X)); \33OWSLogFlush(); \34NSAssert(0, @"Assertion failed: %s", CONVERT_EXPR_TO_STRING(X)); \35} \36} while (NO)3738#define OWSCAssertDebug(X) \39do { \40if (!(X)) { \41OWSLogError(@"Assertion failed: %s", CONVERT_EXPR_TO_STRING(X)); \42OWSLogFlush(); \43NSCAssert(0, @"Assertion failed: %s", CONVERT_EXPR_TO_STRING(X)); \44} \45} while (NO)4647#define OWSFailWithoutLogging(message, ...) \48do { \49NSString *formattedMessage = [NSString stringWithFormat:message, ##__VA_ARGS__]; \50if (IsDebuggerAttached()) { \51TrapDebugger(); \52} else { \53NSAssert(0, formattedMessage); \54} \55} while (NO)5657#define OWSCFailWithoutLogging(message, ...) \58do { \59NSString *formattedMessage = [NSString stringWithFormat:message, ##__VA_ARGS__]; \60NSCAssert(0, formattedMessage); \61} while (NO)6263#define OWSFailNoFormat(message) \64do { \65OWSLogError(@"%@", message); \66OWSLogFlush(); \67NSAssert(0, message); \68} while (NO)6970#define OWSCFailNoFormat(message) \71do { \72OWSLogError(@"%@", message); \73OWSLogFlush(); \74NSCAssert(0, message); \75} while (NO)7677#else7879#define OWSAssertDebug(X)80#define OWSCAssertDebug(X)81#define OWSFailWithoutLogging(message, ...)82#define OWSCFailWithoutLogging(message, ...)83#define OWSFailNoFormat(X)84#define OWSCFailNoFormat(X)8586#endif8788#endif8990// Like OWSAssertDebug, but will fail in production, terminating the app91#define OWSPrecondition(X) \92do { \93if (!(X)) { \94OWSFail(@"Assertion failed: %s", CONVERT_EXPR_TO_STRING(X)); \95} \96} while (NO)9798#define OWSCPrecondition(X) \99do { \100if (!(X)) { \101OWSCFail(@"Assertion failed: %s", CONVERT_EXPR_TO_STRING(X)); \102} \103} while (NO)104105#define OWSAbstractMethod() OWSFail(@"Method needs to be implemented by subclasses.")106107// This macro is intended for use in Objective-C.108#define OWSAssertIsOnMainThread() OWSCAssertDebug([NSThread isMainThread])109110#define OWSFailDebug(_messageFormat, ...) \111do { \112OWSLogError(_messageFormat, ##__VA_ARGS__); \113OWSFailWithoutLogging(_messageFormat, ##__VA_ARGS__); \114} while (0)115116#define OWSCFailDebug(_messageFormat, ...) \117do { \118OWSLogError(_messageFormat, ##__VA_ARGS__); \119OWSCFailWithoutLogging(_messageFormat, ##__VA_ARGS__); \120} while (NO)121122void SwiftExit(NSString *message, const char *file, const char *function, int line);123124#define OWSFail(_messageFormat, ...) \125do { \126OWSFailDebug(_messageFormat, ##__VA_ARGS__); \127\128NSString *_message = [NSString stringWithFormat:_messageFormat, ##__VA_ARGS__]; \129SwiftExit(_message, __FILE__, __PRETTY_FUNCTION__, __LINE__); \130} while (0)131132#define OWSCFail(_messageFormat, ...) \133do { \134OWSCFailDebug(_messageFormat, ##__VA_ARGS__); \135\136NSString *_message = [NSString stringWithFormat:_messageFormat, ##__VA_ARGS__]; \137SwiftExit(_message, __FILE__, __PRETTY_FUNCTION__, __LINE__); \138} while (NO)139140__attribute__((annotate("returns_localized_nsstring"))) static inline NSString *LocalizationNotNeeded(NSString *s)141{142return s;143}144145NS_ASSUME_NONNULL_END146147148