agent/native/ext/elastic_apm_assert.h (140 lines of code) (raw):
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#pragma once
#include <stdbool.h>
#include <stdlib.h> // NULL
#include <inttypes.h> // PRId64, PRIu64
#include <stdarg.h>
#include "elastic_apm_assert_enabled.h"
#include "basic_macros.h" // ELASTIC_APM_NO_RETURN_ATTRIBUTE, ELASTIC_APM_PRINTF_ATTRIBUTE
#include "basic_types.h" // Int64, UInt64
#include "internal_checks.h"
#include "TextOutputStream_forward_decl.h"
void elasticApmAbort() ELASTIC_APM_NO_RETURN_ATTRIBUTE;
#define ELASTIC_APM_STATIC_ASSERT( cond ) \
typedef char ELASTIC_APM_PP_CONCAT( elastic_apm_static_assert_t_, ELASTIC_APM_PP_CONCAT( __LINE__, ELASTIC_APM_PP_CONCAT( _, __COUNTER__ ) ) ) [ (cond) ? 1 : -1 ]
#if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 )
enum AssertLevel
{
assertLevel_not_set = -1,
assertLevel_off = 0,
assertLevel_O_1,
assertLevel_O_n,
assertLevel_all,
numberOfAssertLevels = assertLevel_all + 1
};
typedef enum AssertLevel AssertLevel;
extern const char* assertLevelNames[ numberOfAssertLevels ];
AssertLevel internalChecksToAssertLevel( InternalChecksLevel internalChecksLevel );
#ifndef ELASTIC_APM_ASSERT_DEFAULT_LEVEL
# if ( ELASTIC_APM_IS_DEBUG_BUILD_01 != 0 )
# define ELASTIC_APM_ASSERT_DEFAULT_LEVEL assertLevel_all
# else
# define ELASTIC_APM_ASSERT_DEFAULT_LEVEL assertLevel_off
# endif
#endif
void elasticApmAssertFailed(
const char* filePath /* <- argument #1 */
, unsigned int lineNumber
, const char* funcName
, const char* msgPrintfFmt /* <- printf format is argument #4 */
, /* msgPrintfFmtArgs */ ... /* <- arguments for printf format placeholders start from argument #5 */
) ELASTIC_APM_PRINTF_ATTRIBUTE( /* printfFmtPos: */ 4, /* printfFmtArgsPos: */ 5 ) ELASTIC_APM_NO_RETURN_ATTRIBUTE;
void vElasticApmAssertFailed(
const char* filePath
, unsigned int lineNumber
, const char* funcName
, const char* msgPrintfFmt
, va_list msgPrintfFmtArgs
) ELASTIC_APM_NO_RETURN_ATTRIBUTE;
#ifndef ELASTIC_APM_ASSERT_FAILED_FUNC
# define ELASTIC_APM_ASSERT_FAILED_FUNC elasticApmAssertFailed
# define ELASTIC_APM_ASSERT_FAILED_FUNC_NO_RETURN_ATTRIBUTE ELASTIC_APM_NO_RETURN_ATTRIBUTE
#endif
#ifndef ELASTIC_APM_ASSERT_FAILED_FUNC_NO_RETURN_ATTRIBUTE
# define ELASTIC_APM_ASSERT_FAILED_FUNC_NO_RETURN_ATTRIBUTE
#endif
// Declare to avoid warnings
void ELASTIC_APM_ASSERT_FAILED_FUNC(
const char* filePath /* <- argument #1 */
, unsigned int lineNumber
, const char* funcName
, const char* msgPrintfFmt /* <- printf format is argument #4 */
, /* msgPrintfFmtArgs */ ... /* <- arguments for printf format placeholders start from argument #5 */
) ELASTIC_APM_PRINTF_ATTRIBUTE( /* printfFmtPos: */ 4, /* printfFmtArgsPos: */ 5 ) ELASTIC_APM_ASSERT_FAILED_FUNC_NO_RETURN_ATTRIBUTE;
AssertLevel getGlobalAssertLevel();
#define ELASTIC_APM_ASSERT_WITH_LEVEL( level, cond, msgPrintfFmt, /* msgPrintfFmtArgs */ ... ) \
do { \
if ( getGlobalAssertLevel() >= (level) && ( ! (cond) ) ) \
ELASTIC_APM_ASSERT_FAILED_FUNC \
( \
__FILE__ \
, __LINE__ \
, __FUNCTION__ \
, "Assertion failed! Condition: %s" "%s" msgPrintfFmt \
, #cond \
, ELASTIC_APM_IF_VA_ARGS_EMPTY_ELSE( "", ". " ,##__VA_ARGS__ ) \
,##__VA_ARGS__ \
); \
} while ( 0 )
#define ELASTIC_APM_ASSERT_VALID_OBJ_WITH_LEVEL( level, assertValidObjCall ) \
do { \
if ( getGlobalAssertLevel() >= level ) \
(void)(assertValidObjCall); \
} while ( 0 )
#else // #if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 )
#define ELASTIC_APM_ASSERT_WITH_LEVEL( level, cond, msgPrintfFmt, /* msgPrintfFmtArgs */ ... ) ELASTIC_APM_NOOP_STATEMENT
#define ELASTIC_APM_ASSERT_VALID_OBJ_WITH_LEVEL( level, assertValidObjCall ) ELASTIC_APM_NOOP_STATEMENT
#endif // #if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 )
#define ELASTIC_APM_ASSERT( cond, msgPrintfFmt, /* msgPrintfFmtArgs: */ ... ) \
ELASTIC_APM_ASSERT_WITH_LEVEL( assertLevel_O_1, cond, msgPrintfFmt /* msgPrintfFmtArgs: */ , ##__VA_ARGS__ ) \
/**/
#define ELASTIC_APM_ASSERT_O_N( cond, /* , msg: */ ... ) \
ELASTIC_APM_ASSERT_WITH_LEVEL( assertLevel_O_n, cond, msgPrintfFmt /* msgPrintfFmtArgs: */ , ##__VA_ARGS__ ) \
/**/
#define ELASTIC_APM_ASSERT_VALID_OBJ( assertValidObjCall ) ELASTIC_APM_ASSERT_VALID_OBJ_WITH_LEVEL( assertLevel_O_1, assertValidObjCall )
#define ELASTIC_APM_ASSERT_VALID_OBJ_O_N( assertValidObjCall ) ELASTIC_APM_ASSERT_VALID_OBJ_WITH_LEVEL( assertLevel_O_n, assertValidObjCall )
static inline
bool isValidPtr( const void* ptr )
{
return ptr != NULL;
}
#define ELASTIC_APM_ASSERT_VALID_PTR( ptr ) ELASTIC_APM_ASSERT_VALID_OBJ( isValidPtr( ptr ) )
#define ELASTIC_APM_ASSERT_VALID_OUT_PTR_TO_PTR( ptrToPtr ) ELASTIC_APM_ASSERT( isValidPtr( ptrToPtr ) && ( *(ptrToPtr) == NULL ), "" )
#define ELASTIC_APM_ASSERT_VALID_IN_PTR_TO_PTR( ptrToPtr ) ELASTIC_APM_ASSERT( isValidPtr( ptrToPtr ) && isValidPtr( *(ptrToPtr) ), "" )
#define ELASTIC_APM_ASSERT_VALID_STRING( str ) ELASTIC_APM_ASSERT_VALID_PTR( str )
#define ELASTIC_APM_ASSERT_PTR_IS_NULL( ptr ) ELASTIC_APM_ASSERT( (ptr) == NULL, #ptr ": %p", (ptr) )
#define ELASTIC_APM_ASSERT_OP( lhsOperand, binaryRelOperator, rhsOperand, operandType, printfFmtForOperandType ) \
ELASTIC_APM_ASSERT \
( \
((operandType)(lhsOperand)) binaryRelOperator ((operandType)(rhsOperand)) \
, #lhsOperand ": %" printfFmtForOperandType ", " #rhsOperand ": %" printfFmtForOperandType \
, ((operandType)(lhsOperand)), ((operandType)(rhsOperand)) \
) \
/**/
#define ELASTIC_APM_ASSERT_EQ_UINT64( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP( lhsOperand, ==, rhsOperand, UInt64, PRIu64 )
#define ELASTIC_APM_ASSERT_GE_UINT64( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP( lhsOperand, >=, rhsOperand, UInt64, PRIu64 )
#define ELASTIC_APM_ASSERT_GT_UINT64( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP( lhsOperand, >, rhsOperand, UInt64, PRIu64 )
#define ELASTIC_APM_ASSERT_LE_UINT64( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP( lhsOperand, <=, rhsOperand, UInt64, PRIu64 )
#define ELASTIC_APM_ASSERT_LT_UINT64( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP( lhsOperand, <, rhsOperand, UInt64, PRIu64 )
#define ELASTIC_APM_ASSERT_OP_PTR( lhsOperand, binaryRelOperator, rhsOperand ) \
ELASTIC_APM_ASSERT \
( \
(lhsOperand) binaryRelOperator (rhsOperand) \
, #lhsOperand ": %p, " #rhsOperand ": %p" \
, (lhsOperand), (rhsOperand) \
) \
/**/
#define ELASTIC_APM_ASSERT_EQ_PTR( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP_PTR( lhsOperand, ==, rhsOperand )
#define ELASTIC_APM_ASSERT_GE_PTR( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP_PTR( lhsOperand, >=, rhsOperand )
#define ELASTIC_APM_ASSERT_LE_PTR( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP_PTR( lhsOperand, <=, rhsOperand )
#define ELASTIC_APM_ASSERT_LT_PTR( lhsOperand, rhsOperand ) ELASTIC_APM_ASSERT_OP_PTR( lhsOperand, <, rhsOperand )
#define ELASTIC_APM_ASSERT_EQ_CHAR( lhsOperand, rhsOperand ) \
ELASTIC_APM_ASSERT \
( \
(lhsOperand) == (rhsOperand) \
, #lhsOperand ": %c (as unsigned int: %u), " #rhsOperand ": %c (as unsigned int: %u)" \
, (lhsOperand), ((unsigned int)(lhsOperand)), (rhsOperand), ((unsigned int)(rhsOperand)) \
) \
/**/
#define ELASTIC_APM_ASSERT_IN_INCLUSIVE_RANGE_UINT64( rangeBegin, x, rangeEnd ) \
ELASTIC_APM_ASSERT( ELASTIC_APM_IS_IN_INCLUSIVE_RANGE( rangeBegin, x, rangeEnd ) \
, #rangeBegin ": %" PRIu64 ", " #x ": %" PRIu64 ", " #rangeEnd ": %" PRIu64 \
, (UInt64)(rangeBegin), (UInt64)(x), (UInt64)(rangeEnd) ) \
/**/
#define ELASTIC_APM_ASSERT_IN_END_EXCLUDED_RANGE_UINT64( rangeBeginIncluded, x, rangeEndExcluded ) \
ELASTIC_APM_ASSERT( ELASTIC_APM_IS_IN_END_EXCLUDED_RANGE( rangeBeginIncluded, x, rangeEndExcluded ) \
, #rangeBeginIncluded ": %" PRIu64 ", " #x ": %" PRIu64 ", " #rangeEndExcluded ": %" PRIu64 \
, (UInt64)(rangeBeginIncluded), (UInt64)(x), (UInt64)(rangeEndExcluded) ) \
/**/
String streamAssertLevel( AssertLevel level, TextOutputStream* txtOutStream );