1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-06-18 23:57:33 +02:00

Add stack trace macros to all functions.

Low-level functions only include stack trace in test builds while higher-level functions ship with stack trace built-in. Stack traces include all parameters passed to the function but production builds only create the parameter list when the log level is set high enough, i.e. debug or trace depending on the function.
This commit is contained in:
David Steele
2018-05-18 11:57:32 -04:00
parent abb9651f4c
commit 52bc073234
141 changed files with 6489 additions and 1179 deletions

View File

@ -1,6 +1,7 @@
/***********************************************************************************************************************************
PostgreSQL Info
***********************************************************************************************************************************/
#include "common/debug.h"
#include "common/memContext.h"
#include "postgres/info.h"
#include "postgres/type.h"
@ -13,6 +14,11 @@ Map control/catalog version to PostgreSQL version
static uint
pgVersionMap(uint32_t controlVersion, uint32_t catalogVersion)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT32, controlVersion);
FUNCTION_TEST_PARAM(UINT32, catalogVersion);
FUNCTION_TEST_END();
uint result = 0;
if (controlVersion == 1002 && catalogVersion == 201707211)
@ -44,7 +50,7 @@ pgVersionMap(uint32_t controlVersion, uint32_t catalogVersion)
controlVersion, catalogVersion);
}
return result;
FUNCTION_TEST_RESULT(UINT, result);
}
/***********************************************************************************************************************************
@ -53,6 +59,12 @@ Get info from pg_control
PgControlInfo
pgControlInfo(const String *pgPath)
{
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STRING, pgPath);
FUNCTION_TEST_ASSERT(pgPath != NULL);
FUNCTION_DEBUG_END();
PgControlInfo result = {0};
MEM_CONTEXT_TEMP_BEGIN()
@ -73,5 +85,5 @@ pgControlInfo(const String *pgPath)
}
MEM_CONTEXT_TEMP_END();
return result;
FUNCTION_DEBUG_RESULT(PG_CONTROL_INFO, result);
}

View File

@ -25,4 +25,12 @@ Functions
***********************************************************************************************************************************/
PgControlInfo pgControlInfo(const String *pgPath);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_PG_CONTROL_INFO_TYPE \
PgControlInfo
#define FUNCTION_DEBUG_PG_CONTROL_INFO_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "PgControlInfo", buffer, bufferSize)
#endif

View File

@ -65,6 +65,7 @@ minimize register spilling. For less sophisticated compilers it might be benefic
#include <string.h>
#include "common/assert.h"
#include "common/debug.h"
#include "common/error.h"
#include "postgres/pageChecksum.h"
#include "postgres/type.h"
@ -134,10 +135,15 @@ do { \
} while (0)
static uint32_t
pageChecksumBlock(const unsigned char *page, uint32_t pageSize)
pageChecksumBlock(const unsigned char *page, unsigned int pageSize)
{
ASSERT_DEBUG(page != NULL);
ASSERT_DEBUG(pageSize == PG_PAGE_SIZE);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UCHARP, page);
FUNCTION_TEST_PARAM(UINT, pageSize);
FUNCTION_TEST_ASSERT(page != NULL);
FUNCTION_TEST_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_TEST_END();
uint32_t sums[N_SUMS];
uint32_t (*dataArray)[N_SUMS] = (uint32_t (*)[N_SUMS])page;
@ -161,7 +167,7 @@ pageChecksumBlock(const unsigned char *page, uint32_t pageSize)
for (i = 0; i < N_SUMS; i++)
result ^= sums[i];
return result;
FUNCTION_TEST_RESULT(UINT32, result);
}
/***********************************************************************************************************************************
@ -173,7 +179,14 @@ The checksum includes the block number (to detect the case where a page is someh
uint16_t
pageChecksum(const unsigned char *page, unsigned int blockNo, unsigned int pageSize)
{
ASSERT_DEBUG(page != NULL);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UCHARP, page);
FUNCTION_TEST_PARAM(UINT, blockNo);
FUNCTION_TEST_PARAM(UINT, pageSize);
FUNCTION_TEST_ASSERT(page != NULL);
FUNCTION_TEST_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_TEST_END();
// Save pd_checksum and temporarily set it to zero, so that the checksum calculation isn't affected by the old checksum stored
// on the page. Restore it after, because actually updating the checksum is NOT part of the API of this function.
@ -188,7 +201,7 @@ pageChecksum(const unsigned char *page, unsigned int blockNo, unsigned int pageS
checksum ^= blockNo;
// Reduce to a uint16 with an offset of one. That avoids checksums of zero, which seems like a good idea.
return (uint16_t)((checksum % 65535) + 1);
FUNCTION_TEST_RESULT(UINT16, (uint16_t)(checksum % 65535 + 1));
}
/***********************************************************************************************************************************
@ -198,15 +211,25 @@ bool
pageChecksumTest(
const unsigned char *page, unsigned int blockNo, unsigned int pageSize, uint32_t ignoreWalId, uint32_t ignoreWalOffset)
{
ASSERT_DEBUG(page != NULL);
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UCHARP, page);
FUNCTION_TEST_PARAM(UINT, blockNo);
FUNCTION_TEST_PARAM(UINT, pageSize);
FUNCTION_TEST_PARAM(UINT32, ignoreWalId);
FUNCTION_TEST_PARAM(UINT32, ignoreWalOffset);
return
FUNCTION_TEST_ASSERT(page != NULL);
FUNCTION_TEST_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(
BOOL,
// This is a new page so don't test checksum
((PageHeader)page)->pd_upper == 0 ||
// LSN is after the backup started so checksum is not tested because pages may be torn
(((PageHeader)page)->pd_lsn.walid >= ignoreWalId && ((PageHeader)page)->pd_lsn.xrecoff >= ignoreWalOffset) ||
// Checksum is valid
((PageHeader)page)->pd_checksum == pageChecksum(page, blockNo, pageSize);
((PageHeader)page)->pd_checksum == pageChecksum(page, blockNo, pageSize));
}
/***********************************************************************************************************************************
@ -217,13 +240,21 @@ pageChecksumBufferTest(
const unsigned char *pageBuffer, unsigned int pageBufferSize, unsigned int blockNoBegin, unsigned int pageSize,
uint32_t ignoreWalId, uint32_t ignoreWalOffset)
{
ASSERT_DEBUG(pageBuffer != NULL);
ASSERT_DEBUG(pageBufferSize > 0);
ASSERT_DEBUG(pageSize == PG_PAGE_SIZE);
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(UCHARP, pageBuffer);
FUNCTION_DEBUG_PARAM(UINT, pageBufferSize);
FUNCTION_DEBUG_PARAM(UINT, blockNoBegin);
FUNCTION_DEBUG_PARAM(UINT, pageSize);
FUNCTION_DEBUG_PARAM(UINT32, ignoreWalId);
FUNCTION_DEBUG_PARAM(UINT32, ignoreWalOffset);
// If the buffer does not represent an even number of pages then error
if (pageBufferSize % pageSize != 0)
THROW_FMT(AssertError, "buffer size %u, page size %u are not divisible", pageBufferSize, pageSize);
FUNCTION_TEST_ASSERT(pageBuffer != NULL);
FUNCTION_DEBUG_ASSERT(pageBufferSize > 0);
FUNCTION_DEBUG_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_DEBUG_ASSERT(pageBufferSize % pageSize == 0);
FUNCTION_DEBUG_END();
bool result = true;
// Loop through all pages in the buffer
for (unsigned int pageIdx = 0; pageIdx < pageBufferSize / pageSize; pageIdx++)
@ -232,9 +263,11 @@ pageChecksumBufferTest(
// Return false if the checksums do not match
if (!pageChecksumTest(page, blockNoBegin + pageIdx, pageSize, ignoreWalId, ignoreWalOffset))
return false;
{
result = false;
break;
}
}
// All checksums match
return true;
FUNCTION_DEBUG_RESULT(BOOL, result);
}