Native code (C++) debugging?

Hi,

I'm developing an application that has a significant part of it's business logic in C++ (ported from Windows Mobile). This component requires Bluetooth integration (easiest to to back up in the C# world then pass data down to the native layer). It's run as part a MonoDroid application.

I've been looking round for documentation on how to debug the Native side of the app but have not found too much. There is stuff on debugging native code when running a Java app (and it's very fiddly). The requirement of this component to talk to a Bluetooth SPP makes things trickier as the Bluetooth API in native C++ on Android is not standard or always provided (as far as I understand).

Any thought's on how this can be done? If it can be done? easily?

Cheers,
Joffa.

Best Answer

Answers

  • Hi Jon,

    Thanks, I will try this as see how I go. If I get something working I'll post it up for others.

    Cheers, Joffa.

  • LiamLiam USMember

    Did you get anywhere with this Joffa?

    I am trying to debug a Xamarin.Android application that leverages a native shared library compiled with a standalone ndk-r8e toolchain.

    The main problem I'm having is to get the gdbserver launched on the physical device. As it is not a rooted device, I'm not able to simply adb push the binary up and run it by hand as I run into permissions issues.

    Is there anyway to get Xamarin to launch this for me?

    Thanks,

  • GeoffAldridge.9490GeoffAldridge.9490 AUMember

    Hi Liam,

    Sadly I haven't got this working. Having said that, I left this process for a while and have not come back to working on it again. I do believe that to get some of this working you will probably need to have a rooted device.

    I have not explored running this from the Xamarin tools.

    Cheers, Joffa.

  • JonathanPryorJonathanPryor Xamurai USXamarin Team Xamurai

    Is there anyway to get Xamarin to launch this for me?

    Entirely untested, but an idea that has occurred to me is to copy gdbclient to e.g. libgdbclient.so, then add libgdbclient.so to your project as libs\armeabi-v7a\libgdbclient.so with a Build action of AndroidNativeLibrary (change the ABI as appropriate).

    This will prompt Android to extract libgdbclient.so into your app's lib directory, e.g. /data/data/@[email protected]/lib/libgdbclient.so will exist. Furthermore, it should be executable, meaning that you should be able to execute it via adb shell.

    Again, entirely untested, but the minimal testing I've done suggests that this should work...

  • LiamLiam USMember

    Jonathan,

    I had that exact same thought earlier today! Unfortunately I had it 10 minutes before I had to leave the office so whilst I did manage to get a gdbserver running on the Android device, I wasn't able to connect to it from a client running on my desktop.

    I will have another shot at it tomorrow morning (I'm on GMT here). If I do get it to work I'll post an example.

  • JonathanPryorJonathanPryor Xamurai USXamarin Team Xamurai

    If I do get it to work I'll post an example.

    Excellent. That's something I've been wanting to do for awhile, but haven't had a chance to actually do yet. Knowing how it would actually work would allow me to more easily integrate that into the build system.

  • LiamLiam USMember

    Jonathan,

    I was able to get the gdbserver running running on a Nexus 7 and after a little bit of work even get a gdb client on my desktop to talk to that gdbserver without having communications errors. However I was not able to get the gdb client to read debugger symbols and therefore was unable to do anything useful with the connection, like set a breakpoint or even do a backtrace.

    For my own sanity I'm going to put this on the back burner for this week, I'll likely pick it up again next week. If you'd like any of the project files I'm currently using just let me know and I'll put them somewhere visible, otherwise I'll assume you're only interested in a fully working set =)

    Liam

  • a54110a54110 RUMember

    You can use gdb. http://igor-konyshev.blogspot.ru/2013/05/native-monoandroid.html Text is in Russian but the pictures are well describe the process.

  • GeoffAldridge.9490GeoffAldridge.9490 AUMember

    Hi Igor,

    We've not got back to a position where we can try this for real in our app. But will be trying again in a month or so.

    Thanks for the additional details.

    Thanks, Joffa.

  • FlorianGiraultFlorianGirault ✭✭ JPMember ✭✭
    edited June 2013

    EDIT:
    Finally it seems to be working!
    I just forgot to enter the command "Continue" before my native code was called.
    So in gdb I did:
    set solib-search-path path/to/mylibrary
    break MyFunction
    continue

    And my breakpoint was hit!

    Now I will try to connect from eclipse instead of using the command line.

    Hi!
    Is there anymore information on this? By following the link I was able to connect a gdb session to the android process, but it crashes when I want to debug. Here are the steps I followed:
    1. Create a native lib, and a Xamarin app that calls the native lib
    2. Make sure that the native lib is compiled in DEBUG mode (so that gdbserver is copied in the libs folder)
    3. Start the application on the device from visual studio
    4. In Cygwin: cd {XamarinProjectFolder}\obj\Debug\android
    5. Still in cygwin: ndk-gdb

    By doing this, I get a gdb session to the application. Then by using "set solib-search-path", and "i sha" I can see that my shared library is loaded. Then I can set a breakpoint somewhere. But then, when the native code executes I get (gdb) Cannot access memory at address 0x10 But if I try without opening a gdb session the app works properly (and the code is very simple - helloworld level, so I am sure it is not a bug) Is there something else that should be configured?
  • FlorianGiraultFlorianGirault ✭✭ JPMember ✭✭

    It doesn't work anymore!
    After this post I tried to do it with eclipse, without success, and retried without eclipse to compare, and now I am back having errors like "cannot access memory at address 0x10".
    There must be something that i did before that enabled the breakpoint to be hit...
    But anyway even if it finds my .so file, why isn't gdb able to read the debug symbols from it???

    I'll post again if I can understand what I missed...

  • FlorianGiraultFlorianGirault ✭✭ JPMember ✭✭
    edited June 2013

    Ok, I am able to get gdb working again from the command line.
    But for some reason I get some "bad system call" error if I don't run the native code in the appli, in the same way as it is run when debugging later.
    It is very strange.
    If I get "bad system call" and just do quit in gdb, then the application goes back to normal...
    I think it is very unstable...
    Also even if it works in some particular case, I don't know how to make it loads the debug symbols.
    If I check the sharedlibrary info, I can see "Shared library is missing debugging information" but it is compiled with the -g flag!
    I really don't understand. It is much easier to get this working with Java/JNI.

  • FlorianGiraultFlorianGirault ✭✭ JPMember ✭✭
    edited June 2013

    Getting closer:
    By generating a separate symbol file from the library ( native.so.sym ), now from the command line gdb is able to load the symbols.
    Still no luck with eclipse though...

    NOTE: separate symbol file is generated with the "arm-linux-androideabi-objcopy" command of the ndk under {NDK_ROOT}\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin

  • FlorianGiraultFlorianGirault ✭✭ JPMember ✭✭
    edited June 2013

    OK I managed to get it working with eclipse now, and source support. I think I got almost same features as for usual android jni debugging: I can set breakpoints in source, see the disassembly and check the value of variables in the disassembly window.
    I'm not 100% sure of the procedure, but the keys are:
    1) Basically we need to follow the procedure described here by Martin Hejna to be able to connect to the already running application (you should read it first):
    mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-debugging/

    2) The difference is that you have to additionally (note that I am working on windows):

    • create an android application with your native code from eclipse (I named the package with the same name as generated by xamarin.android, but I don't know if that was necessary)
    • put your native code in the jni folder as for normal android app
    • let the java source folder (src) empty
    • include the <jni.h> header somewhere in your native code (I'm not sure it's necessary, but it seemed that by doing that ndk-gdb was generating the app_process that I needed?)
    • Add something similar to the following at the end of the ANDROID.MK file, to generate symbol file during build, and put it in next to the library you want to debug:
      LOCAL_MODULE_FILE := $(LOCAL_PATH)/../libs/armeabi-v7a/$(notdir $(LOCAL_BUILT_MODULE))
      LOCAL_SYM_FILE := $(LOCAL_MODULE_FILE).sym
      all: $(LOCAL_SYM_FILE)
      $(LOCAL_SYM_FILE) : $(LOCAL_MODULE_FILE)
      C:\Android\ndk\android-ndk-r8d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-objcopy $(LOCAL_MODULE_FILE) $(LOCAL_SYM_FILE)

    • Build, then use cygwin to use "ndk-gdb" command once on the project. This should create an "obj" folder. You should be able to see app_process, linker and your binary under obj/local/armeabi or similar. Note that you have to launch the application on the device to connect with ndk-gdb. Then you can quit the debug session.

    • setup the remote debugging in eclipse with parameters:
      Main > c/c++ application: ./obj/local/armeabi-v7a/app_process
      Main > Project:
      Debugger > Uncheck "Stop on startup at"
      Debugger > Main > GDB debugger: C:\Android\ndk\android-ndk-r8d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-gdb
      Debugger > Main > GDB command file: obj\local\armeabi-v7a\gdb2.setup (NOTE: windows style path is important here!)
      Debugger > Shared Libraries: obj\local\armeabi-v7a (NOTE: again windows-style path)

    • Then use Martin Hejna's ndk-gdb-eclipse script to start the gdb server, and connect the client from eclipse.

    That worked for me.
    I will post a proper guide somewhere else (maybe on Stack Overflow) when I have more time.

  • LarryGugerLarryGuger USMember

    Hi All,

    I am from the Microsoft C++ team and we are very interested in talking to developers that are incorporating C++ libraries into their Xamarin apps. If you are doing that I would be very excited if you would reach out to me directly. My email alias is larrygug. The domain is microsoft.com. :-)

    Larry

Sign In or Register to comment.