Geeks With Blogs
Timo Heinäpurola

Our engine is written in almost pure C++ with some part in C# that run on Mono. The code base is huge which mans that we’re primarily looking for platforms that support C++ development. Looking at the current set of platforms on the market this is really not a big issue with Windows Phone being the only platform that does currently not support native development. Sadly this means that we’re currently not planning a Windows Phone release in the near future.

Looking at other platforms, about a year ago Android was not really an option for us at Raccoon Interactive. It seemed like a ragtag platform with only Java support. Not only was there almost no good support for C++ development but the Java run-time was/is very slow to say the least. The Android NDK now provides support for native development and builds on the SDK which contains all the basic tools like the emulator and the Android Debug Bridge (ADB). That and the fact the Android is quickly gaining momentum meant that we’d just found our first platform.

We’re not quite there yet with the Android version of our engine but I thought I’d give you some insight on the intricacies of actually developing for that platform while maintaining our productivity (read: continue using Visual Studio). I’ll most likely be posting more about Android development as the port progresses, but today I’m going to focus on debugging.

To start with, we use vs-android instead of the NDK build pipeline, which means that there’s no need for Cygwin and we’re able to build our engine from within Visual Studio in the same way we build our Windows version. vs-android consists of a set of MSBuild targets that execute the compiler and linker commands provided by the NDK. The targets also include steps for packaging and deploying the native application.

Another method for building Android native applications from within Visual Studio is WinGDB that has one huge advantage over vs-android: you can actually debug the application remotely within Visual Studio! At this point you might be asking “Why use vs-android then?” There’s actually a simple answer to this. WinGDB requires you to create a new project instead of just adding a build setup for the already existing project. I was also not able to link my library, that is loaded by the native activity, with another library. This was crucial for us because we have multiple libraries that form the whole engine and it’s out of the question to pack everything into a single library.

All this means that when we wish to build and test our engine on Android, this is pretty much what we do:

  • Develop normally within Visual Studio.
  • Build the project for the Android build target.
  • Deploy the APK onto the phone (this can be done automatically by setting the vs-android Ant build to handle the deployment).
  • Launch the application on the phone/emulator.
  • Manually set up the GDB server on the phone/emulator and the GDB client on the Windows host to communicate with each other.
  • Debug the application.

There are some pit falls when setting up a debugging session, however. First of all, you can’t use the ndk-gdb script that comes with the Android NDK because we don’t have a makefile project to start with, which the script uses to set up the debug session. Also because we don’t use the typical ndk-build script for building the makefile project (which we don’t have) we don’t get the gdbserver application deployed onto with the APK by default.

All this means hat setting up the debugging session becomes somewhat tricky. First of all you have to deploy the gdbserver application with the APK. The way we solved this was copying it to the libs folder that also contains the libraries built by vs-android. The libs folder is not cleared during building so the application stays there when we put it there. This way gdbserver will be found under the folder /data/data/com.ri.MyAndroidApplication/lib with the correct user access rights associated with it. The correct gdbserver executable can be found under NDK_PATH/toolchains/arm-linux-androideabi-4.4.3/prebuilt.

The second part is setting up TCP forwarding from the phone to your PC. This happens by running the following command (note that I expect <ANDROID_SDK>\platform-tools to be in your PATH environment variable).

adb forward tcp:1234 localfilesystem:/data/data/com.ri.MyAndroidApplication/debug-pipe

The command redirects TCP connections to localhost:1234 on the PC to the named pipe on the Android system. We then configure the GDB server to listen to debug-pipe on the emulator/phone. This happens by executing the following command on the emulator/phone. First you have to determine the application process ID (pid). This can be done by executing “adb shell ps” and looking up the correct process (com.ri.MyAndroidApplication in our case).

adb shell run-as com.ri.MyAndroidApplication
/data/data/com.ri.MyAndroidApplication/lib/gdbserver +debug-pipe
--attach <process-pid>

The run-as command executes the application as the user that also runs the application com.ri.MyAndroidApplication. This is kinda neat since Android runs all applications under different user accounts to protect your phone from malicious users. The run-as command will look up the user that would run the application and then run the application with he correct user rights.

So, now we have the server running. But like with all servers in the world, you also need a client for any of this to be meaningful. The Android NDK comes with a GDB client that you’re supposed to use. This client can be found under “<NDK_PATH>/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin” and is called arm-linux-androideabi-gdb.exe.

We will actually be debugging a process named app_process that resides on the emulator/phone. This executable has to be pulled from the emulator/phone so we can inspect it for symbols. We also need to pull the correct libc.so version so the debugger can be correctly setup. To perform these steps execute the following commands in a new command prompt.

adb pull /system/bin/app_process app_process
adb pull /system/lib/libc.so libc.so

Great, let’s get to the actual beef, connecting to the GDB server. Run the GDB client executable inside the command prompt and execute the following commands.

(gdb) set solib-search-path <NDK_PATH>/platforms/android-9/arch-arm/usr/lib
(gdb) directory <NDK_PATH>/platforms/android-9/arch-arm/usr/include;
<NDK_PATH>/sources/cxx-stl/system
(gdb) file app_process (gdb) target remote :1234

At this point you should have successfully connected to the the GDB server and should be able to work with the debugger. I’m not going to go into detail about GDB commands but a few handy ones are b (breakpoing), c (continue), step, next and info threads (listing threads when developing a multithreaded application).

GDB is actually quite handy once you get over the shock of not having a GUI. But hey, real programmers only need their keyboard Silmänisku

Posted on Monday, September 12, 2011 3:49 PM | Back to top


Comments on this post: Working with Android on Windows and without Cygwin

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © raccoon_tim | Powered by: GeeksWithBlogs.net