I have an Android application using multiple native pthreads which I need to debug. The only sensible option I see is using android-ndk-profiler, which is based on gprof. However, gprof is known to not work properly with multithreading. Gladly, there is a work-around by Sam Hocevar available that wraps pthreads to allow gprof proper profiling on multi-threading applications.
Now, they suggest to use LD_PRELOAD to load the libgprofhelper.so before the library-to-profile. This does not work for me.
I decided to go with a very simple test, where I have one function in my library-to-profile, call it libtoProfile.so:
void printDummy()
{
__android_log_print(ANDROID_LOG_FATAL, "SomeTag", "Hello World!");
}
I compile this for armeabi-v7a with the Android NDK r10d. objdump -T libtoProfile.so | grep printDummy says
00113cf9 g DF .text 0000001c printDummy
file libtoProfile.so says
libavNative.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped
Now I create my library libgprofhelper.so, which should shadow the printDummy()-function in libtoProfile.so. It has very similar code:
void printDummy()
{
__android_log_print(ANDROID_LOG_FATAL, "SomeTag", "Successfully overshadowed!");
}
It is built with exactly the same settings / flags / compilers and for the same architecture (armeabi-v7a).
libgprofhelper.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped
objdump -T libgprofhelper.so | grep printDummy
00000c39 g DF .text 00000018 printDummy
So far, this seems fine for me.
I have a rooted HTC One M7 running Android 4.4.2. I use adb push libgprofhelper.so /data/libgprofhelper.so to get the library on my device.
I then manually install the application using libtoProfile.so, which has package name av.profiling.
I then issue
root@m7:/ # setprop wrap.av.profiling "LD_PRELOAD=/data/libgprofhelper.so"
which creates the following entry
130|root@m7:/ # getprop | grep profiling
[wrap.av.profiling]: [LD_PRELOAD=/data/libgprofhelper.so]
However, when I start my app (via Launcher or via am start -n ...) I cannot see any sign in logcat that it tries to load libgprofhelper.so, neither is the desired output there. The app just says "Hello World!", which means the LD_PRELOAD has no effect at all.
Does anybody know if LD_PRELOAD works as desired on Android 4.4.2 or are there any different ways to trace where my error is? Of course, alternative ways to profile CPU-usage of multi native threads are welcome as well.