Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Henry <luhenry@microsoft.com>2017-11-28 00:37:11 +0300
committerGitHub <noreply@github.com>2017-11-28 00:37:11 +0300
commit984f6484666c2ee6fefec949c81fdff1189c9488 (patch)
treec73bd36899c94bbdefc0835d003b1a37c592ebf0 /sdks/android
parent20de41832a4ee7a393e432700182b01c9e775fe6 (diff)
[sdks] Use runtime logging features to intercept Console.{Out,Error} and runtime logs for instrumentation (#6083)
* [sdks] Fix Android pick of mono runtime * [android] Have Console.{Out,Error} go through the runtime log mechanism to ease their interception * [sdks] Intercept runtime logs instead of Console to send back for instrumentation * [sdks] Intercept Android test runner logging
Diffstat (limited to 'sdks/android')
-rw-r--r--sdks/android/jni/runtime-bootstrap.c112
-rw-r--r--sdks/android/managed/main.cs44
2 files changed, 88 insertions, 68 deletions
diff --git a/sdks/android/jni/runtime-bootstrap.c b/sdks/android/jni/runtime-bootstrap.c
index 2f060df132b..535f4b1bbc9 100644
--- a/sdks/android/jni/runtime-bootstrap.c
+++ b/sdks/android/jni/runtime-bootstrap.c
@@ -62,6 +62,9 @@ typedef struct MonoImage_ MonoImage;
typedef struct MonoObject_ MonoObject;
typedef struct MonoThread_ MonoThread;
+/* Imported from `mono-logger.h` */
+typedef void (*MonoLogCallback) (const char *log_domain, const char *log_level, const char *message, int32_t fatal, void *user_data);
+
/*
* The "err" variable contents must be allocated using g_malloc or g_strdup
*/
@@ -93,6 +96,8 @@ typedef void (*mono_domain_set_config_fn) (MonoDomain *, const char *, const cha
typedef int (*mono_runtime_set_main_args_fn) (int argc, char* argv[]);
typedef MonoMethod* (*mono_class_get_methods_fn) (MonoClass* klass, void **iter);
typedef const char* (*mono_method_get_name_fn) (MonoMethod *method);
+typedef void (*mono_trace_init_fn) (void);
+typedef void (*mono_trace_set_log_handler_fn) (MonoLogCallback callback, void *user_data);
static JavaVM *jvm;
@@ -119,6 +124,8 @@ static mono_domain_set_config_fn mono_domain_set_config;
static mono_runtime_set_main_args_fn mono_runtime_set_main_args;
static mono_class_get_methods_fn mono_class_get_methods;
static mono_method_get_name_fn mono_method_get_name;
+static mono_trace_init_fn mono_trace_init;
+static mono_trace_set_log_handler_fn mono_trace_set_log_handler;
static MonoAssembly *main_assembly;
static void *runtime_bootstrap_dso;
@@ -131,13 +138,82 @@ static void* my_dlopen (const char *name, int flags, char **err, void *user_data
//stuff
+
+static void
+_runtime_log (const char *log_domain, const char *log_level, const char *message, int32_t fatal, void *user_data)
+{
+ static jclass AndroidRunner_klass = NULL;
+ static jmethodID AndroidRunner_WriteLineToInstrumentation_method = NULL;
+ JNIEnv *env;
+ jstring j_message;
+
+ if (jvm == NULL)
+ __android_log_assert ("", "mono-sdks", "%s: jvm is NULL", __func__);
+
+ (*jvm)->GetEnv (jvm, (void**)&env, JNI_VERSION_1_6);
+
+ if (AndroidRunner_klass == NULL || AndroidRunner_WriteLineToInstrumentation_method == NULL) {
+ AndroidRunner_klass = (*env)->FindClass (env, "org/mono/android/AndroidRunner");
+ AndroidRunner_WriteLineToInstrumentation_method = (*env)->GetStaticMethodID (env, AndroidRunner_klass, "WriteLineToInstrumentation", "(Ljava/lang/String;)V");
+ }
+
+ j_message = (*env)->NewStringUTF(env, message);
+
+ (*env)->CallStaticVoidMethod (env, AndroidRunner_klass, AndroidRunner_WriteLineToInstrumentation_method, j_message);
+
+ (*env)->DeleteLocalRef (env, j_message);
+
+ /* Still print it on the logcat */
+
+ android_LogPriority android_log_level;
+ switch (*log_level) {
+ case 'e': /* error */
+ android_log_level = ANDROID_LOG_FATAL;
+ break;
+ case 'c': /* critical */
+ android_log_level = ANDROID_LOG_ERROR;
+ break;
+ case 'w': /* warning */
+ android_log_level = ANDROID_LOG_WARN;
+ break;
+ case 'm': /* message */
+ android_log_level = ANDROID_LOG_INFO;
+ break;
+ case 'i': /* info */
+ android_log_level = ANDROID_LOG_DEBUG;
+ break;
+ case 'd': /* debug */
+ android_log_level = ANDROID_LOG_VERBOSE;
+ break;
+ default:
+ android_log_level = ANDROID_LOG_UNKNOWN;
+ break;
+ }
+
+ __android_log_write (android_log_level, log_domain, message);
+ if (android_log_level == ANDROID_LOG_FATAL)
+ abort ();
+}
+
static void
_log (const char *format, ...)
{
va_list args;
+ char *buf;
+ int nbuf;
+
+ errno = 0;
+
va_start (args, format);
- __android_log_vprint (ANDROID_LOG_INFO, "MONO", format, args);
+ nbuf = vasprintf (&buf, format, args);
va_end (args);
+
+ if (buf == NULL || nbuf == -1)
+ __android_log_assert ("", "mono-sdks", "%s: vasprintf failed, error: \"%s\" (%d), nbuf = %d, buf = \"%s\"", __func__, strerror(errno), errno, nbuf, buf ? buf : "(null)");
+
+ _runtime_log ("mono-sdks", "debug", buf, 0, NULL);
+
+ free (buf);
}
static void
@@ -243,10 +319,10 @@ Java_org_mono_android_AndroidRunner_runTests (JNIEnv* env, jobject thiz, jstring
strncpy_str (env, data_dir, j_data_dir, sizeof(data_dir));
strncpy_str (env, assemblies_dir, j_assembly_dir, sizeof(assemblies_dir));
- _log ("-- file dir %s\n", file_dir);
- _log ("-- cache dir %s\n", cache_dir);
- _log ("-- data dir %s\n", data_dir);
- _log ("-- assembly dir %s\n", assemblies_dir);
+ _log ("-- file dir %s", file_dir);
+ _log ("-- cache dir %s", cache_dir);
+ _log ("-- data dir %s", data_dir);
+ _log ("-- assembly dir %s", assemblies_dir);
prctl (PR_SET_DUMPABLE, 1);
snprintf (buff, sizeof(buff), "%s/libmonosgen-2.0.so", data_dir);
@@ -279,6 +355,8 @@ Java_org_mono_android_AndroidRunner_runTests (JNIEnv* env, jobject thiz, jstring
mono_runtime_set_main_args = dlsym (libmono, "mono_runtime_set_main_args");
mono_class_get_methods = dlsym (libmono, "mono_class_get_methods");
mono_method_get_name = dlsym (libmono, "mono_method_get_name");
+ mono_trace_init = dlsym (libmono, "mono_trace_init");
+ mono_trace_set_log_handler = dlsym (libmono, "mono_trace_set_log_handler");
//MUST HAVE envs
setenv ("TMPDIR", cache_dir, 1);
@@ -290,9 +368,13 @@ Java_org_mono_android_AndroidRunner_runTests (JNIEnv* env, jobject thiz, jstring
create_and_set (file_dir, "home/.config", "XDG_CONFIG_HOME");
//Debug flags
- // setenv ("MONO_LOG_LEVEL", "debug", 1);
+ setenv ("MONO_LOG_LEVEL", "info", 1);
+ setenv ("MONO_LOG_MASK", "all", 1);
// setenv ("MONO_VERBOSE_METHOD", "GetCallingAssembly", 1);
+ mono_trace_init ();
+ mono_trace_set_log_handler (_runtime_log, NULL);
+
mono_set_assemblies_path (assemblies_dir);
mono_set_crash_chaining (1);
mono_set_signal_chaining (1);
@@ -558,24 +640,6 @@ _monodroid_get_dns_servers (void **dns_servers_array)
return count;
}
-MONO_API void
-AndroidIntrumentationWriter_WriteLineToInstrumentation (char *chars)
-{
- JNIEnv *env;
- jclass AndroidRunner_klass;
- jmethodID AndroidRunner_WriteLineToInstrumentation_method;
- jstring j_chars;
-
- (*jvm)->GetEnv (jvm, (void**)&env, JNI_VERSION_1_6);
-
- AndroidRunner_klass = (*env)->FindClass (env, "org/mono/android/AndroidRunner");
- AndroidRunner_WriteLineToInstrumentation_method = (*env)->GetStaticMethodID (env, AndroidRunner_klass, "WriteLineToInstrumentation", "(Ljava/lang/String;)V");
-
- j_chars = (*env)->NewStringUTF(env, chars);
-
- (*env)->CallStaticVoidMethod (env, AndroidRunner_klass, AndroidRunner_WriteLineToInstrumentation_method, j_chars);
-}
-
JNIEXPORT jint JNICALL
JNI_OnLoad (JavaVM *vm, void *reserved)
{
diff --git a/sdks/android/managed/main.cs b/sdks/android/managed/main.cs
index 1ac277d3699..84b6081cb56 100644
--- a/sdks/android/managed/main.cs
+++ b/sdks/android/managed/main.cs
@@ -14,9 +14,6 @@ public class Driver
public static void RunTests ()
{
- Console.SetOut (TextWriter.Synchronized (new AndroidIntrumentationWriter (Console.Out)));
- Console.SetError (TextWriter.Synchronized (new AndroidIntrumentationWriter (Console.Error)));
-
string assembly = File.ReadAllText ($"{AppDomain.CurrentDomain.BaseDirectory}/testassembly.txt");
Console.WriteLine ($"Testing assembly \"{assembly}\"");
@@ -40,45 +37,4 @@ public class Driver
{
Environment.Exit (1);
}
-
- class AndroidIntrumentationWriter : TextWriter
- {
- readonly StringBuilder Line = new StringBuilder ();
-
- readonly TextWriter Inner;
-
- public override Encoding Encoding => Inner.Encoding;
-
- public AndroidIntrumentationWriter (TextWriter inner)
- {
- Inner = inner;
- }
-
- public override void Write(char value)
- {
- if (value == '\n')
- WriteLine ();
- else
- Line.Append (value);
- }
-
- public override void WriteLine ()
- {
- var l = Line.ToString ();
- Line.Clear ();
-
- unsafe
- {
- fixed (byte *chars = Encoding.UTF8.GetBytes (l + '\0'))
- {
- WriteLineToInstrumentation (chars);
- }
- }
-
- Inner.WriteLine (l);
- }
-
- [DllImport ("__Internal", EntryPoint = "AndroidIntrumentationWriter_WriteLineToInstrumentation", CharSet = CharSet.Unicode)]
- static unsafe extern void WriteLineToInstrumentation (byte *chars);
- }
}