From 85377ee3dbe2373d40dc401b1d6349c391cd9d94 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 11 Sep 2023 04:37:27 +0900 Subject: [PATCH] [SDK][CRT][MSVCRT] Implement _CrtSetReportMode and _CrtSetReportFile (#5662) - Implement reporting to file. CORE-11835, CORE-15517, ROSTESTS-386 --- dll/win32/msvcrt/msvcrt.spec | 8 ++--- sdk/include/crt/crtdbg.h | 9 +++--- sdk/lib/crt/misc/dbgrpt.cpp | 60 ++++++++++++++++++++++++++++++++---- sdk/lib/crt/misc/misc.cmake | 1 + 4 files changed, 64 insertions(+), 14 deletions(-) diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec index e80a290e2fd..9f2c5a55eb6 100644 --- a/dll/win32/msvcrt/msvcrt.spec +++ b/dll/win32/msvcrt/msvcrt.spec @@ -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() diff --git a/sdk/include/crt/crtdbg.h b/sdk/include/crt/crtdbg.h index 3a20d5316fb..f9545698e89 100644 --- a/sdk/include/crt/crtdbg.h +++ b/sdk/include/crt/crtdbg.h @@ -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) diff --git a/sdk/lib/crt/misc/dbgrpt.cpp b/sdk/lib/crt/misc/dbgrpt.cpp index dbb1ebbc966..131a918a2e2 100644 --- a/sdk/lib/crt/misc/dbgrpt.cpp +++ b/sdk/lib/crt/misc/dbgrpt.cpp @@ -16,6 +16,8 @@ #include #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 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 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 achar_traits; typedef dbgrpt_char_traits 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 = ""; const wchar_traits::char_t* wchar_traits::szUnknownFile = L""; -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 +static inline BOOL _CrtDbgReportToFile(HANDLE hFile, const char_t* szMsg) +{ + typedef dbgrpt_char_traits 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 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(_CrtReportFiles[reportType], szCompleteMessage); } if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_DEBUG) diff --git a/sdk/lib/crt/misc/misc.cmake b/sdk/lib/crt/misc/misc.cmake index d5cea9dd5cc..7b8bb4c9efd 100644 --- a/sdk/lib/crt/misc/misc.cmake +++ b/sdk/lib/crt/misc/misc.cmake @@ -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