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
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.
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);
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
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
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;
}
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.