[SDK][CRT][MSVCRT] Implement _CrtSetReportMode and _CrtSetReportFile (#5662)

- Implement reporting to file.
CORE-11835, CORE-15517, ROSTESTS-386
This commit is contained in:
Katayama Hirofumi MZ 2023-09-11 04:37:27 +09:00 committed by GitHub
parent 993a45024e
commit 85377ee3db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 14 deletions

View file

@ -199,9 +199,9 @@
@ cdecl -arch=i386 _CItanh() @ cdecl -arch=i386 _CItanh()
@ stub -version=0x600+ _CrtCheckMemory @ stub -version=0x600+ _CrtCheckMemory
@ stub -version=0x600+ _CrtDbgBreak @ stub -version=0x600+ _CrtDbgBreak
@ stub -version=0x600+ _CrtDbgReport @ cdecl -version=0x600+ _CrtDbgReport(long str long str str)
@ stub -version=0x600+ _CrtDbgReportV @ stub -version=0x600+ _CrtDbgReportV
@ stub -version=0x600+ _CrtDbgReportW @ cdecl -version=0x600+ _CrtDbgReportW(long wstr long wstr wstr)
@ stub -version=0x600+ _CrtDbgReportWV @ stub -version=0x600+ _CrtDbgReportWV
@ stub -version=0x600+ _CrtDoForAllClientObjects @ stub -version=0x600+ _CrtDoForAllClientObjects
@ stub -version=0x600+ _CrtDumpMemoryLeaks @ stub -version=0x600+ _CrtDumpMemoryLeaks
@ -218,10 +218,10 @@
@ stub -version=0x600+ _CrtSetDbgBlockType @ stub -version=0x600+ _CrtSetDbgBlockType
@ stub -version=0x600+ _CrtSetDbgFlag @ stub -version=0x600+ _CrtSetDbgFlag
@ stub -version=0x600+ _CrtSetDumpClient @ stub -version=0x600+ _CrtSetDumpClient
@ stub -version=0x600+ _CrtSetReportFile @ cdecl -version=0x600+ _CrtSetReportFile(long ptr)
@ stub -version=0x600+ _CrtSetReportHook @ stub -version=0x600+ _CrtSetReportHook
@ stub -version=0x600+ _CrtSetReportHook2 @ stub -version=0x600+ _CrtSetReportHook2
@ stub -version=0x600+ _CrtSetReportMode @ cdecl -version=0x600+ _CrtSetReportMode(long long)
@ stdcall _CxxThrowException(long long) @ stdcall _CxxThrowException(long long)
@ cdecl -arch=i386 -norelay _EH_prolog() @ cdecl -arch=i386 -norelay _EH_prolog()
@ cdecl _Getdays() @ cdecl _Getdays()

View file

@ -91,8 +91,6 @@ extern "C" {
#endif #endif
// Assertion and error reporting // Assertion and error reporting
#ifndef _DEBUG #ifndef _DEBUG
@ -124,6 +122,8 @@ extern "C" {
#define _RPTFW0(rptno,msg) #define _RPTFW0(rptno,msg)
#define _RPTFWN(rptno,msg,...) #define _RPTFWN(rptno,msg,...)
#define _CrtSetReportMode(t,f) ((int)0)
#define _CrtSetReportFile(t,f) ((_HFILE)0)
#else // _DEBUG #else // _DEBUG
@ -161,6 +161,9 @@ extern "C" {
#define _RPTFW0(rptno,msg) _RPT_BASEW(rptno, _CRT_WIDE(__FILE__), __LINE__, NULL, L"%s", msg) #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__) #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 #endif
@ -230,8 +233,6 @@ extern "C" {
#define _CrtGetReportHook() ((_CRT_REPORT_HOOK)0) #define _CrtGetReportHook() ((_CRT_REPORT_HOOK)0)
#define _CrtSetReportHook2(t,f) ((int)0) #define _CrtSetReportHook2(t,f) ((int)0)
#define _CrtSetReportHookW2(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 _CrtSetBreakAlloc(a) ((long)0)
#define _CrtSetAllocHook(f) ((_CRT_ALLOC_HOOK)0) #define _CrtSetAllocHook(f) ((_CRT_ALLOC_HOOK)0)

View file

@ -16,6 +16,8 @@
#include <windows.h> #include <windows.h>
#undef OutputDebugString #undef OutputDebugString
#undef _CrtSetReportMode
#undef _CrtSetReportFile
#define DBGRPT_MAX_BUFFER_SIZE 4096 #define DBGRPT_MAX_BUFFER_SIZE 4096
#define DBGRPT_ASSERT_PREFIX_MESSAGE "Assertion failed: " #define DBGRPT_ASSERT_PREFIX_MESSAGE "Assertion failed: "
@ -38,6 +40,13 @@ static const wchar_t* _CrtModeMessages[_CRT_ERRCNT] =
L"Error", L"Error",
L"Assertion Failed" 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 // 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); 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 const char_t* szUnknownFile;
static void OutputDebugString(const char_t* message); static void OutputDebugString(const char_t* message);
static size_t StringLength(const char_t* str) { return strlen(str); }
}; };
template<> template<>
@ -69,13 +79,13 @@ struct dbgrpt_char_traits<wchar_t>
static const char_t* szUnknownFile; static const char_t* szUnknownFile;
static void OutputDebugString(const char_t* message); static void OutputDebugString(const char_t* message);
static size_t StringLength(const char_t* str) { return wcslen(str); };
}; };
// Shortcut // Shortcut
typedef dbgrpt_char_traits<char> achar_traits; typedef dbgrpt_char_traits<char> achar_traits;
typedef dbgrpt_char_traits<wchar_t> wchar_traits; typedef dbgrpt_char_traits<wchar_t> wchar_traits;
const wchar_t* achar_traits::szAssertionMessage = const wchar_t* achar_traits::szAssertionMessage =
L"Debug %s!\n" L"Debug %s!\n"
L"%s%hs" /* module */ 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 achar_traits::char_t* achar_traits::szUnknownFile = "<unknown file>";
const wchar_traits::char_t* wchar_traits::szUnknownFile = L"<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); OutputDebugStringA(message);
} }
void wchar_traits::OutputDebugString(const wchar_t* message) inline void wchar_traits::OutputDebugString(const wchar_t* message)
{ {
OutputDebugStringW(message); OutputDebugStringW(message);
} }
static static
HMODULE _CrtGetUser32() HMODULE _CrtGetUser32()
{ {
@ -221,6 +230,46 @@ void _CrtLeaveDbgReport(int reportType)
_InterlockedDecrement(&_CrtInAssert); _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> template <typename char_t>
static int _CrtHandleDbgReport(int reportType, const char_t* szCompleteMessage, const char_t* szFormatted, 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) if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_FILE)
{ {
OutputDebugStringA("ERROR: Please implement _CrtSetReportFile first\n"); _CrtDbgReportToFile<char_t>(_CrtReportFiles[reportType], szCompleteMessage);
_CrtDbgBreak();
} }
if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_DEBUG) if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_DEBUG)

View file

@ -15,6 +15,7 @@ list(APPEND CRT_MISC_SOURCE
misc/amsg.c misc/amsg.c
misc/assert.c misc/assert.c
misc/crt_init.c misc/crt_init.c
misc/dbgrpt.cpp
misc/environ.c misc/environ.c
misc/getargs.c misc/getargs.c
misc/i10output.c misc/i10output.c