mirror of
https://github.com/reactos/reactos.git
synced 2025-05-04 18:31:40 +00:00
[SDK][CRT][MSVCRT] Implement _CrtSetReportMode and _CrtSetReportFile (#5662)
- Implement reporting to file. CORE-11835, CORE-15517, ROSTESTS-386
This commit is contained in:
parent
993a45024e
commit
85377ee3db
4 changed files with 64 additions and 14 deletions
|
@ -199,9 +199,9 @@
|
|||
@ cdecl -arch=i386 _CItanh()
|
||||
@ stub -version=0x600+ _CrtCheckMemory
|
||||
@ stub -version=0x600+ _CrtDbgBreak
|
||||
@ stub -version=0x600+ _CrtDbgReport
|
||||
@ cdecl -version=0x600+ _CrtDbgReport(long str long str str)
|
||||
@ stub -version=0x600+ _CrtDbgReportV
|
||||
@ stub -version=0x600+ _CrtDbgReportW
|
||||
@ cdecl -version=0x600+ _CrtDbgReportW(long wstr long wstr wstr)
|
||||
@ stub -version=0x600+ _CrtDbgReportWV
|
||||
@ stub -version=0x600+ _CrtDoForAllClientObjects
|
||||
@ stub -version=0x600+ _CrtDumpMemoryLeaks
|
||||
|
@ -218,10 +218,10 @@
|
|||
@ stub -version=0x600+ _CrtSetDbgBlockType
|
||||
@ stub -version=0x600+ _CrtSetDbgFlag
|
||||
@ stub -version=0x600+ _CrtSetDumpClient
|
||||
@ stub -version=0x600+ _CrtSetReportFile
|
||||
@ cdecl -version=0x600+ _CrtSetReportFile(long ptr)
|
||||
@ stub -version=0x600+ _CrtSetReportHook
|
||||
@ stub -version=0x600+ _CrtSetReportHook2
|
||||
@ stub -version=0x600+ _CrtSetReportMode
|
||||
@ cdecl -version=0x600+ _CrtSetReportMode(long long)
|
||||
@ stdcall _CxxThrowException(long long)
|
||||
@ cdecl -arch=i386 -norelay _EH_prolog()
|
||||
@ cdecl _Getdays()
|
||||
|
|
|
@ -91,8 +91,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// Assertion and error reporting
|
||||
|
||||
#ifndef _DEBUG
|
||||
|
@ -124,6 +122,8 @@ extern "C" {
|
|||
#define _RPTFW0(rptno,msg)
|
||||
#define _RPTFWN(rptno,msg,...)
|
||||
|
||||
#define _CrtSetReportMode(t,f) ((int)0)
|
||||
#define _CrtSetReportFile(t,f) ((_HFILE)0)
|
||||
|
||||
#else // _DEBUG
|
||||
|
||||
|
@ -161,6 +161,9 @@ extern "C" {
|
|||
#define _RPTFW0(rptno,msg) _RPT_BASEW(rptno, _CRT_WIDE(__FILE__), __LINE__, NULL, L"%s", msg)
|
||||
#define _RPTFWN(rptno,msg,...) _RPT_BASEW(rptno, _CRT_WIDE(__FILE__), __LINE__, NULL, msg, __VA_ARGS__)
|
||||
|
||||
int __cdecl _CrtSetReportMode(int reportType, int reportMode);
|
||||
_HFILE __cdecl _CrtSetReportFile(int reportType, _HFILE reportFile);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -230,8 +233,6 @@ extern "C" {
|
|||
#define _CrtGetReportHook() ((_CRT_REPORT_HOOK)0)
|
||||
#define _CrtSetReportHook2(t,f) ((int)0)
|
||||
#define _CrtSetReportHookW2(t,f) ((int)0)
|
||||
#define _CrtSetReportMode(t,f) ((int)0)
|
||||
#define _CrtSetReportFile(t,f) ((_HFILE)0)
|
||||
|
||||
#define _CrtSetBreakAlloc(a) ((long)0)
|
||||
#define _CrtSetAllocHook(f) ((_CRT_ALLOC_HOOK)0)
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include <windows.h>
|
||||
|
||||
#undef OutputDebugString
|
||||
#undef _CrtSetReportMode
|
||||
#undef _CrtSetReportFile
|
||||
|
||||
#define DBGRPT_MAX_BUFFER_SIZE 4096
|
||||
#define DBGRPT_ASSERT_PREFIX_MESSAGE "Assertion failed: "
|
||||
|
@ -38,6 +40,13 @@ static const wchar_t* _CrtModeMessages[_CRT_ERRCNT] =
|
|||
L"Error",
|
||||
L"Assertion Failed"
|
||||
};
|
||||
// Report files
|
||||
static _HFILE _CrtReportFiles[_CRT_ERRCNT] =
|
||||
{
|
||||
_CRTDBG_INVALID_HFILE,
|
||||
_CRTDBG_INVALID_HFILE,
|
||||
_CRTDBG_INVALID_HFILE
|
||||
};
|
||||
|
||||
// Manually delay-load as to not have a dependency on user32
|
||||
typedef int (WINAPI *tMessageBoxW)(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType);
|
||||
|
@ -57,6 +66,7 @@ struct dbgrpt_char_traits<char>
|
|||
static const char_t* szUnknownFile;
|
||||
|
||||
static void OutputDebugString(const char_t* message);
|
||||
static size_t StringLength(const char_t* str) { return strlen(str); }
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -69,13 +79,13 @@ struct dbgrpt_char_traits<wchar_t>
|
|||
static const char_t* szUnknownFile;
|
||||
|
||||
static void OutputDebugString(const char_t* message);
|
||||
static size_t StringLength(const char_t* str) { return wcslen(str); };
|
||||
};
|
||||
|
||||
// Shortcut
|
||||
typedef dbgrpt_char_traits<char> achar_traits;
|
||||
typedef dbgrpt_char_traits<wchar_t> wchar_traits;
|
||||
|
||||
|
||||
const wchar_t* achar_traits::szAssertionMessage =
|
||||
L"Debug %s!\n"
|
||||
L"%s%hs" /* module */
|
||||
|
@ -97,17 +107,16 @@ const wchar_traits::char_t* wchar_traits::szEmptyString = L"";
|
|||
const achar_traits::char_t* achar_traits::szUnknownFile = "<unknown file>";
|
||||
const wchar_traits::char_t* wchar_traits::szUnknownFile = L"<unknown file>";
|
||||
|
||||
void achar_traits::OutputDebugString(const char* message)
|
||||
inline void achar_traits::OutputDebugString(const char* message)
|
||||
{
|
||||
OutputDebugStringA(message);
|
||||
}
|
||||
|
||||
void wchar_traits::OutputDebugString(const wchar_t* message)
|
||||
inline void wchar_traits::OutputDebugString(const wchar_t* message)
|
||||
{
|
||||
OutputDebugStringW(message);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
HMODULE _CrtGetUser32()
|
||||
{
|
||||
|
@ -221,6 +230,46 @@ void _CrtLeaveDbgReport(int reportType)
|
|||
_InterlockedDecrement(&_CrtInAssert);
|
||||
}
|
||||
|
||||
EXTERN_C
|
||||
int __cdecl _CrtSetReportMode(int reportType, int reportMode)
|
||||
{
|
||||
if (reportType >= _CRT_ERRCNT || reportType < 0)
|
||||
return 0;
|
||||
|
||||
int oldReportMode = _CrtModeOutputFormat[reportType];
|
||||
if (reportMode != _CRTDBG_REPORT_MODE)
|
||||
_CrtModeOutputFormat[reportType] = reportMode;
|
||||
return oldReportMode;
|
||||
}
|
||||
|
||||
EXTERN_C
|
||||
_HFILE __cdecl _CrtSetReportFile(int reportType, _HFILE reportFile)
|
||||
{
|
||||
if (reportType >= _CRT_ERRCNT || reportType < 0)
|
||||
return NULL;
|
||||
|
||||
_HFILE oldReportFile = _CrtReportFiles[reportType];
|
||||
if (reportFile != _CRTDBG_REPORT_FILE)
|
||||
_CrtReportFiles[reportType] = reportFile;
|
||||
return oldReportFile;
|
||||
}
|
||||
|
||||
template <typename char_t>
|
||||
static inline BOOL _CrtDbgReportToFile(HANDLE hFile, const char_t* szMsg)
|
||||
{
|
||||
typedef dbgrpt_char_traits<char_t> traits;
|
||||
|
||||
if (hFile == _CRTDBG_INVALID_HFILE || hFile == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (hFile == _CRTDBG_FILE_STDOUT)
|
||||
hFile = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
else if (hFile == _CRTDBG_FILE_STDERR)
|
||||
hFile = ::GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
DWORD cbMsg = (DWORD)(traits::StringLength(szMsg) * sizeof(char_t));
|
||||
return ::WriteFile(hFile, szMsg, cbMsg, &cbMsg, NULL);
|
||||
}
|
||||
|
||||
template <typename char_t>
|
||||
static int _CrtHandleDbgReport(int reportType, const char_t* szCompleteMessage, const char_t* szFormatted,
|
||||
|
@ -230,8 +279,7 @@ static int _CrtHandleDbgReport(int reportType, const char_t* szCompleteMessage,
|
|||
|
||||
if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_FILE)
|
||||
{
|
||||
OutputDebugStringA("ERROR: Please implement _CrtSetReportFile first\n");
|
||||
_CrtDbgBreak();
|
||||
_CrtDbgReportToFile<char_t>(_CrtReportFiles[reportType], szCompleteMessage);
|
||||
}
|
||||
|
||||
if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_DEBUG)
|
||||
|
|
|
@ -15,6 +15,7 @@ list(APPEND CRT_MISC_SOURCE
|
|||
misc/amsg.c
|
||||
misc/assert.c
|
||||
misc/crt_init.c
|
||||
misc/dbgrpt.cpp
|
||||
misc/environ.c
|
||||
misc/getargs.c
|
||||
misc/i10output.c
|
||||
|
|
Loading…
Reference in a new issue