Sdílet prostřednictvím


How to: Write a Run-Time Error Reporting Function

This topic applies to:

Edition

Visual Basic

C#

F#

C++

Web Developer

Express

Topic does not apply Topic does not apply Topic does not apply

Native only

Topic does not apply

Pro, Premium, and Ultimate

Topic does not apply Topic does not apply Topic does not apply

Native only

Topic does not apply

A custom reporting function for run-time errors must have the same declaration as _CrtDbgReportW. It should return a value of 1 to the debugger.

The following example shows how to define a custom reporting function.

Example

#include <stdio.h>
int errorhandler = 0;
void configureMyErrorFunc(int i)
{
    errorhandler = i;
}

int MyErrorFunc(int errorType, const wchar_t *filename,
                int linenumber, const wchar_t *moduleName,
                const wchar_t *format, ...)
{
    switch (errorhandler)
    {
    case 0:
    case 1:
        wprintf(L"Error type %d at %s line %d in %s",
                errorType, filename, linenumber, moduleName);
        break;
    case 2:
    case 3:
        fprintf(stderr, "Error type");
        break;
    }

    return 1;
}

The following example shows a more complex custom reporting function. In this example, the switch statement handles various error types, as defined by the reportType parameter of _CrtDbgReportW. Because you are replacing _CrtDbgReportW, you cannot use _CrtSetReportMode. Your function must handle the output. The first variable argument in this function takes a run-time error number. For more information, see _RTC_SetErrorType.

#include <windows.h>
#include <stdarg.h>
#include <rtcapi.h>
#include <malloc.h>
#pragma runtime_checks("", off)
int Catch_RTC_Failure(int errType, const wchar_t *file, int line, 
                   const wchar_t *module, const wchar_t *format, ...)
{
    // Prevent re-entrance.
    static long running = 0;
    while (InterlockedExchange(&running, 1))
        Sleep(0);
    // Now, disable all RTC failures.
    int numErrors = _RTC_NumErrors();
    int *errors=(int*)_alloca(numErrors);
    for (int i = 0; i < numErrors; i++)
        errors[i] = _RTC_SetErrorType((_RTC_ErrorNumber)i, _RTC_ERRTYPE_IGNORE);

   // First, get the rtc error number from the var-arg list.
    va_list vl;
    va_start(vl, format);
    _RTC_ErrorNumber rtc_errnum = va_arg(vl, _RTC_ErrorNumber);
    va_end(vl);

    wchar_t buf[512];
    const char *err = _RTC_GetErrDesc(rtc_errnum);
    swprintf_s(buf, 512, L"%S\nLine #%d\nFile:%s\nModule:%s",
        err,
        line,
        file ? file : L"Unknown",
        module ? module : L"Unknown");
    int res = (MessageBox(NULL, buf, L"RTC Failed...", MB_YESNO) == IDYES) ? 1 : 0;
    // Now, restore the RTC errortypes.
    for(int i = 0; i < numErrors; i++)
        _RTC_SetErrorType((_RTC_ErrorNumber)i, errors[i]);
    running = 0;
    return res;
}
#pragma runtime_checks("", restore)

Use _RTC_SetErrorFuncW to install your custom function in place of _CrtDbgReportW. For more information, see _RTC_SetErrorFuncW. The _RTC_SetErrorFuncW return value is the previous reporting function, which you can save and restore if necessary.

#include <rtcapi.h>
int main()
{
    _RTC_error_fnW oldfunction, newfunc;
    oldfunction = _RTC_SetErrorFuncW(&MyErrorFunc);
    // Run some code.
    newfunc = _RTC_SetErrorFuncW(oldfunction);
    // newfunc == &MyErrorFunc;
    // Run some more code.
}

See Also

Concepts

Native Run-Time Checks Customization