Redirect stdout to logcat in Android NDK

前端 未结 6 960
遇见更好的自我
遇见更好的自我 2020-12-08 19:53

I can\'t get my Nexus S (running Android 4.0) to redirect native stdout message to logcat. I\'ve read that I need to do this:

$ adb shell stop
$ adb shell se         


        
相关标签:
6条回答
  • 2020-12-08 20:00

    stdout/stderr are redirected to /dev/null in Android apps. The setprop workaround is a hack for rooted devices that copies stdout/stderr to the log. See Android Native Code Debugging.

    0 讨论(0)
  • 2020-12-08 20:09

    You should also be able to wrap your logging code to detect if it's Android and if so use Android's logging. This may or may not be practical for everyone.

    Include the logging header file:

    #include <android/log.h>

    Use the built in logging functionality:

    __android_log_print(ANDROID_LOG_INFO, "foo", "Error: %s", foobar);

    0 讨论(0)
  • 2020-12-08 20:12

    This was not obvious to me from the previous answers. Even on rooted devices you need to run:

    adb root
    adb shell stop
    adb shell setprop log.redirect-stdio true
    adb shell start
    
    0 讨论(0)
  • 2020-12-08 20:21

    setprop log.redirect-stdio true redirects only output generated by java code, but not the native code. This fact is described on developer.android.com in following way:

    By default, the Android system sends stdout and stderr (System.out and System.err) output to /dev/null. In processes that run the Dalvik VM, you can have the system write a copy of the output to the log file.

    To get output from the native code, I really liked this solution

    0 讨论(0)
  • 2020-12-08 20:26

    Here the code I use to to output stdout and stderr to android log

    #include <android/log.h>
    #include <pthread.h>
    #include <unistd.h>
    
    static int pfd[2];
    static pthread_t loggingThread;
    static const char *LOG_TAG = "YOU APP LOG TAG";
    
    static void *loggingFunction(void*) {
        ssize_t readSize;
        char buf[128];
    
        while((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
            if(buf[readSize - 1] == '\n') {
                --readSize;
            }
    
            buf[readSize] = 0;  // add null-terminator
    
            __android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, buf); // Set any log level you want
        }
    
        return 0;
    }
    
    static int runLoggingThread() { // run this function to redirect your output to android log
        setvbuf(stdout, 0, _IOLBF, 0); // make stdout line-buffered
        setvbuf(stderr, 0, _IONBF, 0); // make stderr unbuffered
    
        /* 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(&loggingThread, 0, loggingFunction, 0) == -1) {
            return -1;
        }
    
        pthread_detach(loggingThread);
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-08 20:26

    Try putting fflush(stdout); after your printf. Or alternatively use fprintf(stderr, "This message comes from C (JNI).\n");

    stdout by default is buffering. stderr - is not. And you are using System.err, not System.out from Java.

    Also you can disable stdout buffering with this: setvbuf(stdout, NULL, _IONBF, 0); Just make sure you call it before first printf call.

    0 讨论(0)
提交回复
热议问题