From: Twaik Yont <9674930+twaik@users.noreply.github.com> Upcoming changes will move parts of ioctl dispatch execution to threads originating purely from the Java/Android side, without a Wine TEB. In such contexts, the standard Wine debug macros (TRACE/WARN/FIXME/ERR) are unsafe, as they rely on TEB-backed state and may crash. Prepare for this by making logging context-aware in device.c without requiring invasive changes across all call sites. Introduce a lightweight helper to detect whether the current thread has a Wine TEB, and use it to route logging accordingly: * on Wine threads, preserve the standard Wine debug behavior * on non-Wine threads, fall back to Android logging via __android_log_print Override TRACE/WARN/FIXME/ERR locally so existing code continues to work unchanged while remaining safe in both execution contexts. Also provide a local wine_dbgstr_rect implementation that avoids dependencies on Wine thread state, and force early initialization of debug channel flags for use outside Wine threads. This keeps logging semantics consistent while allowing ioctl dispatch code to run on Java-only threads without requiring widespread changes. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/device.c | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 0032224560d..5315af13747 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -46,6 +46,50 @@ #include <dlfcn.h> +BOOL __is_wine_thread(void) +{ + static __thread signed char cached = -1; + + if (cached == -1) + cached = NtCurrentTeb() ? 1 : 0; + + return cached ? TRUE : FALSE; +} + +static inline const char *_wine_dbgstr_rect( const RECT *rect ) +{ + enum { N = 4 }; + static __thread char buf[N][64]; + static __thread int idx; + char *ret = buf[idx++ % N]; + + if (!rect) return "(null)"; + snprintf( ret, 64, "(%d,%d)-(%d,%d)", (int)rect->left, (int)rect->top, (int)rect->right, (int)rect->bottom ); + return ret; +} + +#undef TRACE +#undef WARN +#undef FIXME +#undef ERR + +#define __LOG(cls, prio, fmt, ...) \ + do { \ + if (__is_wine_thread()) \ + WINE ## cls (fmt, ##__VA_ARGS__); \ + else if (!(__wine_dbch_android.flags & (1 << __WINE_DBCL_INIT)) || \ + __WINE_GET_DEBUGGING(cls, &__wine_dbch_android)) \ + p__android_log_print(ANDROID_LOG_##prio, "wineandroid.drv", "%s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ + } while (0) + +#define TRACE(...) __LOG(_TRACE, VERBOSE, __VA_ARGS__) +#define WARN(...) __LOG(_WARN, WARN, __VA_ARGS__) +#define FIXME(...) __LOG(_FIXME, WARN, "FIXME: " __VA_ARGS__) +#define ERR(...) __LOG(_ERR, ERROR, __VA_ARGS__) + +#define wine_dbgstr_rect _wine_dbgstr_rect + + WINE_DEFAULT_DEBUG_CHANNEL(android); #ifndef SYNC_IOC_WAIT @@ -1032,6 +1076,7 @@ void start_android_device(void) void *ret_ptr; ULONG ret_len; struct dispatch_callback_params params = {.callback = start_device_callback}; + __wine_dbg_get_channel_flags(&__wine_dbch_android); // force lazy init of debug channel flags for use outside Wine thread context if (KeUserDispatchCallback( ¶ms, sizeof(params), &ret_ptr, &ret_len )) return; if (ret_len == sizeof(thread)) thread = *(HANDLE *)ret_ptr; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10710