¿Cómo redirigir la aplicación de Android stdout/stderr con ADB?

¿Cómo redirigir la aplicación de Android stdout/stderr con ADB?

Quiero automatizar más el proceso de desarrollo de software para algunas aplicaciones de línea de comandos de Android. Hace años, habría instalado Busybox en un dispositivo Android físico, habría buscado un microscopio y habría comenzado a escribir Emacs para Android. Hoy estoy buscando una forma más conveniente de codificar.

En particular, quiero redirigir los descriptores de archivos stdout y stderr para aplicaciones de Android (NDK), de forma similar a cómo funciona qemu-arm64-static.

¿Alguien sabe si esto es posible con ADB? Como alternativa, podría estructurar mis aplicaciones como microservicios y utilizar el reenvío de puertos ADB. Pero al hacerlo perdería muchas convenciones clásicas de UNIX.

Veo que ADB tiene captura de registro, para mensajes NDK (log.h) y SDK (Log.class). Pero, lamentablemente, no veo una forma clara de redirigir el STDIN del host a la aplicación invitada de Android STDIN.

¿Quizás haya una manera de activar Toybox (mksh) a través de adb y enviar comandos sh personalizados allí?

Respuesta1

Varias fuentes (p. ej.https://stackoverflow.com/a/36561699/340175yhttps://github.com/android/ndk/issues/671#issuecomment-383890481) recomiendan el enfoque descrito enhttps://codelab.wordpress.com/2014/11/03/how-to-use-standard-output-streams-for-logging-in-android-apps/

Para la posteridad, el código de esa publicación de blog es el siguiente:

static int pfd[2];
static pthread_t thr;
static const char *tag = "myapp";

int start_logger(const char *app_name)
{
    tag = app_name;

    /* make stdout line-buffered and stderr unbuffered */
    setvbuf(stdout, 0, _IOLBF, 0);
    setvbuf(stderr, 0, _IONBF, 0);

    /* create the pipe and redirect stdout and stderr */
    pipe(pfd);
    dup2(pfd[1], 1);
    dup2(pfd[1], 2);

    /* spawn the logging thread */
    if(pthread_create(&thr, 0, thread_func, 0) == -1)
        return -1;
    pthread_detach(thr);
    return 0;
}

static void *thread_func(void*)
{
    ssize_t rdsz;
    char buf[128];
    while((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
        if(buf[rdsz - 1] == '\n') --rdsz;
        buf[rdsz] = 0;  /* add null-terminator */
        __android_log_write(ANDROID_LOG_DEBUG, tag, buf);
    }
    return 0;
}

Esto implica escribir y/o modificar código.

Existe un enfoque anticuado que aún puede funcionar para algunos emuladores de versiones anteriores de Android (no lo he probado) que se analiza en un artículo hermano sobre Stack Overflow:https://stackoverflow.com/questions/10531050/redirect-stdout-to-logcat-in-android-ndkNo creo que sea sensato intentar reproducir aquí la discusión de esas preguntas y respuestas, especialmente porque las opciones dependen de varios factores discutidos en ese tema. Actualice este tema una vez que haya progresado.

información relacionada