Monday, March 29, 2010

Serial: CRT debug report




Report type: _CRT_WARN, _CRT_ERROR, _CRT_ASSERT

Required Header: crtdbg.h

_CRT_WARN: Warnings, messages, and information that does not need immediate attention.
_CRT_ERROR: Errors, unrecoverable problems, and issues that require immediate attention.
_CRT_ASSERT: Assertion failures (asserted expressions that evaluate to FALSE).


Example:

/*


* REPORT.C:

* In this program, calls are made to the _CrtSetReportMode,
* _CrtSetReportFile, and _CrtSetReportHook functions.
* The _ASSERT macros are called to evaluate their expression.
* When the condition fails, these macros print a diagnostic message
* and call _CrtDbgReport to generate a debug report and the
* client-defined reporting function is called as well.
* The _RPTn and _RPTFn group of macros are also exercised in
* this program, as an alternative to the printf function.
* When these macros are called, the client-defined reporting function
* takes care of all the reporting - _CrtDbgReport won't be called.

*/

#include
#include
#include

#include

/*
* Define our own reporting function.
* We'll hook it into the debug reporting
* process later using _CrtSetReportHook.
*
* Define a global int to keep track of
* how many assertion failures occur.
*/

int gl_num_asserts=0;

int OurReportingFunction( int reportType, char *userMessage, int *retVal )
{
/*
* Tell the user our reporting function is being called.
* In other words - verify that the hook routine worked.
*/

fprintf("Inside the client-defined reporting function.\n", STDOUT);
fflush(STDOUT);

/*
* When the report type is for an ASSERT,
* we'll report some information, but we also
* want _CrtDbgReport to get called -
* so we'll return TRUE.
*
* When the report type is a WARNing or ERROR,
* we'll take care of all of the reporting. We don't
* want _CrtDbgReport to get called -
* so we'll return FALSE.
*/

if (reportType == _CRT_ASSERT)
{
    gl_num_asserts++;
    fprintf("This is the number of Assertion failures that have occurred: %d \n", gl_num_asserts, STDOUT);
    fflush(STDOUT);
    fprintf("Returning TRUE from the client-defined reporting function.\n", STDOUT);
    fflush(STDOUT);
    return(TRUE);
}
else
{
    fprintf("This is the debug user message: %s \n", userMessage, STDOUT);
    fflush(STDOUT);
    fprintf("Returning FALSE from the client-defined reporting function.\n", STDOUT);
    fflush(STDOUT);
    return(FALSE);
}

/*
* By setting retVal to zero, we are instructing _CrtDbgReport
* to continue with normal execution after generating the report.
* If we wanted _CrtDbgReport to start the debugger, we would set
* retVal to one.
*/

retVal = 0;
}



int main()
{
char *p1, *p2;

/*
* Hook in our client-defined reporting function.
* Every time a _CrtDbgReport is called to generate
* a debug report, our function will get called first.
*/

_CrtSetReportHook( OurReportingFunction );

/*
* Define the report destination(s) for each type of report
* we are going to generate. In this case, we are going to
* generate a report for every report type: _CRT_WARN,
* _CRT_ERROR, and _CRT_ASSERT.
* The destination(s) is defined by specifying the report mode(s)
* and report file for each report type.
* This program sends all report types to STDOUT.
*/

_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);

_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);

_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);

_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);

_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);

_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);

/*
* Allocate and assign the pointer variables
*/

p1 = malloc(10);
strcpy(p1, "I am p1");
p2 = malloc(10);
strcpy(p2, "I am p2");

/*
* Use the report macros as a debugging
* warning mechanism, similar to printf.
*
* Use the assert macros to check if the
* p1 and p2 variables are equivalent.
*
* If the expression fails, _ASSERTE will
* include a string representation of the
* failed expression in the report.
*
* _ASSERT does not include the
* expression in the generated report.
*/

_RPT0(_CRT_WARN, "\n\n Use the assert macros to evaluate the expression p1 == p2.\n");

_RPTF2(_CRT_WARN, "\n Will _ASSERT find '%s' == '%s' ?\n", p1, p2);

_ASSERT(p1 == p2);

_RPTF2(_CRT_WARN, "\n\n Will _ASSERTE find '%s' == '%s' ?\n", p1, p2);

_ASSERTE(p1 == p2);

_RPT2(_CRT_ERROR, "\n \n '%s' != '%s'\n", p1, p2);

free(p2);
free(p1);

return 0;
}


Output:

Inside the client-defined reporting function.
This is the debug user message: Use the assert macros to evaluate the expression p1 == p2
Returning FALSE from the client-defined reporting function.
Inside the client-defined reporting function.
This is the debug user message: dbgmacro.c(54) : Will _ASSERT find 'I am p1' == 'I am p2' ?
Returning FALSE from the client-defined reporting function.
Inside the client-defined reporting function.
This is the number of Assertion failures that have occurred: 1
Returning TRUE from the client-defined reporting function.
dbgmacro.c(55) : Assertion failed
Inside the client-defined reporting function.
This is the debug user message: dbgmacro.c(57) : Will _ASSERTE find 'I am p1' == 'I am p2' ?
Returning FALSE from the client-defined reporting function.
Inside the client-defined reporting function.
This is the number of Assertion failures that have occurred: 2
Returning TRUE from the client-defined reporting function.
dbgmacro.c(58) : Assertion failed: p1 == p2
Inside the client-defined reporting function.
This is the debug user message: 'I am p1' != 'I am p2'
Returning FALSE from the client-defined reporting function.

Ref: http://msdn.microsoft.com/en-us/library/aa246776%28VS.60%29.aspx

Tags: Serial programming, _CRT_WARN, _CRT_ERROR, _CRT_ASSERT, _RPT0, _RPTF2, _ASSERTE, _RPT2



No comments:

Post a Comment

Labels