Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add Android logging support to a couple of runtime files.
  • Loading branch information
lateralusX committed Mar 21, 2025
commit 9019d4e654d717fb4fd07ed46e82e3beb9a50166
1 change: 1 addition & 0 deletions src/coreclr/inc/utilcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ using std::nothrow;

#include <stddef.h>
#include <minipal/guid.h>
#include <minipal/log.h>
#include <dn-u16.h>

#include "clrnt.h"
Expand Down
21 changes: 11 additions & 10 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#define DLLEXPORT
#endif // !DLLEXPORT

#if defined(HOST_ANDROID)
#include <android/log.h>
#endif
#include "minipal/log.h"

/*****************************************************************************/

Expand Down Expand Up @@ -150,16 +148,19 @@ FILE* jitstdout()
// Like printf/logf, but only outputs to jitstdout -- skips call back into EE.
int jitprintf(const char* fmt, ...)
{
int status;
va_list vl;
va_start(vl, fmt);
#if defined(HOST_ANDROID)
int status = jitstdout() == procstdout()
? __android_log_vprint(ANDROID_LOG_VERBOSE, MAIN_CLR_MODULE_NAME_A, fmt, vl)
: vfprintf(jitstdout(), fmt, vl);
#else
int status = vfprintf(jitstdout(), fmt, vl);
#endif
if (jitstdout() == procstdout())
{
status = minipal_log_vprint_verbose(fmt, vl);
}
else
{
status = vfprintf(jitstdout(), fmt, vl);
}
va_end(vl);

return status;
}

Expand Down
13 changes: 10 additions & 3 deletions src/coreclr/jit/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#pragma hdrstop
#endif
#include "compiler.h"
#include "minipal/log.h"

#if MEASURE_FATAL
unsigned fatal_badCode;
Expand Down Expand Up @@ -318,7 +319,10 @@ int vflogf(FILE* file, const char* fmt, va_list args)
// 0-length string means flush
if (fmt[0] == '\0')
{
fflush(file);
if (file == procstdout())
minipal_log_flush_verbose();
else
fflush(file);
return 0;
}

Expand All @@ -331,8 +335,11 @@ int vflogf(FILE* file, const char* fmt, va_list args)
OutputDebugStringA(buffer);
}

// We use fputs here so that this executes as fast a possible
fputs(&buffer[0], file);
if (file == procstdout())
minipal_log_write_verbose(buffer);
else
fputs(&buffer[0], file);

return written;
}

Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/pal/src/thread/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2452,6 +2452,16 @@ PAL_GenerateCoreDump(

(no return value)
--*/
#ifdef HOST_ANDROID
#include <minipal/log.h>
VOID
PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, bool serialize)
{
// TODO: Dump all managed threads callstacks into logcat and/or file?
// TODO: Dump stress log into logcat and/or file when enabled?
minipal_log_write_fatal("Aborting process.\n");
}
#else
VOID
PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, bool serialize)
{
Expand Down Expand Up @@ -2520,6 +2530,7 @@ PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, bool serialize)
free(signalAddressArg);
}
}
#endif

/*++
Function:
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/utilcode/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,10 @@ VOID LogSpewAlwaysValist(const char *fmt, va_list args)

if (LogFlags & LOG_ENABLE_CONSOLE_LOGGING)
{
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pBuffer, buflen, &written, 0);
minipal_log_write_stdout(pBuffer);
//<TODO>@TODO ...Unnecessary to flush console?</TODO>
if (LogFlags & LOG_ENABLE_FLUSH_FILE)
FlushFileBuffers( GetStdHandle(STD_OUTPUT_HANDLE) );
minipal_log_sync_stdout();
}

if (LogFlags & LOG_ENABLE_DEBUGGER_LOGGING)
Expand Down Expand Up @@ -415,6 +415,5 @@ VOID LogSpewAlways (const char *fmt, ... )
LogSpewValist (LF_ALWAYS, LL_ALWAYS, fmt, args);
va_end(args);
}

#endif // LOGGING

41 changes: 25 additions & 16 deletions src/coreclr/vm/eepolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void SafeExitProcess(UINT exitCode, ShutdownCompleteAction sca = SCA_ExitProcess
{
_ASSERTE(!"Bad Exit value");
FAULT_NOT_FATAL(); // if we OOM we can simply give up
fprintf(stderr, "Error 0x%08x.\n\nBreakOnBadExit: returning bad exit code.", exitCode);
minipal_log_print_stderr("Error 0x%08x.\n\nBreakOnBadExit: returning bad exit code.", exitCode);
DebugBreak();
}
}
Expand Down Expand Up @@ -233,8 +233,10 @@ class CallStackLogger

MethodDesc* pMD = m_frames[index];
TypeString::AppendMethodInternal(str, pMD, TypeString::FormatNamespace|TypeString::FormatFullInst|TypeString::FormatSignature);
PrintToStdErrW(str.GetUnicode());
PrintToStdErrA("\n");
str.Append(W("\n"));

MAKE_MULTIBYTE_FROMWIDE_BESTFIT(strUTF8, str.GetUnicode(), CP_UTF8);
minipal_log_write_stderr(strUTF8);
}

public:
Expand Down Expand Up @@ -264,13 +266,15 @@ class CallStackLogger
SmallStackSString repeatStr;
repeatStr.AppendPrintf("Repeated %d times:\n", m_largestCommonStartRepeat);

PrintToStdErrW(repeatStr.GetUnicode());
PrintToStdErrA("--------------------------------\n");
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(repeatStrUTF8, repeatStr.GetUnicode(), CP_UTF8);
minipal_log_write_stderr(repeatStrUTF8);

minipal_log_write_stderr("--------------------------------\n");
for (int i = 0; i < m_largestCommonStartLength; i++)
{
PrintFrame(i, pWordAt);
}
PrintToStdErrA("--------------------------------\n");
minipal_log_write_stderr("--------------------------------\n");
}

for (int i = m_largestCommonStartLength * m_largestCommonStartRepeat; i < m_frames.Count(); i++)
Expand Down Expand Up @@ -356,7 +360,7 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, PEXCEPTION_POINTERS
{
if (previousThreadID == currentThreadID)
{
PrintToStdErrA("Fatal error while logging another fatal error.\n");
minipal_log_write_stderr("Fatal error while logging another fatal error.\n");
}
else
{
Expand All @@ -371,42 +375,47 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, PEXCEPTION_POINTERS

EX_TRY
{
SString message;
if (exitCode == (UINT)COR_E_FAILFAST)
{
PrintToStdErrA("Process terminated. ");
message.Append(W("Process terminated. "));
}
else
{
PrintToStdErrA("Fatal error. ");
message.Append(W("Fatal error. "));
}

if (errorSource != NULL)
{
PrintToStdErrW(errorSource);
PrintToStdErrA("\n");
message.Append(errorSource);
message.Append(W("\n"));
}

if (pszMessage != NULL)
{
PrintToStdErrW(pszMessage);
message.Append(pszMessage);
}
else
{
// If no message was passed in, generate it from the exitCode
SString exitCodeMessage;
GetHRMsg(exitCode, exitCodeMessage);
PrintToStdErrW((LPCWSTR)exitCodeMessage);
message.Append(exitCodeMessage);
}

PrintToStdErrA("\n");
message.Append(W("\n"));

MAKE_MULTIBYTE_FROMWIDE_BESTFIT(messageUTF8, message.GetUnicode(), CP_UTF8);
minipal_log_write_stderr(messageUTF8);

Thread* pThread = GetThreadNULLOk();
if (pThread && errorSource == NULL)
{
LogCallstackForLogWorker(pThread, pExceptionInfo);

if (argExceptionString != NULL) {
PrintToStdErrW(argExceptionString);
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(argExceptionStringUTF8, argExceptionString, CP_UTF8);
minipal_log_write_stderr(argExceptionStringUTF8);
}
}
}
Expand Down Expand Up @@ -598,7 +607,7 @@ void DisplayStackOverflowException()
{
LIMITED_METHOD_CONTRACT;

PrintToStdErrA("Stack overflow.\n");
minipal_log_write_stderr("Stack overflow.\n");
}

DWORD LogStackOverflowStackTraceThread(void* arg)
Expand Down
9 changes: 5 additions & 4 deletions src/coreclr/vm/eventing/eventpipe/ds-rt-coreclr.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ep-rt-coreclr.h"
#include <clrconfignocache.h>
#include <generatedumpflags.h>
#include <minipal/log.h>
#include <eventpipe/ds-process-protocol.h>
#include <eventpipe/ds-profiler-protocol.h>
#include <eventpipe/ds-dump-protocol.h>
Expand Down Expand Up @@ -404,10 +405,10 @@ ds_rt_server_log_pause_message (void)

uint32_t port_suspended = ds_rt_config_value_get_default_port_suspend();

printf("The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command from a Diagnostic Port.\n");
printf("DOTNET_%s=\"%s\"\n", diagPortsName, ports == nullptr ? "" : ports);
printf("DOTNET_DefaultDiagnosticPortSuspend=%u\n", port_suspended);
fflush(stdout);
minipal_log_print_stdout("The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command from a Diagnostic Port.\n");
minipal_log_print_stdout("DOTNET_%s=\"%s\"\n", diagPortsName, ports == nullptr ? "" : ports);
minipal_log_print_stdout("DOTNET_DefaultDiagnosticPortSuspend=%u\n", port_suspended);
minipal_log_flush_stdout();
}

#endif /* ENABLE_PERFTRACING */
Expand Down
37 changes: 20 additions & 17 deletions src/coreclr/vm/excep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4550,7 +4550,7 @@ lDone: ;
char buffer[200];
sprintf_s(buffer, 200, "\nInternal error: Uncaught exception was thrown from IP = %p in UnhandledExceptionFilter_Worker on thread 0x%08x\n",
param.ExceptionEIP, ((GetThreadNULLOk() == NULL) ? 0 : GetThread()->GetThreadId()));
PrintToStdErrA(buffer);
minipal_log_write_stderr(buffer);
_ASSERTE(!"Unexpected exception in UnhandledExceptionFilter_Worker");
#endif
EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE)
Expand Down Expand Up @@ -4756,8 +4756,6 @@ LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or
#pragma code_seg(pop, uef)
#endif // !TARGET_UNIX

void PrintStackTraceToStdout();

static SString GetExceptionMessageWrapper(Thread* pThread, OBJECTREF throwable)
{
STATIC_CONTRACT_THROWS;
Expand Down Expand Up @@ -4788,17 +4786,18 @@ DefaultCatchHandlerExceptionMessageWorker(Thread* pThread,
wcsncpy_s(buf, buf_size, SZ_UNHANDLED_EXCEPTION, SZ_UNHANDLED_EXCEPTION_CHARLEN);
}

PrintToStdErrW(buf);
PrintToStdErrA(" ");

SString message = GetExceptionMessageWrapper(pThread, throwable);
SString message(buf);
SString exceptionMessage = GetExceptionMessageWrapper(pThread, throwable);

if (!message.IsEmpty())
message.Append(W(" "));
if (!exceptionMessage.IsEmpty())
{
PrintToStdErrW(message);
message.Append(exceptionMessage);
}
message.Append(W("\n"));

PrintToStdErrA("\n");
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(messageUTF8, message.GetUnicode(), CP_UTF8);
minipal_log_write_stderr(messageUTF8);

#if defined(FEATURE_EVENT_TRACE) && !defined(TARGET_UNIX)
// Send the log to Windows Event Log
Expand Down Expand Up @@ -4980,11 +4979,11 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers,

if (IsOutOfMemory)
{
PrintToStdErrA("Out of memory.\n");
minipal_log_write_stderr("Out of memory.\n");
}
else
{
PrintToStdErrA("Stack overflow.\n");
minipal_log_write_stderr("Stack overflow.\n");
}
}
else if (SentEvent || IsAsyncThreadException(&throwable))
Expand All @@ -5005,17 +5004,21 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers,
EX_CATCH
{
LOG((LF_EH, LL_INFO10, "Exception occurred while processing uncaught exception\n"));
UtilLoadStringRC(IDS_EE_EXCEPTION_TOSTRING_FAILED, buf, buf_size);
PrintToStdErrA("\n ");
PrintToStdErrW(buf);
PrintToStdErrA("\n");

_ASSERTE(buf_size > 6);
wcscpy_s(buf, buf_size, W("\n "));
UtilLoadStringRC(IDS_EE_EXCEPTION_TOSTRING_FAILED, buf + 4, buf_size - 6);
wcscat_s(buf, buf_size, W("\n"));

MAKE_MULTIBYTE_FROMWIDE_BESTFIT(bufUTF8, buf, CP_UTF8);
minipal_log_write_stderr(bufUTF8);
}
EX_END_CATCH(SwallowAllExceptions);
}
EX_CATCH
{ // If we got here, we can't even print the localized error message. Print non-localized.
LOG((LF_EH, LL_INFO10, "Exception occurred while logging processing uncaught exception\n"));
PrintToStdErrA("\n Error: Can't print exception string because Exception.ToString() failed.\n");
minipal_log_write_stderr("\n Error: Can't print exception string because Exception.ToString() failed.\n");
}
EX_END_CATCH(SwallowAllExceptions);
}
Expand Down
Loading