Well, I am once again confronted with debugging heavily multi threaded C++ applications in Android 2.2. Now it is NDK5(b) and NOT NDK4 as in previous posts. I have seen on the readme of NDK5 that in Android 2.3+, the multi-threaded debugging problem has gone away completely but unfortunately we MUST stick with the 2.2 platform for now.
After move to NDK5, we decided to use the CMake for doing Android builds as it allows us to get one build system for a lot of cross platform (not Android only) components. Unfortunately, this way of building does not give me the possibility to debug application using ndk-gdb. So I had to write my own awkward scripts to ease the debugging process. Now please welcome the complete solution for gdb:
- Get the gdbserver from the Android sources as described in my previous post “Yes I Can Debug Multi-threaded C++ JNI Code on Android“.
- Upload this gdbserver to the running emulator by typing adb push host/path/to/gdbserver /data/gdbserver in your command prompt.
- Get the system libraries from the emulator to path/to/your/project/obj/local/armeabi folder by typing adb pull /system/lib path/to/your/project/obj/local/armeabi.
- Get the Dalvik Virtual Machine app_process binary from the emulator to path/to/your/project/obj/local/armeabi folder by typing adb pull /system/bin/app_process path/to/your/project/obj/local/armeabi.
- Forward the ports with the help of adb by typing adb forward tcp:1234 tcp:1234 in the command prompt.
- Find the PID of the process you wish to attach to (I debug using attaching… never tried to debug starting of the process, fill free to comment if you know how).
- Attach the gdbserver to the running process by typing adb shell /data/gdbserver tcp:1234 --attach PID. Leave the command prompt where you typed it running and open another one.
- Type /path/to/ndk5/build/prebuilt/linux-x86/arm-linux-androideabi-4.4.3/bin/arm-linux-androideabi-gdb path/to/your/project/obj/local/armeabi/app_process --command=path/to/your/project/obj/local/armeabi/gdb.setup. The gdb starts and breaks waiting for the instructions, type target remote tcp:1234. Press Enter.
And DADA! Yes, you are able to see the threads, switch between them, see there call stacks and do other much more important things that doing this stupid manual setup… brr, please feel free to correct me if I am wrong.