From ceaa2af39ef5242de553d47bed2b37a259bfc0f8 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 13 Nov 2012 09:15:59 +0400 Subject: [PATCH] Add support of Android logger * doc/README.macros (GC_ANDROID_LOG): Document new macro. * misc.c: Include android/log.h if GC_ANDROID_LOG. * misc.c (GC_ANDROID_LOG_TAG): Define new macro if GC_ANDROID_LOG (and not ye defined). * misc.c (GC_printf, GC_log_printf, GC_err_puts): Output message using __android_log_write with ANDROID_LOG_DEBUG/INFO/ERROR level (respectively) and GC_ANDROID_LOG_TAG logger name if GC_ANDROID_LOG (skip writing to GC_stdout/stderr/log (respectively) in this case unless redirected to a file). * misc.c (GC_default_on_abort): If GC_ANDROID_LOG then invoke __android_log_assert after WRITE with the same message except for omitting redundant "\n" (and ignore GC_LOOP_ON_ABORT checking in this case because android_log_assert is a no-return function). --- doc/README.macros | 2 ++ misc.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/doc/README.macros b/doc/README.macros index b7d72019..a822f0f4 100644 --- a/doc/README.macros +++ b/doc/README.macros @@ -532,6 +532,8 @@ GC_ONLY_LOG_TO_FILE Don't redirect GC stdout and stderr to the log file specified by GC_LOG_FILE environment variable. Has effect only when the variable is set (to anything other than "0"). +GC_ANDROID_LOG (Android only) Output error/debug information to Android log. + GC_DONT_EXPAND Don't expand the heap unless explicitly requested or forced to. GC_USE_ENTIRE_HEAP Causes the non-incremental collector to use the diff --git a/misc.c b/misc.c index c5117967..533dbfe5 100644 --- a/misc.c +++ b/misc.c @@ -1439,6 +1439,14 @@ GC_API void GC_CALL GC_enable_incremental(void) # define WRITE(f, buf, len) GC_write(f, buf, len) #endif /* !MSWIN32 && !OS2 && !MACOS */ +#ifdef GC_ANDROID_LOG +# include + +# ifndef GC_ANDROID_LOG_TAG +# define GC_ANDROID_LOG_TAG "BDWGC" +# endif +#endif + #define BUFSZ 1024 #ifdef NO_VSNPRINTF @@ -1472,8 +1480,16 @@ void GC_printf(const char *format, ...) { char buf[BUFSZ + 1]; - if (!GC_quiet) { +# ifdef GC_ANDROID_LOG GC_PRINTF_FILLBUF(buf, format); + __android_log_write(ANDROID_LOG_DEBUG, GC_ANDROID_LOG_TAG, buf); + if (GC_stdout == GC_DEFAULT_STDOUT_FD) + return; /* skip duplicate write to stdout */ +# endif + if (!GC_quiet) { +# ifndef GC_ANDROID_LOG + GC_PRINTF_FILLBUF(buf, format); +# endif if (WRITE(GC_stdout, buf, strlen(buf)) < 0) ABORT("write to stdout failed"); } @@ -1492,12 +1508,22 @@ void GC_log_printf(const char *format, ...) char buf[BUFSZ + 1]; GC_PRINTF_FILLBUF(buf, format); +# ifdef GC_ANDROID_LOG + __android_log_write(ANDROID_LOG_INFO, GC_ANDROID_LOG_TAG, buf); + if (GC_log == GC_DEFAULT_STDERR_FD) + return; /* skip duplicate write to stderr */ +# endif if (WRITE(GC_log, buf, strlen(buf)) < 0) ABORT("write to GC log failed"); } void GC_err_puts(const char *s) { +# ifdef GC_ANDROID_LOG + __android_log_write(ANDROID_LOG_ERROR, GC_ANDROID_LOG_TAG, s); + if (GC_stderr == GC_DEFAULT_STDERR_FD) + return; /* skip duplicate write to stderr */ +# endif if (WRITE(GC_stderr, s, strlen(s)) < 0) ABORT("write to stderr failed"); } @@ -1585,9 +1611,12 @@ GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void) if (WRITE(GC_stderr, (void *)msg, strlen(msg)) >= 0) (void)WRITE(GC_stderr, (void *)("\n"), 1); } +# ifdef GC_ANDROID_LOG + __android_log_assert("*" /* cond */, GC_ANDROID_LOG_TAG, "%s\n", msg); +# endif } -# ifndef NO_DEBUGGING +# if !defined(NO_DEBUGGING) && !defined(GC_ANDROID_LOG) if (GETENV("GC_LOOP_ON_ABORT") != NULL) { /* In many cases it's easier to debug a running process. */ /* It's arguably nicer to sleep, but that makes it harder */ -- 2.40.0