1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-06-25 00:16:54 +02:00

Add ASSERT_DEBUG() macro for debugging.

Replace all current assert() calls except in tests that can't use the debug code.
This commit is contained in:
David Steele
2018-03-12 14:31:22 -04:00
parent dd31ae832d
commit cced6ec03a
17 changed files with 133 additions and 25 deletions

View File

@ -83,6 +83,10 @@
<p>Improve code documentation in <code>config</code> module.</p>
</release-item>
<release-item>
<p>Add <code>ASSERT_DEBUG()</code> macro for debugging and replace all current <code>assert()</code> calls except in tests that can't use the debug code.</p>
</release-item>
<release-item>
<release-item-contributor-list>
<release-item-contributor id="shang.cynthia"/>

View File

@ -1,22 +1,28 @@
/***********************************************************************************************************************************
Common Command Routines
***********************************************************************************************************************************/
#include <assert.h>
#include <string.h>
#include "common/debug.h"
#include "common/log.h"
#include "common/memContext.h"
#include "config/config.h"
#include "version.h"
/***********************************************************************************************************************************
Debug Asserts
***********************************************************************************************************************************/
// The command must be set
#define ASSERT_DEBUG_COMMAND_SET() \
ASSERT_DEBUG(cfgCommand() != cfgCmdNone)
/***********************************************************************************************************************************
Begin the command
***********************************************************************************************************************************/
void
cmdBegin()
{
// A command must be set
assert(cfgCommand() != cfgCmdNone);
ASSERT_DEBUG_COMMAND_SET();
// This is fairly expensive log message to generate so skip it if it won't be output
if (logWill(cfgLogLevelDefault()))
@ -112,8 +118,7 @@ End the command
void
cmdEnd(int code)
{
// A command must be set
assert(cfgCommand() != cfgCmdNone);
ASSERT_DEBUG_COMMAND_SET();
// Skip this log message if it won't be output. It's not too expensive but since we skipped cmdBegin(), may as well.
if (logWill(cfgLogLevelDefault()))

29
src/common/debug.h Normal file
View File

@ -0,0 +1,29 @@
/***********************************************************************************************************************************
Debug Routines
***********************************************************************************************************************************/
#ifndef COMMON_DEBUG_H
#define COMMON_DEBUG_H
#include "common/log.h"
/***********************************************************************************************************************************
NDEBUG indicates to C library routines that debugging is off -- set a more readable flag to use when debugging is on
***********************************************************************************************************************************/
#ifndef NDEBUG
#define DEBUG
#endif
/***********************************************************************************************************************************
Assert Macros
***********************************************************************************************************************************/
#ifdef DEBUG
#define ASSERT_DEBUG(condition) \
{ \
if (!(condition)) \
THROW(AssertError, "assertion '%s' failed", #condition); \
}
#else
#define ASSERT_DEBUG(condition)
#endif
#endif

View File

@ -1,7 +1,6 @@
/***********************************************************************************************************************************
Log Handler
***********************************************************************************************************************************/
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
@ -10,6 +9,7 @@ Log Handler
#include <time.h>
#include <unistd.h>
#include "common/debug.h"
#include "common/error.h"
#include "common/log.h"
#include "common/time.h"
@ -36,10 +36,8 @@ bool logTimestamp = false;
/***********************************************************************************************************************************
Debug Asserts
***********************************************************************************************************************************/
#define ASSERT_MESSAGE_LOG_LEVEL_VALID(logLevel) \
{ \
assert(logLevel > logLevelOff); \
}
#define ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel) \
ASSERT_DEBUG(logLevel > logLevelOff)
/***********************************************************************************************************************************
Log buffer
@ -143,28 +141,28 @@ This is useful for log messages that are expensive to generate and should be ski
static bool
logWillFile(LogLevel logLevel)
{
ASSERT_MESSAGE_LOG_LEVEL_VALID(logLevel)
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel)
return logLevel <= logLevelFile && logHandleFile != -1;
}
static bool
logWillStdErr(LogLevel logLevel)
{
ASSERT_MESSAGE_LOG_LEVEL_VALID(logLevel)
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel)
return logLevel <= logLevelStdErr;
}
static bool
logWillStdOut(LogLevel logLevel)
{
ASSERT_MESSAGE_LOG_LEVEL_VALID(logLevel)
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel)
return logLevel <= logLevelStdOut;
}
bool
logWill(LogLevel logLevel)
{
ASSERT_MESSAGE_LOG_LEVEL_VALID(logLevel)
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel)
return logWillStdOut(logLevel) || logWillStdErr(logLevel) || logWillFile(logLevel);
}
@ -174,7 +172,7 @@ General log function
void
logInternal(LogLevel logLevel, const char *fileName, const char *functionName, int code, const char *format, ...)
{
ASSERT_MESSAGE_LOG_LEVEL_VALID(logLevel)
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel)
size_t bufferPos = 0; // Current position in the buffer
@ -197,7 +195,7 @@ logInternal(LogLevel logLevel, const char *fileName, const char *functionName, i
size_t messageStdErrPos = bufferPos - strlen(logLevelStr(logLevel)) - 2;
// Check that error code matches log level
assert(
ASSERT_DEBUG(
code == 0 || (logLevel == logLevelError && code != errorTypeCode(&AssertError)) ||
(logLevel == logLevelAssert && code == errorTypeCode(&AssertError)));

View File

@ -59,6 +59,8 @@ Only call logInternal() if the message will be logged to one of the available ou
logInternal(logLevel, __FILE__, __func__, code, __VA_ARGS__); \
}
#define LOG_ASSERT(...) \
LOG_ANY(logLevelAssert, errorTypeCode(&AssertError), __VA_ARGS__)
#define LOG_ERROR(code, ...) \
LOG_ANY(logLevelError, code, __VA_ARGS__)
#define LOG_INFO(...) \

View File

@ -1,9 +1,9 @@
/***********************************************************************************************************************************
Command and Option Configuration
***********************************************************************************************************************************/
#include <assert.h>
#include <string.h>
#include "common/debug.h"
#include "common/error.h"
#include "common/memContext.h"
#include "config/config.h"
@ -60,6 +60,13 @@ Include the automatically generated configuration data
***********************************************************************************************************************************/
#include "config.auto.c"
/***********************************************************************************************************************************
Debug Asserts
***********************************************************************************************************************************/
// The command must be set
#define ASSERT_DEBUG_COMMAND_SET() \
ASSERT_DEBUG(cfgCommand() != cfgCmdNone)
/***********************************************************************************************************************************
Store the config memory context
***********************************************************************************************************************************/
@ -273,7 +280,7 @@ Does this command log to a file?
bool
cfgLogFile()
{
assert(cfgCommand() != cfgCmdNone);
ASSERT_DEBUG_COMMAND_SET();
return configCommandData[cfgCommand()].logFile;
}
@ -283,7 +290,7 @@ Get default log level -- used for log messages that are common to all commands
LogLevel
cfgLogLevelDefault()
{
assert(cfgCommand() != cfgCmdNone);
ASSERT_DEBUG_COMMAND_SET();
return (LogLevel)configCommandData[cfgCommand()].logLevelDefault;
}

View File

@ -1,11 +1,11 @@
/***********************************************************************************************************************************
Command and Option Parse
***********************************************************************************************************************************/
#include <assert.h>
#include <getopt.h>
#include <string.h>
#include <strings.h>
#include "common/debug.h"
#include "common/error.h"
#include "common/ini.h"
#include "common/log.h"
@ -165,7 +165,7 @@ configParse(unsigned int argListSize, const char *argList[])
reset = option & PARSE_RESET_FLAG;
// Make sure the option id is valid
assert(optionId < CFG_OPTION_TOTAL);
ASSERT_DEBUG(optionId < CFG_OPTION_TOTAL);
// If the the option has not been found yet then set it
if (!parseOptionList[optionId].found)

View File

@ -155,6 +155,27 @@ my $oTestDef =
'common/log' => TESTDEF_COVERAGE_FULL,
},
},
{
&TESTDEF_NAME => 'debug-on',
&TESTDEF_TOTAL => 1,
&TESTDEF_C => true,
&TESTDEF_COVERAGE =>
{
'common/debug' => TESTDEF_COVERAGE_NOCODE,
},
},
{
&TESTDEF_NAME => 'debug-off',
&TESTDEF_TOTAL => 1,
&TESTDEF_C => true,
&TESTDEF_CDEF => '-DNDEBUG -DNO_LOG',
&TESTDEF_COVERAGE =>
{
'common/debug' => TESTDEF_COVERAGE_NOCODE,
},
},
{
&TESTDEF_NAME => 'exit',
&TESTDEF_TOTAL => 1,

View File

@ -1,7 +1,6 @@
/***********************************************************************************************************************************
C Test Harness
***********************************************************************************************************************************/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@ -10,6 +10,8 @@ Log Test Harness
#include "common/type.h"
#include "storage/helper.h"
#ifndef NO_LOG
/***********************************************************************************************************************************
Name of file where logs are stored for testing
***********************************************************************************************************************************/
@ -81,3 +83,5 @@ testLogFinal()
if (!strEqZ(actual, ""))
THROW(AssertError, "\n\nexpected error log to be empty but actual error log was:\n\n%s\n\n", strPtr(actual));
}
#endif

View File

@ -7,9 +7,11 @@ Log Test Harness
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
#ifndef NO_LOG
void testLogInit();
void testLogResult(const char *expected);
void testLogErrResult(const char *expected);
void testLogFinal();
#endif
#endif

View File

@ -0,0 +1,17 @@
/***********************************************************************************************************************************
Test Debug Macros and Routines when Disabled
***********************************************************************************************************************************/
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
void
testRun()
{
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("ASSERT_DEBUG()"))
{
TEST_RESULT_VOID(ASSERT_DEBUG(true), "assert true ignored");
TEST_RESULT_VOID(ASSERT_DEBUG(false || false), "assert false ignored");
}
}

View File

@ -0,0 +1,17 @@
/***********************************************************************************************************************************
Test Debug Macros and Routines
***********************************************************************************************************************************/
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
void
testRun()
{
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("ASSERT_DEBUG()"))
{
TEST_RESULT_VOID(ASSERT_DEBUG(true), "assert true");
TEST_ERROR(ASSERT_DEBUG(false || false), AssertError, "assertion 'false || false' failed");
}
}

View File

@ -1,6 +1,7 @@
/***********************************************************************************************************************************
Test Error Handling
***********************************************************************************************************************************/
#include <assert.h>
/***********************************************************************************************************************************
testTryRecurse - test to blow up try stack

View File

@ -1,6 +1,8 @@
/***********************************************************************************************************************************
Test Types
***********************************************************************************************************************************/
#include <assert.h>
void
testRun()
{

View File

@ -1,6 +1,7 @@
/***********************************************************************************************************************************
Test Page Checksums
***********************************************************************************************************************************/
#include "common/debug.h"
/***********************************************************************************************************************************
Page data for testing -- use 8192 for page size since this is the most common value
@ -26,7 +27,7 @@ testRun()
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("pageChecksum()"))
{
// Checksum for 0x00 fill, page 0x00
// Checksum for 0x00 fill, page 0x00
memset(testPage(0), 0, TEST_PAGE_SIZE);
TEST_RESULT_U16_HEX(pageChecksum(testPage(0), 0, TEST_PAGE_SIZE), 0xC6AA, "check for 0x00 filled page, block 0");
@ -102,7 +103,7 @@ testRun()
// Break the checksum for a page and make sure it is found
unsigned int pageInvalid = 7;
assert(pageInvalid < TEST_PAGE_TOTAL);
ASSERT_DEBUG(pageInvalid < TEST_PAGE_TOTAL);
((PageHeader)testPage(pageInvalid))->pd_checksum = 0xEEEE;
TEST_RESULT_BOOL(

View File

@ -3,7 +3,6 @@ C Test Wrapper
This wrapper runs the the C unit tests.
***********************************************************************************************************************************/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>