https://git.reactos.org/?p=reactos.git;a=commitdiff;h=85377ee3dbe2373d40dc4…
commit 85377ee3dbe2373d40dc401b1d6349c391cd9d94
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Sep 11 04:37:27 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Sep 11 04:37:27 2023 +0900
[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 <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)
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