8

in my Android app I use a native c++ library via JNI. This library produces log lines, if its build in debug mode. I want to have the log lines redirected to logcat.

So I created the lib in debug mode, NDK_DEBUG=1 is used and LOCAL_LDLIBS += -llog is set.

My devices is not rooted but I set:

$ adb shell stop $ adb shell setprop log.redirect-stdio true $ adb shell start

Like it was described at http://developer.android.com/tools/debugging/debugging-log.html#viewingStd and here Is "std::cout" usable in Android-ndk

Using __android_log_print(ANDROID_LOG_INFO, "foo", "Error: %s", foobar); is working but it is not an option for me because the c++ lib is also used for an iOS app so I dont want to change the native code.

I also tried to get the console output (printf) created in the JNI wrapper with this settings but except the "__android_log_print" statements the output is not visble a logcat too.

Did I missed something or is the redirection only possible for rooted devices?

How can I get the console output produced by native code.

Thank You in Advance

Community
  • 1
  • 1
Isnogod
  • 105
  • 1
  • 7

2 Answers2

17

I use a logger header to print crossplatform logs.

In c++ code just write LOGD("msg"); or LOGE("msg"); and print messages checking the platform.

Try creating a crossplatform log header like:

Logs.h

#       ifdef ANDROID
            // LOGS ANDROID
#           include <android/log.h>
#           define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,__VA_ARGS__)
#           define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG  , LOG_TAG,__VA_ARGS__)
#           define LOGI(...) __android_log_print(ANDROID_LOG_INFO   , LOG_TAG,__VA_ARGS__)
#           define LOGW(...) __android_log_print(ANDROID_LOG_WARN   , LOG_TAG,__VA_ARGS__)
#           define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , LOG_TAG,__VA_ARGS__)
#           define LOGSIMPLE(...)
#       else
            // LOGS NO ANDROID
#           include <stdio.h>
#           define LOGV(...) printf("  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGD(...) printf("  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGI(...) printf("  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGW(...) printf("  * Warning: "); printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGE(...) printf("  *** Error:  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGSIMPLE(...) printf(" ");printf(__VA_ARGS__);
#       endif // ANDROID
vgonisanz
  • 11,831
  • 13
  • 78
  • 130
  • 1
    Yeah thanks @Piperoman ! Without rooting the device I did now your approach this seams to be the only way. I added a precompiler definition. The important point is that I had to use: `#define LOGV(FMT, ...) __android_log_vprint(ANDROID_LOG_VERBOSE, LOG_TAG, FMT, __VA_ARGS__)` Without **vprint** the args are not parsed correctly. – Isnogod Jun 24 '14 at 07:28
5

If your device is not rooted, the adb shell stop / start commands will have no effect. That means zygote won't restart, so it won't pick up the new log.redirect-stdio property. This property is something of a hack anyway -- it causes a VM in the same process to create a thread that reads stdout/stderr and forwards them to the log file.

Your best bet is to use a variadic log macro that switches between __android_log_print and whatever iOS wants based on a preprocessor symbol (e.g. __ANDROID__). Then it'll just compile to the right thing.

Community
  • 1
  • 1
fadden
  • 51,356
  • 5
  • 116
  • 166