From: Twaik Yont <9674930+twaik@users.noreply.github.com> When Wine is started through the Android Java entry point (wineandroid.drv), debug output is currently written to a file in the application's private storage through WINEDEBUGLOG. Accessing this file on-device is inconvenient and typically requires a debug build or root access. Redirect stdout and stderr to Android logcat instead. This exposes Wine debug output through the standard Android diagnostics mechanism without requiring access to the application's internal storage. The redirection is installed only in the JNI startup path used by wineandroid. In this environment stdout and stderr are typically not visible to the user (often pointing to /dev/null), so redirecting them to logcat does not replace an existing diagnostics channel. Output is forwarded to logcat in chunks without reconstructing line boundaries. As with the previous WINEDEBUGLOG mechanism, stdout and stderr are not distinguished. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/ntdll/unix/loader.c | 64 ++++++++++++++++++++++---- dlls/wineandroid.drv/WineActivity.java | 6 --- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index ccda16cc14b..3ebaf9bdea1 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -79,6 +79,7 @@ #endif #ifdef __ANDROID__ # include <jni.h> +# include <android/log.h> #endif #include "ntstatus.h" @@ -1884,6 +1885,8 @@ DECLSPEC_EXPORT JavaVM *java_vm = NULL; DECLSPEC_EXPORT jobject java_object = 0; DECLSPEC_EXPORT unsigned short java_gdt_sel = 0; +static __typeof__(__android_log_write) *android_log_write; + /* main Wine initialisation */ static jstring wine_init_jni( JNIEnv *env, jobject obj, jobjectArray cmdline, jobjectArray environment ) { @@ -1936,15 +1939,6 @@ static jstring wine_init_jni( JNIEnv *env, jobject obj, jobjectArray cmdline, jo "android_update_LD_LIBRARY_PATH" ); if (update_func) update_func( val ); } - else if (!strcmp( var, "WINEDEBUGLOG" )) - { - int fd = open( val, O_WRONLY | O_CREAT | O_APPEND, 0666 ); - if (fd != -1) - { - dup2( fd, 2 ); - close( fd ); - } - } (*env)->ReleaseStringUTFChars( env, val_obj, val ); } else unsetenv( var ); @@ -1976,6 +1970,57 @@ static jstring wine_init_jni( JNIEnv *env, jobject obj, jobjectArray cmdline, jo return (*env)->NewStringUTF( env, error ); } +static void *android_log_thread( void *arg ) +{ + int fd = (int)(intptr_t)arg; + char buf[4096]; + ssize_t r; + + for (;;) + { + r = read( fd, buf, sizeof(buf) - 1 ); + if (r > 0) + { + buf[r] = 0; + android_log_write( ANDROID_LOG_DEBUG, "WineOut", buf ); + continue; + } + if (!r) break; + if (errno == EINTR) continue; + break; + } + + close( fd ); + return NULL; +} + +static void init_android_log(void) +{ + pthread_t thread; + void *handle; + int pipefd[2]; + + if ( + !(handle = dlopen( "liblog.so", RTLD_NOW | RTLD_LOCAL )) || + !(android_log_write = (__typeof__(__android_log_write) *) dlsym( handle, "__android_log_write" )) || + pipe( pipefd ) + ) return; + + if (pthread_create( &thread, NULL, android_log_thread, (void *)(intptr_t)pipefd[0] )) + { + close( pipefd[0] ); + close( pipefd[1] ); + return; + } + + pthread_detach( thread ); + + if (dup2( pipefd[1], STDOUT_FILENO ) != -1) + dup2( pipefd[1], STDERR_FILENO ); + + close( pipefd[1] ); +} + jint JNI_OnLoad( JavaVM *vm, void *reserved ) { static const JNINativeMethod method = @@ -1986,6 +2031,7 @@ jint JNI_OnLoad( JavaVM *vm, void *reserved ) JNIEnv *env; jclass class; + init_android_log(); virtual_init(); java_vm = vm; diff --git a/dlls/wineandroid.drv/WineActivity.java b/dlls/wineandroid.drv/WineActivity.java index 2eee16b2dc1..650858d7d0a 100644 --- a/dlls/wineandroid.drv/WineActivity.java +++ b/dlls/wineandroid.drv/WineActivity.java @@ -138,13 +138,7 @@ private void loadWine( String cmdline ) String winedebug = readFileString( new File( prefix, "winedebug" )); if (winedebug == null) winedebug = readFileString( new File( getFilesDir(), "winedebug" )); if (winedebug != null) - { - File log = new File( getFilesDir(), "log" ); env.put( "WINEDEBUG", winedebug ); - env.put( "WINEDEBUGLOG", log.toString() ); - Log.i( LOGTAG, "logging to " + log.toString() ); - log.delete(); - } createProgressDialog( 0, "Setting up the Windows environment..." ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10276