SDL_Log: avoid sending text to the debug stream twice

When debugging a GUI application in Visual Studio,
text printed with fprintf(stderr) will also be sent to the debug stream.

When buiding SDL with SDL_LIBC=ON, this patch makes logging skip
OutputDebugString and rely on fprintf(stderr) to send the text to
the debugger.
This commit is contained in:
Anonymous Maarten 2024-08-07 23:49:02 +02:00 committed by Anonymous Maarten
parent bd7d4a3752
commit 125ce71379

View file

@ -510,9 +510,14 @@ void SDL_LogMessageV(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_S
} }
} }
#if defined(SDL_PLATFORM_WIN32) && !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK) #if defined(SDL_PLATFORM_WIN32) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK)
/* Flag tracking the attachment of the console: 0=unattached, 1=attached to a console, 2=attached to a file, -1=error */ enum {
static int consoleAttached = 0; CONSOLE_UNATTACHED = 0,
CONSOLE_ATTACHED_CONSOLE = 1,
CONSOLE_ATTACHED_FILE = 2,
CONSOLE_ATTACHED_MSVC = 3,
CONSOLE_ATTACHED_ERROR = -1,
} consoleAttached = CONSOLE_UNATTACHED;
/* Handle to stderr output of console. */ /* Handle to stderr output of console. */
static HANDLE stderrHandle = NULL; static HANDLE stderrHandle = NULL;
@ -530,58 +535,68 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
LPTSTR tstr; LPTSTR tstr;
SDL_bool isstack; SDL_bool isstack;
#if !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK) #if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK)
BOOL attachResult; BOOL attachResult;
DWORD attachError; DWORD attachError;
DWORD charsWritten;
DWORD consoleMode; DWORD consoleMode;
#if !defined(HAVE_STDIO_H)
DWORD charsWritten;
#endif
/* Maybe attach console and get stderr handle */ /* Maybe attach console and get stderr handle */
if (consoleAttached == 0) { if (consoleAttached == CONSOLE_UNATTACHED) {
attachResult = AttachConsole(ATTACH_PARENT_PROCESS); attachResult = AttachConsole(ATTACH_PARENT_PROCESS);
if (!attachResult) { if (!attachResult) {
attachError = GetLastError(); attachError = GetLastError();
if (attachError == ERROR_INVALID_HANDLE) { if (attachError == ERROR_INVALID_HANDLE) {
/* This is expected when running from Visual Studio */ /* This is expected when running from Visual Studio */
/*OutputDebugString(TEXT("Parent process has no console\r\n"));*/ /*OutputDebugString(TEXT("Parent process has no console\r\n"));*/
consoleAttached = -1; consoleAttached = CONSOLE_ATTACHED_MSVC;
} else if (attachError == ERROR_GEN_FAILURE) { } else if (attachError == ERROR_GEN_FAILURE) {
OutputDebugString(TEXT("Could not attach to console of parent process\r\n")); OutputDebugString(TEXT("Could not attach to console of parent process\r\n"));
consoleAttached = -1; consoleAttached = CONSOLE_ATTACHED_ERROR;
} else if (attachError == ERROR_ACCESS_DENIED) { } else if (attachError == ERROR_ACCESS_DENIED) {
/* Already attached */ /* Already attached */
consoleAttached = 1; consoleAttached = CONSOLE_ATTACHED_CONSOLE;
} else { } else {
OutputDebugString(TEXT("Error attaching console\r\n")); OutputDebugString(TEXT("Error attaching console\r\n"));
consoleAttached = -1; consoleAttached = CONSOLE_ATTACHED_ERROR;
} }
} else { } else {
/* Newly attached */ /* Newly attached */
consoleAttached = 1; consoleAttached = CONSOLE_ATTACHED_CONSOLE;
} }
if (consoleAttached == 1) { if (consoleAttached == CONSOLE_ATTACHED_CONSOLE) {
stderrHandle = GetStdHandle(STD_ERROR_HANDLE); stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
if (GetConsoleMode(stderrHandle, &consoleMode) == 0) { if (GetConsoleMode(stderrHandle, &consoleMode) == 0) {
/* WriteConsole fails if the output is redirected to a file. Must use WriteFile instead. */ /* WriteConsole fails if the output is redirected to a file. Must use WriteFile instead. */
consoleAttached = 2; consoleAttached = CONSOLE_ATTACHED_FILE;
} }
} }
} }
#endif /* !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK) */ #endif /* !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK) */
length = SDL_strlen(SDL_GetLogPriorityPrefix(priority)) + SDL_strlen(message) + 1 + 1 + 1; length = SDL_strlen(SDL_GetLogPriorityPrefix(priority)) + SDL_strlen(message) + 1 + 1 + 1;
output = SDL_small_alloc(char, length, &isstack); output = SDL_small_alloc(char, length, &isstack);
(void)SDL_snprintf(output, length, "%s%s\r\n", SDL_GetLogPriorityPrefix(priority), message); (void)SDL_snprintf(output, length, "%s%s\r\n", SDL_GetLogPriorityPrefix(priority), message);
tstr = WIN_UTF8ToString(output); tstr = WIN_UTF8ToString(output);
#if defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK)
/* When running in MSVC and using stdio, rely on forwarding of stderr to the debug stream */
if (consoleAttached != CONSOLE_ATTACHED_MSVC) {
/* Output to debugger */
OutputDebugString(tstr);
}
#else
/* Output to debugger */ /* Output to debugger */
OutputDebugString(tstr); OutputDebugString(tstr);
#endif
#if !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK) #if !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK)
/* Screen output to stderr, if console was attached. */ /* Screen output to stderr, if console was attached. */
if (consoleAttached == 1) { if (consoleAttached == CONSOLE_ATTACHED_CONSOLE) {
if (!WriteConsole(stderrHandle, tstr, (DWORD)SDL_tcslen(tstr), &charsWritten, NULL)) { if (!WriteConsole(stderrHandle, tstr, (DWORD)SDL_tcslen(tstr), &charsWritten, NULL)) {
OutputDebugString(TEXT("Error calling WriteConsole\r\n")); OutputDebugString(TEXT("Error calling WriteConsole\r\n"));
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) { if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
@ -589,7 +604,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
} }
} }
} else if (consoleAttached == 2) { } else if (consoleAttached == CONSOLE_ATTACHED_FILE) {
if (!WriteFile(stderrHandle, output, (DWORD)SDL_strlen(output), &charsWritten, NULL)) { if (!WriteFile(stderrHandle, output, (DWORD)SDL_strlen(output), &charsWritten, NULL)) {
OutputDebugString(TEXT("Error calling WriteFile\r\n")); OutputDebugString(TEXT("Error calling WriteFile\r\n"));
} }