mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-02-21 19:48:29 +02:00
Audit mem contexts returned from functions into the calling context.
It is possible for functions to accidentally leak child contexts into the calling context, which may use a lot of memory depending on the use case and where it happens. Use the function return type to determine what should be returned and error when something else is returned. Add FUNCTION_AUDIT_*() macros to handle exceptions. This checking is only performed during unit tests on the code being covered by the specific unit test. Note that this does not work yet for memory allocations, i.e. memNew(). These are pretty rare so are not as much of an issue and they can be added in the future.
This commit is contained in:
parent
de1dfb66ca
commit
9ca492cecf
@ -28,6 +28,8 @@ archiveGetFile(
|
||||
FUNCTION_LOG_PARAM(STRING, walDestination);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(request != NULL);
|
||||
ASSERT(actualList != NULL && !lstEmpty(actualList));
|
||||
ASSERT(walDestination != NULL);
|
||||
|
@ -363,6 +363,8 @@ archiveGetCheck(const StringList *archiveRequestList)
|
||||
FUNCTION_LOG_PARAM(STRING_LIST, archiveRequestList);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(archiveRequestList != NULL);
|
||||
ASSERT(!strLstEmpty(archiveRequestList));
|
||||
|
||||
|
@ -109,6 +109,8 @@ archivePushFile(
|
||||
FUNCTION_LOG_PARAM(STRING_LIST, priorErrorList);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(walSource != NULL);
|
||||
ASSERT(archiveFile != NULL);
|
||||
ASSERT(repoList != NULL);
|
||||
|
@ -218,6 +218,8 @@ archivePushCheck(bool pgPathSet)
|
||||
FUNCTION_LOG_PARAM(BOOL, pgPathSet);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ArchivePushCheckResult result = {.repoList = lstNewP(sizeof(ArchivePushFileRepoData)), .errorList = strLstNew()};
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
|
@ -169,6 +169,8 @@ backupInit(const InfoBackup *infoBackup)
|
||||
FUNCTION_LOG_PARAM(INFO_BACKUP, infoBackup);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(infoBackup != NULL);
|
||||
|
||||
// Initialize for offline backup
|
||||
@ -817,6 +819,8 @@ backupStart(BackupData *backupData)
|
||||
FUNCTION_LOG_PARAM(BACKUP_DATA, backupData);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
BackupStartResult result = {.lsn = NULL};
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
@ -1011,6 +1015,8 @@ backupStop(BackupData *backupData, Manifest *manifest)
|
||||
FUNCTION_LOG_PARAM(MANIFEST, manifest);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
BackupStopResult result = {.lsn = NULL};
|
||||
|
||||
if (cfgOptionBool(cfgOptOnline))
|
||||
@ -1059,6 +1065,8 @@ backupJobResultPageChecksumOut(VariantList *const result, const unsigned int pag
|
||||
FUNCTION_TEST_PARAM(UINT, pageEnd);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
// Output a single page
|
||||
if (pageBegin == pageEnd)
|
||||
{
|
||||
@ -1083,6 +1091,8 @@ backupJobResultPageChecksum(PackRead *const checksumPageResult)
|
||||
FUNCTION_LOG_PARAM(PACK_READ, checksumPageResult);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
VariantList *result = NULL;
|
||||
|
||||
// If there is an error result array
|
||||
@ -1509,6 +1519,8 @@ backupProcessQueue(const BackupData *const backupData, Manifest *const manifest,
|
||||
FUNCTION_LOG_PARAM_P(VOID, jobData);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(manifest != NULL);
|
||||
|
||||
uint64_t result = 0;
|
||||
|
@ -237,7 +237,7 @@ pageChecksumNew(const unsigned int segmentNo, const unsigned int segmentPageTota
|
||||
|
||||
OBJ_NEW_BEGIN(PageChecksum, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
PageChecksum *driver = OBJ_NEW_ALLOC();
|
||||
PageChecksum *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::PageChecksum);
|
||||
|
||||
*driver = (PageChecksum)
|
||||
{
|
||||
|
@ -110,6 +110,8 @@ checkPrimary(const DbGetResult dbGroup)
|
||||
FUNCTION_LOG_PARAM(DB_GET_RESULT, dbGroup);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
// If a primary is defined, check the configuration and perform a WAL switch and make sure the WAL is archived
|
||||
if (dbGroup.primary != NULL)
|
||||
{
|
||||
|
@ -306,6 +306,8 @@ archiveDbList(
|
||||
FUNCTION_TEST_PARAM(UINT, repoKey);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(stanza != NULL);
|
||||
ASSERT(pgData != NULL);
|
||||
ASSERT(archiveSection != NULL);
|
||||
@ -397,6 +399,8 @@ backupListAdd(
|
||||
FUNCTION_TEST_PARAM(INFO_REPO_DATA, repoData); // The repo data where this backup is located
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(backupSection != NULL);
|
||||
ASSERT(backupData != NULL);
|
||||
ASSERT(repoData != NULL);
|
||||
@ -586,6 +590,8 @@ backupList(
|
||||
FUNCTION_TEST_PARAM(UINT, repoIdxMax); // The index of the last repo to check
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(backupSection != NULL);
|
||||
ASSERT(stanzaData != NULL);
|
||||
|
||||
@ -658,6 +664,8 @@ stanzaInfoList(List *stanzaRepoList, const String *const backupLabel, const unsi
|
||||
FUNCTION_TEST_PARAM(UINT, repoIdxMax);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(stanzaRepoList != NULL);
|
||||
|
||||
VariantList *result = varLstNew();
|
||||
@ -804,6 +812,8 @@ formatTextBackup(const DbGroup *dbGroup, String *resultStr)
|
||||
FUNCTION_TEST_PARAM(STRING, resultStr);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(dbGroup != NULL);
|
||||
|
||||
strCatFmt(resultStr, "\n wal archive min/max (%s): ", strZ(dbGroup->version));
|
||||
@ -1002,6 +1012,8 @@ formatTextDb(
|
||||
FUNCTION_TEST_PARAM(UINT64, currentPgSystemId);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(stanzaInfo != NULL);
|
||||
ASSERT(currentPgVersion != NULL);
|
||||
|
||||
@ -1162,6 +1174,8 @@ infoUpdateStanza(
|
||||
FUNCTION_TEST_PARAM(STRING, backupLabel);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT(stanzaRepo != NULL);
|
||||
|
||||
|
@ -28,6 +28,8 @@ storageListRenderInfo(const StorageInfo *const info, IoWrite *const write, const
|
||||
FUNCTION_TEST_PARAM(BOOL, json);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(info != NULL);
|
||||
ASSERT(write != NULL);
|
||||
|
||||
@ -84,6 +86,8 @@ storageListRender(IoWrite *write)
|
||||
FUNCTION_LOG_PARAM(IO_WRITE, write);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
// Get sort order
|
||||
SortOrder sortOrder = sortOrderAsc;
|
||||
|
||||
|
@ -224,6 +224,8 @@ restoreBackupSet(void)
|
||||
{
|
||||
FUNCTION_LOG_VOID(logLevelDebug);
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
RestoreBackupData result = {0};
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
@ -741,6 +743,8 @@ restoreManifestOwner(const Manifest *const manifest, const String **const rootRe
|
||||
FUNCTION_LOG_PARAM_P(VOID, rootReplaceGroup);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(manifest != NULL);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
@ -2009,6 +2013,8 @@ restoreProcessQueue(Manifest *manifest, List **queueList)
|
||||
FUNCTION_LOG_PARAM_P(LIST, queueList);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(manifest != NULL);
|
||||
|
||||
uint64_t result = 0;
|
||||
|
@ -201,6 +201,8 @@ verifyInfoFile(const String *pathFileName, bool keepFile, const String *cipherPa
|
||||
FUNCTION_TEST_PARAM(STRING, cipherPass); // Password to open file if encrypted
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(pathFileName != NULL);
|
||||
|
||||
VerifyInfoFile result = {.errorCode = 0};
|
||||
@ -543,6 +545,8 @@ verifyCreateArchiveIdRange(VerifyArchiveResult *archiveIdResult, StringList *wal
|
||||
FUNCTION_TEST_PARAM_P(UINT, jobErrorTotal); // Pointer to the overall job error total
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(archiveIdResult != NULL);
|
||||
ASSERT(walFileList != NULL);
|
||||
|
||||
@ -1322,6 +1326,8 @@ verifyRender(const List *const archiveIdResultList, const List *const backupResu
|
||||
FUNCTION_TEST_PARAM(BOOL, verboseText); // Is verbose output requested?
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(archiveIdResultList != NULL);
|
||||
ASSERT(backupResultList != NULL);
|
||||
|
||||
|
@ -169,7 +169,7 @@ bz2CompressNew(int level)
|
||||
|
||||
OBJ_NEW_BEGIN(Bz2Compress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
Bz2Compress *driver = OBJ_NEW_ALLOC();
|
||||
Bz2Compress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Bz2Compress);
|
||||
|
||||
*driver = (Bz2Compress)
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ bz2DecompressNew(void)
|
||||
OBJ_NEW_BEGIN(Bz2Decompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
// Allocate state and set context
|
||||
Bz2Decompress *driver = OBJ_NEW_ALLOC();
|
||||
Bz2Decompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Bz2Decompress);
|
||||
|
||||
*driver = (Bz2Decompress)
|
||||
{
|
||||
|
@ -174,7 +174,7 @@ gzCompressNew(int level)
|
||||
|
||||
OBJ_NEW_BEGIN(GzCompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
GzCompress *driver = OBJ_NEW_ALLOC();
|
||||
GzCompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::GzCompress);
|
||||
|
||||
*driver = (GzCompress)
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ gzDecompressNew(void)
|
||||
OBJ_NEW_BEGIN(GzDecompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
// Allocate state and set context
|
||||
GzDecompress *driver = OBJ_NEW_ALLOC();
|
||||
GzDecompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::GzDecompress);
|
||||
|
||||
*driver = (GzDecompress)
|
||||
{
|
||||
|
@ -255,7 +255,7 @@ lz4CompressNew(int level)
|
||||
|
||||
OBJ_NEW_BEGIN(Lz4Compress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
Lz4Compress *driver = OBJ_NEW_ALLOC();
|
||||
Lz4Compress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Lz4Compress);
|
||||
|
||||
*driver = (Lz4Compress)
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ lz4DecompressNew(void)
|
||||
|
||||
OBJ_NEW_BEGIN(Lz4Decompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
Lz4Decompress *driver = OBJ_NEW_ALLOC();
|
||||
Lz4Decompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Lz4Decompress);
|
||||
*driver = (Lz4Decompress){0};
|
||||
|
||||
// Create lz4 context
|
||||
|
@ -176,7 +176,7 @@ zstCompressNew(int level)
|
||||
|
||||
OBJ_NEW_BEGIN(ZstCompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
ZstCompress *driver = OBJ_NEW_ALLOC();
|
||||
ZstCompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::ZstCompress);
|
||||
|
||||
*driver = (ZstCompress)
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ zstDecompressNew(void)
|
||||
|
||||
OBJ_NEW_BEGIN(ZstDecompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
ZstDecompress *driver = OBJ_NEW_ALLOC();
|
||||
ZstDecompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::ZstDecompress);
|
||||
|
||||
*driver = (ZstDecompress)
|
||||
{
|
||||
|
@ -429,7 +429,7 @@ cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, Ciphe
|
||||
|
||||
OBJ_NEW_BEGIN(CipherBlock, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
CipherBlock *driver = OBJ_NEW_ALLOC();
|
||||
CipherBlock *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::CipherBlock);
|
||||
|
||||
*driver = (CipherBlock)
|
||||
{
|
||||
|
@ -184,7 +184,7 @@ cryptoHashNew(const HashType type)
|
||||
|
||||
OBJ_NEW_BEGIN(CryptoHash, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
CryptoHash *driver = OBJ_NEW_ALLOC();
|
||||
CryptoHash *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::CryptoHash);
|
||||
*driver = (CryptoHash){0};
|
||||
|
||||
// Use local MD5 implementation since FIPS-enabled systems do not allow MD5. This is a bit misguided since there are valid
|
||||
|
@ -10,6 +10,54 @@ Debug Routines
|
||||
#include "common/type/stringStatic.h"
|
||||
#include "common/type/stringZ.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
These functions allow auditing of child mem contexts and allocations that are left in the calling context when a function exits.
|
||||
This helps find leaks, i.e. child mem contexts or allocations created in the calling context (and not freed) accidentally.
|
||||
|
||||
The FUNCTION_AUDIT_*() macros can be used to annotate functions that do that follow the default behavior, i.e. that a single value
|
||||
is returned and that is the only value created in the calling context.
|
||||
***********************************************************************************************************************************/
|
||||
#if defined(DEBUG_MEM) && defined(DEBUG_TEST_TRACE)
|
||||
#include "common/macro.h"
|
||||
#include "common/memContext.h"
|
||||
|
||||
// Begin the audit
|
||||
#define FUNCTION_TEST_MEM_CONTEXT_AUDIT_BEGIN() \
|
||||
MemContextAuditState MEM_CONTEXT_AUDIT_param = {.memContext = memContextCurrent()}; \
|
||||
memContextAuditBegin(&MEM_CONTEXT_AUDIT_param)
|
||||
|
||||
// End the audit
|
||||
#define FUNCTION_TEST_MEM_CONTEXT_AUDIT_END(returnType) \
|
||||
memContextAuditEnd(&MEM_CONTEXT_AUDIT_param, returnType)
|
||||
|
||||
// Allow any new mem contexts or allocations in the calling context. These should be fixed and this macro eventually removed.
|
||||
#define FUNCTION_AUDIT_IF(condition) \
|
||||
do \
|
||||
{ \
|
||||
if (!(condition)) \
|
||||
MEM_CONTEXT_AUDIT_param.returnTypeAny = true; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
// Callbacks are difficult to audit so ignore them. Eventually they should all be removed.
|
||||
#define FUNCTION_AUDIT_CALLBACK() MEM_CONTEXT_AUDIT_param.returnTypeAny = true
|
||||
|
||||
// Helper function that creates new mem contexts or allocations in the calling context. These functions should be static (except
|
||||
// for interface helpers) but it is not clear that anything else needs to be done.
|
||||
#define FUNCTION_AUDIT_HELPER() MEM_CONTEXT_AUDIT_param.returnTypeAny = true
|
||||
|
||||
// Function returns a struct that has new mem contexts or allocations in the calling context. Find a way to fix these.
|
||||
#define FUNCTION_AUDIT_STRUCT() MEM_CONTEXT_AUDIT_param.returnTypeAny = true
|
||||
#else
|
||||
#define FUNCTION_TEST_MEM_CONTEXT_AUDIT_BEGIN()
|
||||
#define FUNCTION_TEST_MEM_CONTEXT_AUDIT_END(returnType)
|
||||
|
||||
#define FUNCTION_AUDIT_IF(condition)
|
||||
#define FUNCTION_AUDIT_CALLBACK()
|
||||
#define FUNCTION_AUDIT_HELPER()
|
||||
#define FUNCTION_AUDIT_STRUCT()
|
||||
#endif // DEBUG_TEST_TRACE_MACRO
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Base function debugging macros
|
||||
|
||||
@ -22,6 +70,7 @@ level is set to debug or trace.
|
||||
#ifdef DEBUG_TEST_TRACE
|
||||
#define FUNCTION_LOG_BEGIN_BASE(logLevel) \
|
||||
LogLevel FUNCTION_LOG_LEVEL() = STACK_TRACE_PUSH(logLevel); \
|
||||
FUNCTION_TEST_MEM_CONTEXT_AUDIT_BEGIN(); \
|
||||
\
|
||||
{ \
|
||||
stackTraceParamLog(); \
|
||||
@ -34,6 +83,7 @@ level is set to debug or trace.
|
||||
#else
|
||||
#define FUNCTION_LOG_BEGIN_BASE(logLevel) \
|
||||
LogLevel FUNCTION_LOG_LEVEL() = STACK_TRACE_PUSH(logLevel); \
|
||||
FUNCTION_TEST_MEM_CONTEXT_AUDIT_BEGIN(); \
|
||||
\
|
||||
if (logAny(FUNCTION_LOG_LEVEL())) \
|
||||
{ \
|
||||
@ -228,6 +278,7 @@ Macros to return function results (or void)
|
||||
{ \
|
||||
typePre FUNCTION_LOG_##typeMacroPrefix##_TYPE typePost FUNCTION_LOG_RETURN_result = __VA_ARGS__; \
|
||||
\
|
||||
FUNCTION_TEST_MEM_CONTEXT_AUDIT_END(STRINGIFY(FUNCTION_LOG_##typeMacroPrefix##_TYPE)); \
|
||||
STACK_TRACE_POP(false); \
|
||||
\
|
||||
IF_LOG_ANY(FUNCTION_LOG_LEVEL()) \
|
||||
@ -263,6 +314,7 @@ Macros to return function results (or void)
|
||||
#define FUNCTION_LOG_RETURN_STRUCT(...) \
|
||||
do \
|
||||
{ \
|
||||
FUNCTION_TEST_MEM_CONTEXT_AUDIT_END("struct"); \
|
||||
STACK_TRACE_POP(false); \
|
||||
\
|
||||
IF_LOG_ANY(FUNCTION_LOG_LEVEL()) \
|
||||
@ -300,6 +352,8 @@ Ignore DEBUG_TEST_TRACE_MACRO if DEBUG is not defined because the underlying fun
|
||||
|
||||
#ifdef DEBUG_TEST_TRACE_MACRO
|
||||
#define FUNCTION_TEST_BEGIN() \
|
||||
FUNCTION_TEST_MEM_CONTEXT_AUDIT_BEGIN(); \
|
||||
\
|
||||
/* Ensure that FUNCTION_LOG_BEGIN() and FUNCTION_TEST_BEGIN() are not both used in a single function by declaring the */ \
|
||||
/* same variable that FUNCTION_LOG_BEGIN() uses to track logging */ \
|
||||
LogLevel FUNCTION_LOG_LEVEL(); \
|
||||
@ -344,6 +398,7 @@ Ignore DEBUG_TEST_TRACE_MACRO if DEBUG is not defined because the underlying fun
|
||||
typePre type typePost FUNCTION_TEST_result = __VA_ARGS__; \
|
||||
\
|
||||
STACK_TRACE_POP(true); \
|
||||
FUNCTION_TEST_MEM_CONTEXT_AUDIT_END(STRINGIFY(type)); \
|
||||
\
|
||||
return FUNCTION_TEST_result; \
|
||||
} \
|
||||
@ -385,6 +440,7 @@ Ignore DEBUG_TEST_TRACE_MACRO if DEBUG is not defined because the underlying fun
|
||||
(void)FUNCTION_TEST_BEGIN_exists; \
|
||||
\
|
||||
STACK_TRACE_POP(true); \
|
||||
FUNCTION_TEST_MEM_CONTEXT_AUDIT_END("void"); \
|
||||
return; \
|
||||
} \
|
||||
while (0)
|
||||
|
@ -96,7 +96,7 @@ ioBufferReadNew(const Buffer *buffer)
|
||||
|
||||
OBJ_NEW_BEGIN(IoBufferRead, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
IoBufferRead *driver = OBJ_NEW_ALLOC();
|
||||
IoBufferRead *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoRead::IoBufferRead);
|
||||
|
||||
*driver = (IoBufferRead)
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ ioBufferWriteNew(Buffer *buffer)
|
||||
|
||||
OBJ_NEW_BEGIN(IoBufferWrite, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
IoBufferWrite *driver = OBJ_NEW_ALLOC();
|
||||
IoBufferWrite *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoWrite::IoBufferWrite);
|
||||
|
||||
*driver = (IoBufferWrite)
|
||||
{
|
||||
|
@ -158,7 +158,7 @@ ioFdReadNew(const String *name, int fd, TimeMSec timeout)
|
||||
|
||||
OBJ_NEW_BEGIN(IoFdRead, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
IoFdRead *driver = OBJ_NEW_ALLOC();
|
||||
IoFdRead *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoRead::IoFdRead);
|
||||
|
||||
*driver = (IoFdRead)
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ ioFdWriteNew(const String *name, int fd, TimeMSec timeout)
|
||||
|
||||
OBJ_NEW_BEGIN(IoFdWrite, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
IoFdWrite *driver = OBJ_NEW_ALLOC();
|
||||
IoFdWrite *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoWrite::IoFdWrite);
|
||||
|
||||
*driver = (IoFdWrite)
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ ioBufferNew(void)
|
||||
|
||||
OBJ_NEW_BEGIN(IoBuffer, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
IoBuffer *driver = OBJ_NEW_ALLOC();
|
||||
IoBuffer *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::IoBuffer);
|
||||
*driver = (IoBuffer){0};
|
||||
|
||||
this = ioFilterNewP(BUFFER_FILTER_TYPE, driver, NULL, .inOut = ioBufferProcess, .inputSame = ioBufferInputSame);
|
||||
|
@ -56,7 +56,7 @@ ioSinkNew(void)
|
||||
|
||||
OBJ_NEW_BEGIN(IoSink, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
IoSink *driver = OBJ_NEW_ALLOC();
|
||||
IoSink *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::IoSink);
|
||||
this = ioFilterNewP(SINK_FILTER_TYPE, driver, NULL, .inOut = ioSinkProcess);
|
||||
}
|
||||
OBJ_NEW_END();
|
||||
|
@ -95,7 +95,7 @@ ioSizeNew(void)
|
||||
|
||||
OBJ_NEW_BEGIN(IoSize, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
IoSize *driver = OBJ_NEW_ALLOC();
|
||||
IoSize *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::IoSize);
|
||||
*driver = (IoSize){0};
|
||||
|
||||
this = ioFilterNewP(SIZE_FILTER_TYPE, driver, NULL, .in = ioSizeProcess, .result = ioSizeResult);
|
||||
|
@ -174,7 +174,7 @@ sckClientNew(const String *const host, const unsigned int port, const TimeMSec t
|
||||
|
||||
OBJ_NEW_BEGIN(SocketClient, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
SocketClient *driver = OBJ_NEW_ALLOC();
|
||||
SocketClient *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoClient::SocketClient);
|
||||
|
||||
*driver = (SocketClient)
|
||||
{
|
||||
|
@ -157,7 +157,7 @@ sckServerNew(const String *const address, const unsigned int port, const TimeMSe
|
||||
|
||||
OBJ_NEW_BEGIN(SocketServer, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
SocketServer *const driver = OBJ_NEW_ALLOC();
|
||||
SocketServer *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoServer::SocketServer);
|
||||
|
||||
*driver = (SocketServer)
|
||||
{
|
||||
|
@ -181,7 +181,7 @@ sckSessionNew(IoSessionRole role, int fd, const String *host, unsigned int port,
|
||||
|
||||
OBJ_NEW_BEGIN(SocketSession, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
SocketSession *driver = OBJ_NEW_ALLOC();
|
||||
SocketSession *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoSession::SocketSession);
|
||||
|
||||
String *name = strNewFmt("%s:%u", strZ(host), port);
|
||||
|
||||
|
@ -370,7 +370,7 @@ tlsClientNew(
|
||||
|
||||
OBJ_NEW_BEGIN(TlsClient, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
TlsClient *driver = OBJ_NEW_ALLOC();
|
||||
TlsClient *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoClient::TlsClient);
|
||||
|
||||
*driver = (TlsClient)
|
||||
{
|
||||
|
@ -296,7 +296,7 @@ tlsServerNew(
|
||||
|
||||
OBJ_NEW_BEGIN(TlsServer, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
TlsServer *const driver = OBJ_NEW_ALLOC();
|
||||
TlsServer *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoServer::TlsServer);
|
||||
|
||||
*driver = (TlsServer)
|
||||
{
|
||||
|
@ -365,7 +365,7 @@ tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
|
||||
|
||||
OBJ_NEW_BEGIN(TlsSession, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
TlsSession *driver = OBJ_NEW_ALLOC();
|
||||
TlsSession *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoSession::TlsSession);
|
||||
|
||||
*driver = (TlsSession)
|
||||
{
|
||||
|
@ -93,6 +93,8 @@ lockReadFileData(const String *const lockFile, const int fd)
|
||||
FUNCTION_LOG_PARAM(INT, fd);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(lockFile != NULL);
|
||||
ASSERT(fd != -1);
|
||||
|
||||
@ -143,6 +145,8 @@ lockReadFile(const String *const lockFile, const LockReadFileParam param)
|
||||
FUNCTION_LOG_PARAM(BOOL, param.remove);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(lockFile != NULL);
|
||||
|
||||
LockReadResult result = {.status = lockReadStatusValid};
|
||||
@ -204,6 +208,8 @@ lockRead(const String *const lockPath, const String *const stanza, const LockTyp
|
||||
FUNCTION_LOG_PARAM(ENUM, lockType);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
LockReadResult result = {0};
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
|
@ -52,6 +52,7 @@ struct MemContext
|
||||
{
|
||||
#ifdef DEBUG
|
||||
const char *name; // Indicates what the context is being used for
|
||||
uint64_t sequenceNew; // Sequence when this context was created (used for audit)
|
||||
bool active:1; // Is the context currently active?
|
||||
#endif
|
||||
MemQty childQty:2; // How many child contexts can this context have?
|
||||
@ -228,6 +229,165 @@ static struct MemContextStack
|
||||
static unsigned int memContextCurrentStackIdx = 0;
|
||||
static unsigned int memContextMaxStackIdx = 0;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
***********************************************************************************************************************************/
|
||||
#ifdef DEBUG
|
||||
|
||||
static uint64_t memContextSequence = 0;
|
||||
|
||||
FN_EXTERN void
|
||||
memContextAuditBegin(MemContextAuditState *const state)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM_P(VOID, state);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(state != NULL);
|
||||
ASSERT(state->memContext != NULL);
|
||||
ASSERT(state->memContext == memContextTop() || state->memContext->sequenceNew != 0);
|
||||
|
||||
if (state->memContext->childInitialized)
|
||||
{
|
||||
ASSERT(state->memContext->childQty != memQtyNone);
|
||||
|
||||
if (state->memContext->childQty == memQtyOne)
|
||||
{
|
||||
MemContextChildOne *const memContextChild = memContextChildOne(state->memContext);
|
||||
|
||||
if (memContextChild->context != NULL)
|
||||
state->sequenceContextNew = memContextChild->context->sequenceNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(state->memContext->childQty == memQtyMany);
|
||||
MemContextChildMany *const memContextChild = memContextChildMany(state->memContext);
|
||||
|
||||
for (unsigned int contextIdx = 0; contextIdx < memContextChild->listSize; contextIdx++)
|
||||
{
|
||||
if (memContextChild->list[contextIdx] != NULL &&
|
||||
memContextChild->list[contextIdx]->sequenceNew > state->sequenceContextNew)
|
||||
{
|
||||
state->sequenceContextNew = memContextChild->list[contextIdx]->sequenceNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
static bool
|
||||
memContextAuditNameMatch(const char *const actual, const char *const expected)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRINGZ, actual);
|
||||
FUNCTION_TEST_PARAM(STRINGZ, expected);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(actual != NULL);
|
||||
ASSERT(expected != NULL);
|
||||
|
||||
unsigned int actualIdx = 0;
|
||||
|
||||
while (actual[actualIdx] != '\0' && actual[actualIdx] == expected[actualIdx])
|
||||
actualIdx++;
|
||||
|
||||
FUNCTION_TEST_RETURN(
|
||||
BOOL,
|
||||
(actual[actualIdx] == '\0' || strncmp(actual + actualIdx, "::", 2) == 0) &&
|
||||
(expected[actualIdx] == '\0' || strcmp(expected + actualIdx, " *") == 0));
|
||||
}
|
||||
|
||||
FN_EXTERN void
|
||||
memContextAuditEnd(const MemContextAuditState *const state, const char *const returnType)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM_P(VOID, state);
|
||||
FUNCTION_TEST_PARAM(STRINGZ, returnType);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (state->returnTypeAny)
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
|
||||
if (state->memContext->childInitialized)
|
||||
{
|
||||
ASSERT(state->memContext->childQty != memQtyNone);
|
||||
|
||||
const char *returnTypeInvalid = NULL;
|
||||
const char *returnTypeFound = NULL;
|
||||
|
||||
if (state->memContext->childQty == memQtyOne)
|
||||
{
|
||||
MemContextChildOne *const memContextChild = memContextChildOne(state->memContext);
|
||||
|
||||
if (memContextChild->context != NULL && memContextChild->context->sequenceNew > state->sequenceContextNew &&
|
||||
!memContextAuditNameMatch(memContextChild->context->name, returnType))
|
||||
{
|
||||
returnTypeInvalid = memContextChild->context->name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(state->memContext->childQty == memQtyMany);
|
||||
MemContextChildMany *const memContextChild = memContextChildMany(state->memContext);
|
||||
|
||||
for (unsigned int contextIdx = 0; contextIdx < memContextChild->listSize; contextIdx++)
|
||||
{
|
||||
if (memContextChild->list[contextIdx] != NULL &&
|
||||
memContextChild->list[contextIdx]->sequenceNew > state->sequenceContextNew)
|
||||
{
|
||||
if (memContextAuditNameMatch(memContextChild->list[contextIdx]->name, returnType))
|
||||
{
|
||||
if (returnTypeFound != NULL)
|
||||
{
|
||||
returnTypeInvalid = memContextChild->list[contextIdx]->name;
|
||||
break;
|
||||
}
|
||||
|
||||
returnTypeFound = memContextChild->list[contextIdx]->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnTypeInvalid = memContextChild->list[contextIdx]->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (returnTypeInvalid != NULL)
|
||||
{
|
||||
if (returnTypeFound != NULL)
|
||||
{
|
||||
THROW_FMT(
|
||||
AssertError, "expected return type '%s' already found but also found '%s'", returnTypeFound, returnTypeInvalid);
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
AssertError, "expected return type '%s' but found '%s'", returnType, returnTypeInvalid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
FN_EXTERN void *
|
||||
memContextAuditAllocExtraName(void *const allocExtra, const char *const name)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM_P(VOID, allocExtra);
|
||||
FUNCTION_TEST_PARAM(STRINGZ, name);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
memContextFromAllocExtra(allocExtra)->name = name;
|
||||
|
||||
FUNCTION_TEST_RETURN_P(VOID, allocExtra);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Wrapper around malloc() with error handling
|
||||
***********************************************************************************************************************************/
|
||||
@ -432,6 +592,9 @@ memContextNew(
|
||||
// Set the context name
|
||||
.name = name,
|
||||
|
||||
// Set audit sequence
|
||||
.sequenceNew = ++memContextSequence,
|
||||
|
||||
// Set new context active
|
||||
.active = true,
|
||||
#endif
|
||||
|
@ -38,6 +38,33 @@ Space is reserved for this many allocations when a context is created. When mor
|
||||
***********************************************************************************************************************************/
|
||||
#define MEM_CONTEXT_ALLOC_INITIAL_SIZE 4
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions and macros to audit a mem context by detecting new child contexts/allocations that were created begin the begin/end but
|
||||
are not the expected return type.
|
||||
***********************************************************************************************************************************/
|
||||
#if defined(DEBUG)
|
||||
typedef struct MemContextAuditState
|
||||
{
|
||||
MemContext *memContext; // Mem context to audit
|
||||
|
||||
bool returnTypeAny; // Skip auditing for this mem context
|
||||
uint64_t sequenceContextNew; // Max sequence for new contexts at beginning
|
||||
} MemContextAuditState;
|
||||
|
||||
// Begin the audit
|
||||
FN_EXTERN void memContextAuditBegin(MemContextAuditState *state);
|
||||
|
||||
// End the audit and make sure the return type is as expected
|
||||
FN_EXTERN void memContextAuditEnd(const MemContextAuditState *state, const char *returnTypeDefault);
|
||||
|
||||
// Rename a mem context using the extra allocation pointer
|
||||
#define MEM_CONTEXT_AUDIT_ALLOC_EXTRA_NAME(this, name) memContextAuditAllocExtraName(this, #name)
|
||||
|
||||
FN_EXTERN void *memContextAuditAllocExtraName(void *allocExtra, const char *name);
|
||||
#else
|
||||
#define MEM_CONTEXT_AUDIT_ALLOC_EXTRA_NAME(this, name) this
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Memory management functions
|
||||
|
||||
|
@ -131,6 +131,8 @@ kvPutInternal(KeyValue *this, const Variant *key, Variant *value)
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(key != NULL);
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
// Find the key
|
||||
unsigned int listIdx = kvGetIdx(this, key);
|
||||
|
||||
|
@ -41,6 +41,15 @@ OBJ_NEW_END();
|
||||
#define OBJ_NEW_END() \
|
||||
MEM_CONTEXT_NEW_END()
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Rename an object for auditing purposes. The original name for an object is based on the type used to create the object but a
|
||||
different name might be needed to identify it during auditing. For example, a filter named IoSink would need to be renamed to
|
||||
IoFilter to identify it as a filter for auditing.
|
||||
|
||||
This only has an effect in test builds.
|
||||
***********************************************************************************************************************************/
|
||||
#define OBJ_NAME(this, name) MEM_CONTEXT_AUDIT_ALLOC_EXTRA_NAME(this, name)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Used in interface function parameter lists to discourage use of the untyped thisVoid parameter, e.g.:
|
||||
|
||||
|
@ -1066,7 +1066,7 @@ pckReadPack(PackRead *const this, PckReadPackParam param)
|
||||
pckReadTag(this, ¶m.id, pckTypeMapPack, false);
|
||||
|
||||
// Get the pack size
|
||||
Buffer *result = bufNew(this->tagNextSize);
|
||||
Buffer *const result = OBJ_NAME(bufNew(this->tagNextSize), Pack::Buffer);
|
||||
|
||||
// Read the pack out in chunks
|
||||
while (bufUsed(result) < bufSize(result))
|
||||
@ -1939,7 +1939,7 @@ pckWriteResult(PackWrite *const this)
|
||||
{
|
||||
ASSERT(this->tagStack.top == NULL);
|
||||
|
||||
result = (Pack *)this->buffer;
|
||||
result = (Pack *)OBJ_NAME(this->buffer, Pack::Buffer);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(PACK, result);
|
||||
|
@ -137,7 +137,7 @@ Pack Functions
|
||||
FN_INLINE_ALWAYS Pack *
|
||||
pckDup(const Pack *const this)
|
||||
{
|
||||
return (Pack *)bufDup((const Buffer *)this);
|
||||
return (Pack *)OBJ_NAME(bufDup((const Buffer *)this), Pack::Buffer);
|
||||
}
|
||||
|
||||
// Cast Buffer to Pack
|
||||
|
@ -21,7 +21,7 @@ Constructors
|
||||
FN_INLINE_ALWAYS StringList *
|
||||
strLstNew(void)
|
||||
{
|
||||
return (StringList *)lstNewP(sizeof(String *), .comparator = lstComparatorStr);
|
||||
return (StringList *)OBJ_NAME(lstNewP(sizeof(String *), .comparator = lstComparatorStr), StringList::List);
|
||||
}
|
||||
|
||||
// Split a string into a string list based on a delimiter
|
||||
|
@ -211,7 +211,7 @@ varNewBool(bool data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantBool)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantBool);
|
||||
|
||||
*this = (VariantBool)
|
||||
{
|
||||
@ -320,7 +320,7 @@ varNewInt(int data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantInt)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantInt);
|
||||
|
||||
*this = (VariantInt)
|
||||
{
|
||||
@ -436,7 +436,7 @@ varNewInt64(int64_t data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantInt64)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantInt64);
|
||||
|
||||
*this = (VariantInt64)
|
||||
{
|
||||
@ -536,7 +536,7 @@ varNewUInt(unsigned int data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantUInt)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantUInt);
|
||||
|
||||
*this = (VariantUInt)
|
||||
{
|
||||
@ -661,7 +661,7 @@ varNewUInt64(uint64_t data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantUInt64)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantUInt64);
|
||||
|
||||
*this = (VariantUInt64)
|
||||
{
|
||||
@ -773,7 +773,7 @@ varNewKv(KeyValue *data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantKeyValue, .childQty = 1)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantKeyValue);
|
||||
|
||||
*this = (VariantKeyValue)
|
||||
{
|
||||
@ -826,7 +826,7 @@ varNewStr(const String *data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantString, .childQty = 1)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantString);
|
||||
|
||||
*this = (VariantString)
|
||||
{
|
||||
@ -844,7 +844,7 @@ varNewStr(const String *data)
|
||||
|
||||
OBJ_NEW_EXTRA_BEGIN(VariantString, (uint16_t)(allocExtra))
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantString);
|
||||
|
||||
*this = (VariantString)
|
||||
{
|
||||
@ -982,7 +982,7 @@ varNewVarLst(const VariantList *data)
|
||||
|
||||
OBJ_NEW_BEGIN(VariantVariantList, .childQty = 1)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), Variant::VariantVariantList);
|
||||
|
||||
*this = (VariantVariantList)
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ Constructors
|
||||
FN_INLINE_ALWAYS VariantList *
|
||||
varLstNew(void)
|
||||
{
|
||||
return (VariantList *)lstNewP(sizeof(Variant *));
|
||||
return (VariantList *)OBJ_NAME(lstNewP(sizeof(Variant *)), VariantList::List);
|
||||
}
|
||||
|
||||
// Create VariantList from StringList
|
||||
|
@ -79,7 +79,7 @@ static XmlNodeList *
|
||||
xmlNodeLstNew(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(XML_NODE_LIST, (XmlNodeList *)lstNewP(sizeof(XmlNode *)));
|
||||
FUNCTION_TEST_RETURN(XML_NODE_LIST, (XmlNodeList *)OBJ_NAME(lstNewP(sizeof(XmlNode *)), XmlNodeList::List));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
|
@ -67,6 +67,8 @@ cfgLoadUpdateOption(void)
|
||||
{
|
||||
FUNCTION_LOG_VOID(logLevelTrace);
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
// Make sure the repo option is set for the stanza-delete command when more than one repo is configured or the first configured
|
||||
// repo is not key 1.
|
||||
if (!cfgCommandHelp() && cfgOptionValid(cfgOptRepo) && cfgCommand() == cfgCmdStanzaDelete &&
|
||||
|
@ -765,6 +765,8 @@ cfgParseOptionalRule(
|
||||
FUNCTION_TEST_PARAM(ENUM, optionId);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(optionalRuleType != 0);
|
||||
ASSERT(commandId < CFG_COMMAND_TOTAL);
|
||||
ASSERT(optionId < CFG_OPTION_TOTAL);
|
||||
@ -1103,7 +1105,7 @@ cfgParseOptionKeyIdxName(ConfigOption optionId, unsigned int keyIdx)
|
||||
FUNCTION_TEST_RETURN_CONST(
|
||||
STRINGZ,
|
||||
zNewFmt(
|
||||
"%s%u%s", parseRuleOptionGroup[parseRuleOption[optionId].groupId].name, keyIdx + 1,
|
||||
"%s%u%s", parseRuleOptionGroup[parseRuleOption[optionId].groupId].name, keyIdx + 1,
|
||||
parseRuleOption[optionId].name + strlen(parseRuleOptionGroup[parseRuleOption[optionId].groupId].name)));
|
||||
}
|
||||
|
||||
@ -1222,6 +1224,8 @@ cfgFileLoadPart(String **config, const Buffer *configPart)
|
||||
FUNCTION_LOG_PARAM(BUFFER, configPart);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
if (configPart != NULL)
|
||||
{
|
||||
String *configPartStr = strNewBuf(configPart);
|
||||
@ -1265,6 +1269,8 @@ cfgFileLoad( // NOTE: Pas
|
||||
FUNCTION_LOG_PARAM(STRING, origConfigDefault);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(optionList != NULL);
|
||||
ASSERT(optConfigDefault != NULL);
|
||||
ASSERT(optConfigIncludePathDefault != NULL);
|
||||
|
@ -377,6 +377,8 @@ dbBackupStart(Db *const this, const bool startFast, const bool stopAuto, const b
|
||||
FUNCTION_LOG_PARAM(BOOL, archiveCheck);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
DbBackupStartResult result = {.lsn = NULL};
|
||||
@ -541,6 +543,8 @@ dbBackupStop(Db *this)
|
||||
FUNCTION_LOG_PARAM(DB, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
DbBackupStopResult result = {.lsn = NULL};
|
||||
|
@ -56,6 +56,8 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
|
||||
FUNCTION_LOG_PARAM(BOOL, standbyRequired);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(!(primaryOnly && standbyRequired));
|
||||
|
||||
DbGetResult result = {0};
|
||||
|
@ -163,6 +163,8 @@ infoLoadCallback(void *const data, const String *const section, const String *co
|
||||
FUNCTION_TEST_PARAM(STRING, value);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(data != NULL);
|
||||
ASSERT(section != NULL);
|
||||
ASSERT(key != NULL);
|
||||
@ -250,6 +252,8 @@ infoNewLoad(IoRead *read, InfoLoadNewCallback *callbackFunction, void *callbackD
|
||||
FUNCTION_LOG_PARAM_P(VOID, callbackData);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(read != NULL);
|
||||
ASSERT(callbackFunction != NULL);
|
||||
ASSERT(callbackData != NULL);
|
||||
@ -336,6 +340,8 @@ infoSaveValue(InfoSave *const infoSaveData, const char *const section, const cha
|
||||
FUNCTION_TEST_PARAM(STRING, jsonValue);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(infoSaveData != NULL);
|
||||
ASSERT(section != NULL);
|
||||
ASSERT(key != NULL);
|
||||
@ -450,6 +456,8 @@ infoCipherPassSet(Info *this, const String *cipherPass)
|
||||
FUNCTION_TEST_PARAM(STRING, cipherPass);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_IF(memContextCurrent() != this->memContext); // Do not audit calls from within the object
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
|
@ -47,6 +47,8 @@ infoBackupNewInternal(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
InfoBackup *this = OBJ_NEW_ALLOC();
|
||||
|
||||
*this = (InfoBackup)
|
||||
@ -252,6 +254,8 @@ infoBackupSaveCallback(void *const data, const String *const sectionNext, InfoSa
|
||||
FUNCTION_TEST_PARAM(INFO_SAVE, infoSaveData);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(data != NULL);
|
||||
ASSERT(infoSaveData != NULL);
|
||||
|
||||
|
@ -43,6 +43,8 @@ infoPgNewInternal(InfoPgType type)
|
||||
FUNCTION_TEST_PARAM(STRING_ID, type);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
InfoPg *this = OBJ_NEW_ALLOC();
|
||||
|
||||
*this = (InfoPg)
|
||||
@ -106,6 +108,8 @@ infoPgLoadCallback(void *const data, const String *const section, const String *
|
||||
FUNCTION_TEST_PARAM(STRING, value);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(data != NULL);
|
||||
ASSERT(section != NULL);
|
||||
ASSERT(key != NULL);
|
||||
@ -285,6 +289,8 @@ infoPgSaveCallback(void *const data, const String *const sectionNext, InfoSave *
|
||||
FUNCTION_TEST_PARAM(INFO_SAVE, infoSaveData);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(data != NULL);
|
||||
ASSERT(infoSaveData != NULL);
|
||||
|
||||
|
@ -499,6 +499,8 @@ manifestNewInternal(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
Manifest *this = OBJ_NEW_ALLOC();
|
||||
|
||||
*this = (Manifest)
|
||||
@ -546,6 +548,7 @@ static ManifestLinkCheck
|
||||
manifestLinkCheckInit(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
FUNCTION_TEST_RETURN_TYPE(
|
||||
ManifestLinkCheck, (ManifestLinkCheck){.linkList = lstNewP(sizeof(ManifestLinkCheckItem), .comparator = lstComparatorStr)});
|
||||
}
|
||||
@ -754,6 +757,8 @@ manifestBuildInfo(
|
||||
FUNCTION_TEST_PARAM(STORAGE_INFO, *info);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(buildData != NULL);
|
||||
ASSERT(manifestParentName != NULL);
|
||||
ASSERT(pgPath != NULL);
|
||||
@ -1817,6 +1822,8 @@ manifestLoadCallback(void *callbackData, const String *const section, const Stri
|
||||
FUNCTION_TEST_PARAM(STRING, value);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(callbackData != NULL);
|
||||
ASSERT(section != NULL);
|
||||
ASSERT(key != NULL);
|
||||
@ -2307,6 +2314,8 @@ manifestSaveCallback(void *const callbackData, const String *const sectionNext,
|
||||
FUNCTION_TEST_PARAM(INFO_SAVE, infoSaveData);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(callbackData != NULL);
|
||||
ASSERT(infoSaveData != NULL);
|
||||
|
||||
|
@ -195,6 +195,8 @@ protocolLocalExec(
|
||||
FUNCTION_TEST_PARAM(UINT, processId);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(helper != NULL);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
@ -671,6 +673,8 @@ protocolRemoteExec(
|
||||
FUNCTION_TEST_PARAM(UINT, processId);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(helper != NULL);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
|
@ -113,6 +113,8 @@ protocolServerCommandGet(ProtocolServer *const this)
|
||||
FUNCTION_LOG_PARAM(PROTOCOL_SERVER, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ProtocolServerCommandGetResult result = {0};
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
|
@ -127,7 +127,7 @@ storageReadAzureNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageReadAzure, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageReadAzure *driver = OBJ_NEW_ALLOC();
|
||||
StorageReadAzure *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageRead::StorageReadAzure);
|
||||
|
||||
*driver = (StorageReadAzure)
|
||||
{
|
||||
|
@ -315,6 +315,8 @@ storageAzureListInternal(
|
||||
FUNCTION_LOG_PARAM_P(VOID, callbackData);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(path != NULL);
|
||||
|
||||
@ -734,7 +736,7 @@ storageAzureNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageAzure, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageAzure *driver = OBJ_NEW_ALLOC();
|
||||
StorageAzure *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), Storage::StorageAzure);
|
||||
|
||||
*driver = (StorageAzure)
|
||||
{
|
||||
|
@ -276,7 +276,7 @@ storageWriteAzureNew(StorageAzure *storage, const String *name, uint64_t fileId,
|
||||
|
||||
OBJ_NEW_BEGIN(StorageWriteAzure, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageWriteAzure *driver = OBJ_NEW_ALLOC();
|
||||
StorageWriteAzure *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageWrite::StorageWriteAzure);
|
||||
|
||||
*driver = (StorageWriteAzure)
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ storageReadGcsNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageReadGcs, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageReadGcs *driver = OBJ_NEW_ALLOC();
|
||||
StorageReadGcs *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageRead::StorageReadGcs);
|
||||
|
||||
*driver = (StorageReadGcs)
|
||||
{
|
||||
|
@ -118,6 +118,8 @@ storageGcsAuthToken(HttpRequest *const request, const time_t timeBegin)
|
||||
FUNCTION_TEST_PARAM(TIME, timeBegin);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
StorageGcsAuthTokenResult result = {0};
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
@ -246,6 +248,8 @@ storageGcsAuthService(StorageGcs *this, time_t timeBegin)
|
||||
FUNCTION_TEST_PARAM(TIME, timeBegin);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(timeBegin > 0);
|
||||
|
||||
@ -289,6 +293,8 @@ storageGcsAuthAuto(StorageGcs *this, time_t timeBegin)
|
||||
FUNCTION_TEST_PARAM(TIME, timeBegin);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(timeBegin > 0);
|
||||
|
||||
@ -543,6 +549,8 @@ storageGcsListInternal(
|
||||
FUNCTION_LOG_PARAM_P(VOID, callbackData);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(path != NULL);
|
||||
|
||||
@ -965,7 +973,7 @@ storageGcsNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageGcs, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageGcs *driver = OBJ_NEW_ALLOC();
|
||||
StorageGcs *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), Storage::StorageGcs);
|
||||
|
||||
*driver = (StorageGcs)
|
||||
{
|
||||
|
@ -335,7 +335,7 @@ storageWriteGcsNew(StorageGcs *storage, const String *name, size_t chunkSize)
|
||||
|
||||
OBJ_NEW_BEGIN(StorageWriteGcs, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageWriteGcs *driver = OBJ_NEW_ALLOC();
|
||||
StorageWriteGcs *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageWrite::StorageWriteGcs);
|
||||
|
||||
*driver = (StorageWriteGcs)
|
||||
{
|
||||
|
@ -224,7 +224,7 @@ storageReadPosixNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageReadPosix, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
StorageReadPosix *driver = OBJ_NEW_ALLOC();
|
||||
StorageReadPosix *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageRead::StorageReadPosix);
|
||||
|
||||
*driver = (StorageReadPosix)
|
||||
{
|
||||
|
@ -48,6 +48,8 @@ storagePosixInfo(THIS_VOID, const String *file, StorageInfoLevel level, StorageI
|
||||
FUNCTION_LOG_PARAM(BOOL, param.followLink);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(file != NULL);
|
||||
|
||||
@ -167,6 +169,8 @@ storagePosixListEntry(
|
||||
FUNCTION_TEST_PARAM(ENUM, level);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(list != NULL);
|
||||
ASSERT(path != NULL);
|
||||
@ -612,7 +616,7 @@ storagePosixNewInternal(
|
||||
|
||||
OBJ_NEW_BEGIN(StoragePosix, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StoragePosix *driver = OBJ_NEW_ALLOC();
|
||||
StoragePosix *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), Storage::StoragePosix);
|
||||
|
||||
*driver = (StoragePosix)
|
||||
{
|
||||
|
@ -249,7 +249,7 @@ storageWritePosixNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageWritePosix, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
StorageWritePosix *driver = OBJ_NEW_ALLOC();
|
||||
StorageWritePosix *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageWrite::StorageWritePosix);
|
||||
|
||||
*driver = (StorageWritePosix)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ storageReadNew(void *driver, const StorageReadInterface *interface)
|
||||
FUNCTION_LOG_PARAM_P(STORAGE_READ_INTERFACE, interface);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(driver != NULL);
|
||||
ASSERT(interface != NULL);
|
||||
|
||||
|
@ -132,6 +132,8 @@ storageRemoteFeatureProtocol(PackRead *const param, ProtocolServer *const server
|
||||
FUNCTION_LOG_PARAM(PROTOCOL_SERVER, server);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(param == NULL);
|
||||
ASSERT(server != NULL);
|
||||
|
||||
@ -194,6 +196,8 @@ storageRemoteInfoProtocolPut(
|
||||
FUNCTION_TEST_PARAM(STORAGE_INFO, info);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(data != NULL);
|
||||
ASSERT(write != NULL);
|
||||
ASSERT(info != NULL);
|
||||
|
@ -306,7 +306,7 @@ storageReadRemoteNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageReadRemote, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), StorageRead::StorageReadRemote);
|
||||
|
||||
*this = (StorageReadRemote)
|
||||
{
|
||||
|
@ -44,6 +44,8 @@ storageRemoteInfoGet(StorageRemoteInfoData *const data, PackRead *const read, St
|
||||
FUNCTION_TEST_PARAM(STORAGE_INFO, info);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(data != NULL);
|
||||
ASSERT(read != NULL);
|
||||
ASSERT(info != NULL);
|
||||
@ -126,6 +128,8 @@ storageRemoteInfo(THIS_VOID, const String *file, StorageInfoLevel level, Storage
|
||||
FUNCTION_LOG_PARAM(BOOL, param.followLink);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
StorageInfo result = {.level = level};
|
||||
@ -486,7 +490,7 @@ storageRemoteNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageRemote, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageRemote *driver = OBJ_NEW_ALLOC();
|
||||
StorageRemote *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), Storage::StorageRemote);
|
||||
|
||||
*driver = (StorageRemote)
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ storageWriteRemoteNew(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageWriteRemote, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
|
||||
{
|
||||
this = OBJ_NEW_ALLOC();
|
||||
this = OBJ_NAME(OBJ_NEW_ALLOC(), StorageWrite::StorageWriteRemote);
|
||||
|
||||
*this = (StorageWriteRemote)
|
||||
{
|
||||
|
@ -130,7 +130,7 @@ storageReadS3New(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageReadS3, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageReadS3 *driver = OBJ_NEW_ALLOC();
|
||||
StorageReadS3 *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageRead::StorageReadS3);
|
||||
|
||||
*driver = (StorageReadS3)
|
||||
{
|
||||
|
@ -622,6 +622,8 @@ storageS3ListInternal(
|
||||
FUNCTION_LOG_PARAM_P(VOID, callbackData);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_CALLBACK();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(path != NULL);
|
||||
|
||||
@ -1131,7 +1133,7 @@ storageS3New(
|
||||
|
||||
OBJ_NEW_BEGIN(StorageS3, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageS3 *driver = OBJ_NEW_ALLOC();
|
||||
StorageS3 *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), Storage::StorageS3);
|
||||
|
||||
*driver = (StorageS3)
|
||||
{
|
||||
|
@ -280,7 +280,7 @@ storageWriteS3New(StorageS3 *storage, const String *name, size_t partSize)
|
||||
|
||||
OBJ_NEW_BEGIN(StorageWriteS3, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
StorageWriteS3 *driver = OBJ_NEW_ALLOC();
|
||||
StorageWriteS3 *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), StorageWrite::StorageWriteS3);
|
||||
|
||||
*driver = (StorageWriteS3)
|
||||
{
|
||||
|
@ -46,6 +46,8 @@ storageNew(
|
||||
FUNCTION_LOG_PARAM(STORAGE_INTERFACE, interface);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(type != 0);
|
||||
ASSERT(strSize(path) >= 1 && strZ(path)[0] == '/');
|
||||
ASSERT(driver != NULL);
|
||||
@ -243,6 +245,8 @@ storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param)
|
||||
FUNCTION_LOG_PARAM(BOOL, param.noPathEnforce);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->pub.interface.info != NULL);
|
||||
|
||||
|
@ -37,6 +37,8 @@ storageWriteNew(void *driver, const StorageWriteInterface *interface)
|
||||
FUNCTION_LOG_PARAM_P(STORAGE_WRITE_INTERFACE, interface);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(driver != NULL);
|
||||
ASSERT(interface != NULL);
|
||||
|
||||
|
@ -79,13 +79,6 @@ unit:
|
||||
- common/debug
|
||||
- common/type/stringStatic
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: type-convert
|
||||
total: 12
|
||||
|
||||
coverage:
|
||||
- common/type/convert
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: assert-off
|
||||
total: 1
|
||||
@ -109,7 +102,7 @@ unit:
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: mem-context
|
||||
total: 7
|
||||
total: 8
|
||||
feature: memContext
|
||||
|
||||
coverage:
|
||||
@ -118,6 +111,13 @@ unit:
|
||||
depend:
|
||||
- common/type/convert
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: type-convert
|
||||
total: 12
|
||||
|
||||
coverage:
|
||||
- common/type/convert
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: time
|
||||
total: 3
|
||||
|
@ -23,6 +23,8 @@ testDefParseModuleList(Yaml *const yaml, List *const moduleList)
|
||||
FUNCTION_LOG_PARAM(LIST, moduleList);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
// Global lists to be copied to next test
|
||||
StringList *const globalDependList = strLstNew();
|
||||
StringList *const globalFeatureList = strLstNew();
|
||||
@ -313,6 +315,8 @@ testDefParse(const Storage *const storageRepo)
|
||||
FUNCTION_LOG_PARAM(STORAGE, storageRepo);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_STRUCT();
|
||||
|
||||
// Module list
|
||||
List *const moduleList = lstNewP(sizeof(TestDefModule), .comparator = lstComparatorStr);
|
||||
|
||||
|
@ -47,6 +47,8 @@ cmdTestPathCreate(const Storage *const storage, const String *const path)
|
||||
FUNCTION_LOG_PARAM(STRING, path);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
FUNCTION_AUDIT_HELPER();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
|
||||
TRY_BEGIN()
|
||||
|
@ -73,7 +73,7 @@ testRun(void)
|
||||
{
|
||||
TEST_TITLE("struct size");
|
||||
|
||||
TEST_RESULT_UINT(sizeof(MemContext), TEST_64BIT() ? 24 : 16, "MemContext size");
|
||||
TEST_RESULT_UINT(sizeof(MemContext), TEST_64BIT() ? 32 : 24, "MemContext size");
|
||||
TEST_RESULT_UINT(sizeof(MemContextChildMany), TEST_64BIT() ? 16 : 12, "MemContextChildMany size");
|
||||
TEST_RESULT_UINT(sizeof(MemContextAllocMany), TEST_64BIT() ? 16 : 12, "MemContextAllocMany size");
|
||||
TEST_RESULT_UINT(sizeof(MemContextCallbackOne), TEST_64BIT() ? 16 : 8, "MemContextCallbackOne size");
|
||||
@ -174,7 +174,7 @@ testRun(void)
|
||||
MEM_CONTEXT_INITIAL_SIZE, "context child list initial size");
|
||||
|
||||
// This test will change if the contexts above change
|
||||
TEST_RESULT_UINT(memContextSize(memContextTop()), TEST_64BIT() ? 584 : 376, "check size");
|
||||
TEST_RESULT_UINT(memContextSize(memContextTop()), TEST_64BIT() ? 656 : 448, "check size");
|
||||
|
||||
TEST_ERROR(
|
||||
memContextFree(memContextChildMany(memContextTop())->list[MEM_CONTEXT_INITIAL_SIZE]), AssertError,
|
||||
@ -196,10 +196,9 @@ testRun(void)
|
||||
{
|
||||
TEST_TITLE("struct size");
|
||||
|
||||
TEST_RESULT_UINT(sizeof(MemContextAlloc), 8, "MemContextAlloc size");
|
||||
TEST_RESULT_UINT(sizeof(MemContextAlloc), 8, "check MemContextAlloc size (same for 32/64 bit)");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_UINT(sizeof(MemContextAlloc), 8, "check MemContextAlloc size (same for 32/64 bit)");
|
||||
TEST_RESULT_PTR(MEM_CONTEXT_ALLOC_BUFFER((void *)1), (void *)(sizeof(MemContextAlloc) + 1), "check buffer macro");
|
||||
TEST_RESULT_PTR(MEM_CONTEXT_ALLOC_HEADER((void *)sizeof(MemContextAlloc)), (void *)0, "check header macro");
|
||||
|
||||
@ -255,7 +254,7 @@ testRun(void)
|
||||
memContextAllocMany(memContextCurrent())->freeIdx, MEM_CONTEXT_ALLOC_INITIAL_SIZE + 3, "check alloc free idx");
|
||||
|
||||
// This test will change if the allocations above change
|
||||
TEST_RESULT_UINT(memContextSize(memContextCurrent()), TEST_64BIT() ? 209 : 145, "check size");
|
||||
TEST_RESULT_UINT(memContextSize(memContextCurrent()), TEST_64BIT() ? 217 : 153, "check size");
|
||||
|
||||
TEST_ERROR(
|
||||
memFree(NULL), AssertError,
|
||||
@ -282,7 +281,7 @@ testRun(void)
|
||||
TEST_ASSIGN(buffer, memNew(200), "new");
|
||||
|
||||
// This test will change if the allocations above change
|
||||
TEST_RESULT_UINT(memContextSize(memContextCurrent()), TEST_64BIT() ? 240 : 228, "check size");
|
||||
TEST_RESULT_UINT(memContextSize(memContextCurrent()), TEST_64BIT() ? 248 : 236, "check size");
|
||||
|
||||
TEST_RESULT_VOID(memContextSwitch(memContextTop()), "switch to top");
|
||||
TEST_RESULT_VOID(memContextFree(memContext), "context free");
|
||||
@ -298,7 +297,7 @@ testRun(void)
|
||||
TEST_RESULT_VOID(memFree(buffer), "free");
|
||||
|
||||
// This test will change if the allocations above change
|
||||
TEST_RESULT_UINT(memContextSize(memContextCurrent()), TEST_64BIT() ? 32 : 20, "check size");
|
||||
TEST_RESULT_UINT(memContextSize(memContextCurrent()), TEST_64BIT() ? 40 : 28, "check size");
|
||||
|
||||
TEST_RESULT_VOID(memContextSwitch(memContextTop()), "switch to top");
|
||||
TEST_RESULT_VOID(memContextFree(memContext), "context free");
|
||||
@ -535,6 +534,140 @@ testRun(void)
|
||||
TEST_RESULT_PTR(memContextChildOne(memContextParent2)->context, memContextChild, "check parent2");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("memContextAudit*s()"))
|
||||
{
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("one child context void success with no child context");
|
||||
|
||||
MemContext *parent = memContextNewP("to be renamed", .allocExtra = 8, .childQty = 1);
|
||||
memContextKeep();
|
||||
memContextSwitch(parent);
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditAllocExtraName(memContextAllocExtra(parent), "one context child"), "rename context");
|
||||
TEST_RESULT_Z(parent->name, "one context child", "check name");
|
||||
|
||||
MemContextAuditState audit = {.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "void"), "audit end");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("return immediately on any");
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
audit.returnTypeAny = true;
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "void"), "audit end");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("one child context void success");
|
||||
|
||||
MemContext *child = memContextNewP("child", .childQty = 1);
|
||||
memContextKeep();
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "void"), "audit end");
|
||||
|
||||
memContextFree(child);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("one child context void success (freed context)");
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "void"), "audit end");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("one child context match success");
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
|
||||
child = memContextNewP("child", .childQty = 1);
|
||||
memContextKeep();
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "child"), "audit end");
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "child *"), "audit end");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("one child context match failure");
|
||||
|
||||
TEST_ERROR(memContextAuditEnd(&audit, "child2"), AssertError, "expected return type 'child2' but found 'child'");
|
||||
TEST_ERROR(memContextAuditEnd(&audit, "chil"), AssertError, "expected return type 'chil' but found 'child'");
|
||||
|
||||
memContextSwitchBack();
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("many child context void success with no child context");
|
||||
|
||||
parent = memContextNewP("many context child", .childQty = MEM_CONTEXT_QTY_MAX);
|
||||
memContextKeep();
|
||||
memContextSwitch(parent);
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "void"), "audit end");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("many child context void success");
|
||||
|
||||
child = memContextNewP("child", .childQty = 1);
|
||||
memContextKeep();
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "void"), "audit end");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("many child context success with child context created before");
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
TEST_RESULT_VOID(memContextAuditEnd(&audit, "child"), "audit end");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("many child context failure with multiple matches");
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
|
||||
memContextNewP("child2::extra", .childQty = 1);
|
||||
memContextKeep();
|
||||
|
||||
memContextFree(child);
|
||||
memContextNewP("child2::extra", .childQty = 1);
|
||||
memContextKeep();
|
||||
|
||||
TEST_ERROR(
|
||||
memContextAuditEnd(&audit, "child2"), AssertError,
|
||||
"expected return type 'child2::extra' already found but also found 'child2::extra'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("many child context failure with no match");
|
||||
|
||||
audit = (MemContextAuditState){.memContext = memContextCurrent()};
|
||||
|
||||
TEST_RESULT_VOID(memContextAuditBegin(&audit), "audit begin");
|
||||
|
||||
memContextNewP("child3::extra", .childQty = 1);
|
||||
memContextKeep();
|
||||
|
||||
TEST_ERROR(
|
||||
memContextAuditEnd(&audit, "child2"), AssertError,
|
||||
"expected return type 'child2' but found 'child3::extra'");
|
||||
|
||||
memContextSwitchBack();
|
||||
}
|
||||
|
||||
memContextFree(memContextTop());
|
||||
|
||||
FUNCTION_HARNESS_RETURN_VOID();
|
||||
|
Loading…
x
Reference in New Issue
Block a user