Skip to content

Commit c50079c

Browse files
committed
Add Android logging support to a couple of runtime files.
1 parent 205abfb commit c50079c

File tree

13 files changed

+504
-145
lines changed

13 files changed

+504
-145
lines changed

src/coreclr/inc/utilcode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ using std::nothrow;
3737

3838
#include <stddef.h>
3939
#include <minipal/guid.h>
40+
#include <minipal/log.h>
4041
#include <dn-u16.h>
4142

4243
#include "clrnt.h"

src/coreclr/jit/ee_il_dll.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2929
#define DLLEXPORT
3030
#endif // !DLLEXPORT
3131

32-
#if defined(HOST_ANDROID)
33-
#include <android/log.h>
34-
#endif
32+
#include "minipal/log.h"
3533

3634
/*****************************************************************************/
3735

@@ -150,16 +148,19 @@ FILE* jitstdout()
150148
// Like printf/logf, but only outputs to jitstdout -- skips call back into EE.
151149
int jitprintf(const char* fmt, ...)
152150
{
151+
int status;
153152
va_list vl;
154153
va_start(vl, fmt);
155-
#if defined(HOST_ANDROID)
156-
int status = jitstdout() == procstdout()
157-
? __android_log_vprint(ANDROID_LOG_VERBOSE, MAIN_CLR_MODULE_NAME_A, fmt, vl)
158-
: vfprintf(jitstdout(), fmt, vl);
159-
#else
160-
int status = vfprintf(jitstdout(), fmt, vl);
161-
#endif
154+
if (jitstdout() == procstdout())
155+
{
156+
status = minipal_log_vprint_verbose(fmt, vl);
157+
}
158+
else
159+
{
160+
status = vfprintf(jitstdout(), fmt, vl);
161+
}
162162
va_end(vl);
163+
163164
return status;
164165
}
165166

src/coreclr/jit/error.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1515
#pragma hdrstop
1616
#endif
1717
#include "compiler.h"
18+
#include "minipal/log.h"
1819

1920
#if MEASURE_FATAL
2021
unsigned fatal_badCode;
@@ -318,7 +319,10 @@ int vflogf(FILE* file, const char* fmt, va_list args)
318319
// 0-length string means flush
319320
if (fmt[0] == '\0')
320321
{
321-
fflush(file);
322+
if (file == procstdout())
323+
minipal_log_flush_verbose();
324+
else
325+
fflush(file);
322326
return 0;
323327
}
324328

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

334-
// We use fputs here so that this executes as fast a possible
335-
fputs(&buffer[0], file);
338+
if (file == procstdout())
339+
minipal_log_write_verbose(buffer);
340+
else
341+
fputs(&buffer[0], file);
342+
336343
return written;
337344
}
338345

src/coreclr/pal/src/thread/process.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,6 +2449,16 @@ PAL_GenerateCoreDump(
24492449
24502450
(no return value)
24512451
--*/
2452+
#ifdef HOST_ANDROID
2453+
#include <minipal/log.h>
2454+
VOID
2455+
PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, bool serialize)
2456+
{
2457+
// TODO: Dump all managed threads callstacks into logcat and/or file?
2458+
// TODO: Dump stress log into logcat and/or file when enabled?
2459+
minipal_log_write_fatal("Aborting process.\n");
2460+
}
2461+
#else
24522462
VOID
24532463
PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, bool serialize)
24542464
{
@@ -2517,6 +2527,7 @@ PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, bool serialize)
25172527
free(signalAddressArg);
25182528
}
25192529
}
2530+
#endif
25202531

25212532
/*++
25222533
Function:

src/coreclr/utilcode/log.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,10 @@ VOID LogSpewAlwaysValist(const char *fmt, va_list args)
372372

373373
if (LogFlags & LOG_ENABLE_CONSOLE_LOGGING)
374374
{
375-
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pBuffer, buflen, &written, 0);
375+
minipal_log_write_stdout(pBuffer);
376376
//<TODO>@TODO ...Unnecessary to flush console?</TODO>
377377
if (LogFlags & LOG_ENABLE_FLUSH_FILE)
378-
FlushFileBuffers( GetStdHandle(STD_OUTPUT_HANDLE) );
378+
minipal_log_sync_stdout();
379379
}
380380

381381
if (LogFlags & LOG_ENABLE_DEBUGGER_LOGGING)
@@ -415,6 +415,5 @@ VOID LogSpewAlways (const char *fmt, ... )
415415
LogSpewValist (LF_ALWAYS, LL_ALWAYS, fmt, args);
416416
va_end(args);
417417
}
418-
419418
#endif // LOGGING
420419

src/coreclr/vm/eepolicy.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void SafeExitProcess(UINT exitCode, ShutdownCompleteAction sca = SCA_ExitProcess
4848
{
4949
_ASSERTE(!"Bad Exit value");
5050
FAULT_NOT_FATAL(); // if we OOM we can simply give up
51-
fprintf(stderr, "Error 0x%08x.\n\nBreakOnBadExit: returning bad exit code.", exitCode);
51+
minipal_log_print_stderr("Error 0x%08x.\n\nBreakOnBadExit: returning bad exit code.", exitCode);
5252
DebugBreak();
5353
}
5454
}
@@ -233,8 +233,10 @@ class CallStackLogger
233233

234234
MethodDesc* pMD = m_frames[index];
235235
TypeString::AppendMethodInternal(str, pMD, TypeString::FormatNamespace|TypeString::FormatFullInst|TypeString::FormatSignature);
236-
PrintToStdErrW(str.GetUnicode());
237-
PrintToStdErrA("\n");
236+
str.Append(W("\n"));
237+
238+
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(strUTF8, str.GetUnicode(), CP_UTF8);
239+
minipal_log_write_stderr(strUTF8);
238240
}
239241

240242
public:
@@ -264,13 +266,15 @@ class CallStackLogger
264266
SmallStackSString repeatStr;
265267
repeatStr.AppendPrintf("Repeated %d times:\n", m_largestCommonStartRepeat);
266268

267-
PrintToStdErrW(repeatStr.GetUnicode());
268-
PrintToStdErrA("--------------------------------\n");
269+
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(repeatStrUTF8, repeatStr.GetUnicode(), CP_UTF8);
270+
minipal_log_write_stderr(repeatStrUTF8);
271+
272+
minipal_log_write_stderr("--------------------------------\n");
269273
for (int i = 0; i < m_largestCommonStartLength; i++)
270274
{
271275
PrintFrame(i, pWordAt);
272276
}
273-
PrintToStdErrA("--------------------------------\n");
277+
minipal_log_write_stderr("--------------------------------\n");
274278
}
275279

276280
for (int i = m_largestCommonStartLength * m_largestCommonStartRepeat; i < m_frames.Count(); i++)
@@ -347,7 +351,7 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, PEXCEPTION_POINTERS
347351
{
348352
if (previousThreadID == currentThreadID)
349353
{
350-
PrintToStdErrA("Fatal error while logging another fatal error.\n");
354+
minipal_log_write_stderr("Fatal error while logging another fatal error.\n");
351355
}
352356
else
353357
{
@@ -362,42 +366,47 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, PEXCEPTION_POINTERS
362366

363367
EX_TRY
364368
{
369+
SString message;
365370
if (exitCode == (UINT)COR_E_FAILFAST)
366371
{
367-
PrintToStdErrA("Process terminated. ");
372+
message.Append(W("Process terminated. "));
368373
}
369374
else
370375
{
371-
PrintToStdErrA("Fatal error. ");
376+
message.Append(W("Fatal error. "));
372377
}
373378

374379
if (errorSource != NULL)
375380
{
376-
PrintToStdErrW(errorSource);
377-
PrintToStdErrA("\n");
381+
message.Append(errorSource);
382+
message.Append(W("\n"));
378383
}
379384

380385
if (pszMessage != NULL)
381386
{
382-
PrintToStdErrW(pszMessage);
387+
message.Append(pszMessage);
383388
}
384389
else
385390
{
386391
// If no message was passed in, generate it from the exitCode
387392
SString exitCodeMessage;
388393
GetHRMsg(exitCode, exitCodeMessage);
389-
PrintToStdErrW((LPCWSTR)exitCodeMessage);
394+
message.Append(exitCodeMessage);
390395
}
391396

392-
PrintToStdErrA("\n");
397+
message.Append(W("\n"));
398+
399+
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(messageUTF8, message.GetUnicode(), CP_UTF8);
400+
minipal_log_write_stderr(messageUTF8);
393401

394402
Thread* pThread = GetThreadNULLOk();
395403
if (pThread && errorSource == NULL)
396404
{
397405
LogCallstackForLogWorker(pThread, pExceptionInfo);
398406

399407
if (argExceptionString != NULL) {
400-
PrintToStdErrW(argExceptionString);
408+
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(argExceptionStringUTF8, argExceptionString, CP_UTF8);
409+
minipal_log_write_stderr(argExceptionStringUTF8);
401410
}
402411
}
403412
}
@@ -589,7 +598,7 @@ void DisplayStackOverflowException()
589598
{
590599
LIMITED_METHOD_CONTRACT;
591600

592-
PrintToStdErrA("Stack overflow.\n");
601+
minipal_log_write_stderr("Stack overflow.\n");
593602
}
594603

595604
DWORD LogStackOverflowStackTraceThread(void* arg)

src/coreclr/vm/eventing/eventpipe/ds-rt-coreclr.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "ep-rt-coreclr.h"
1212
#include <clrconfignocache.h>
1313
#include <generatedumpflags.h>
14+
#include <minipal/log.h>
1415
#include <eventpipe/ds-process-protocol.h>
1516
#include <eventpipe/ds-profiler-protocol.h>
1617
#include <eventpipe/ds-dump-protocol.h>
@@ -404,10 +405,10 @@ ds_rt_server_log_pause_message (void)
404405

405406
uint32_t port_suspended = ds_rt_config_value_get_default_port_suspend();
406407

407-
printf("The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command from a Diagnostic Port.\n");
408-
printf("DOTNET_%s=\"%s\"\n", diagPortsName, ports == nullptr ? "" : ports);
409-
printf("DOTNET_DefaultDiagnosticPortSuspend=%u\n", port_suspended);
410-
fflush(stdout);
408+
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");
409+
minipal_log_print_stdout("DOTNET_%s=\"%s\"\n", diagPortsName, ports == nullptr ? "" : ports);
410+
minipal_log_print_stdout("DOTNET_DefaultDiagnosticPortSuspend=%u\n", port_suspended);
411+
minipal_log_flush_stdout();
411412
}
412413

413414
#endif /* ENABLE_PERFTRACING */

src/coreclr/vm/excep.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4571,7 +4571,7 @@ lDone: ;
45714571
char buffer[200];
45724572
sprintf_s(buffer, 200, "\nInternal error: Uncaught exception was thrown from IP = %p in UnhandledExceptionFilter_Worker on thread 0x%08x\n",
45734573
param.ExceptionEIP, ((GetThreadNULLOk() == NULL) ? 0 : GetThread()->GetThreadId()));
4574-
PrintToStdErrA(buffer);
4574+
minipal_log_write_stderr(buffer);
45754575
_ASSERTE(!"Unexpected exception in UnhandledExceptionFilter_Worker");
45764576
#endif
45774577
EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE)
@@ -4777,8 +4777,6 @@ LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or
47774777
#pragma code_seg(pop, uef)
47784778
#endif // !TARGET_UNIX
47794779

4780-
void PrintStackTraceToStdout();
4781-
47824780
static SString GetExceptionMessageWrapper(Thread* pThread, OBJECTREF throwable)
47834781
{
47844782
STATIC_CONTRACT_THROWS;
@@ -4809,17 +4807,18 @@ DefaultCatchHandlerExceptionMessageWorker(Thread* pThread,
48094807
wcsncpy_s(buf, buf_size, SZ_UNHANDLED_EXCEPTION, SZ_UNHANDLED_EXCEPTION_CHARLEN);
48104808
}
48114809

4812-
PrintToStdErrW(buf);
4813-
PrintToStdErrA(" ");
4814-
4815-
SString message = GetExceptionMessageWrapper(pThread, throwable);
4810+
SString message(buf);
4811+
SString exceptionMessage = GetExceptionMessageWrapper(pThread, throwable);
48164812

4817-
if (!message.IsEmpty())
4813+
message.Append(W(" "));
4814+
if (!exceptionMessage.IsEmpty())
48184815
{
4819-
PrintToStdErrW(message);
4816+
message.Append(exceptionMessage);
48204817
}
4818+
message.Append(W("\n"));
48214819

4822-
PrintToStdErrA("\n");
4820+
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(messageUTF8, message.GetUnicode(), CP_UTF8);
4821+
minipal_log_write_stderr(messageUTF8);
48234822

48244823
#if defined(FEATURE_EVENT_TRACE) && !defined(TARGET_UNIX)
48254824
// Send the log to Windows Event Log
@@ -5002,11 +5001,11 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers,
50025001

50035002
if (IsOutOfMemory)
50045003
{
5005-
PrintToStdErrA("Out of memory.\n");
5004+
minipal_log_write_stderr("Out of memory.\n");
50065005
}
50075006
else
50085007
{
5009-
PrintToStdErrA("Stack overflow.\n");
5008+
minipal_log_write_stderr("Stack overflow.\n");
50105009
}
50115010
}
50125011
else if (SentEvent || IsAsyncThreadException(&throwable))
@@ -5027,17 +5026,21 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers,
50275026
EX_CATCH
50285027
{
50295028
LOG((LF_EH, LL_INFO10, "Exception occurred while processing uncaught exception\n"));
5030-
UtilLoadStringRC(IDS_EE_EXCEPTION_TOSTRING_FAILED, buf, buf_size);
5031-
PrintToStdErrA("\n ");
5032-
PrintToStdErrW(buf);
5033-
PrintToStdErrA("\n");
5029+
5030+
_ASSERTE(buf_size > 6);
5031+
wcscpy_s(buf, buf_size, W("\n "));
5032+
UtilLoadStringRC(IDS_EE_EXCEPTION_TOSTRING_FAILED, buf + 4, buf_size - 6);
5033+
wcscat_s(buf, buf_size, W("\n"));
5034+
5035+
MAKE_MULTIBYTE_FROMWIDE_BESTFIT(bufUTF8, buf, CP_UTF8);
5036+
minipal_log_write_stderr(bufUTF8);
50345037
}
50355038
EX_END_CATCH(SwallowAllExceptions);
50365039
}
50375040
EX_CATCH
50385041
{ // If we got here, we can't even print the localized error message. Print non-localized.
50395042
LOG((LF_EH, LL_INFO10, "Exception occurred while logging processing uncaught exception\n"));
5040-
PrintToStdErrA("\n Error: Can't print exception string because Exception.ToString() failed.\n");
5043+
minipal_log_write_stderr("\n Error: Can't print exception string because Exception.ToString() failed.\n");
50415044
}
50425045
EX_END_CATCH(SwallowAllExceptions);
50435046
}

0 commit comments

Comments
 (0)