I am using https://www.youtube.com/watch?v=kjsC-lKUgM8 tutorial to try to debug a simple NDK app. I have done everything as it is in the video except:
android:debuggable=true
(cause eclipse considers it as error) in AndroidManifest.xml instead I have set the NDK path from Preferences->Android->NDK
and in Project Properties -> C/C++ Build
unchecked Use default build command
and set there ndk-build NDK_DEBUG=1 APP_OPTIM=debug
.x86 emulator
but Samsung Duos S
device with Android 4.0.4
But the breakpoiin that is used in the video in not being hit in my case. I am trying to debug a simple NDK test project already the 4th day. Have investigated lots of material:
But can not hit a single damn breakpoint. Please help if you could do this ever.
The following is an excerpt from an tutorial I wrote for our internal Android development team. The bulk of which was derived from this blog: http://mhandroid.wordpress.com/
Important notes:
Open AndroidManifest.xml, select the Application tab, and set
Debuggable=true
. This will make the application debuggable even when it's running on a device that's running in user mode. 4. Build the Native Sources. From the Terminal, enter the project directory and enter:
ndk-build -B
You should see the following output:
Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
Compile++ thumb : DebuggingTestJNI <= com_sample_test_DebuggingTestActivity.cpp StaticLibrary : libstdc++.a
SharedLibrary : libDebuggingTestJNI.so
Install : libDebuggingTestJNI.so => libs/armeabi/libDebuggingTestJNI.so
- In the Eclipse toolbar, you'll see a green bug. Click the little arrow next to the bug and select "Debug Configurations…".
- Double-click "Android Application" in the tree structure on the left. This will create a template for a new Android Application Debug Configuration.
- In the "Name:" field, name it "DebuggingTest Java Debug" to make sure you know this Configuration applies specifically to the DebuggingTest project, and targets your Java source.
- Under "Project:", click the "Browse…" button and select DebuggingTest.
- Click "Apply" to save your changes.
- Click "Close".
- In the Eclipse toolbar, click the little arrow next to the bug and select "Organize Favorites…".
- Click "Add…"
- Select "DebuggingTest Java Debug" and click "OK".
Your new debug configuration has now been created and added to your favorites. You can access your favorites by clicking the little arrow next to the bug in the toolbar. "DebuggingTest Java Debug" should be at the top of the list.
In the Eclipse toolbar, click the little arrow next to the bug and select "DebuggingTest Java Debug". This will deploy and install the DebuggingTest.apk to your connected Android device and start the debugger.
Navigate to the DebuggingTest project directory in your Terminal and type the following:
ndk-gdb
If the command succeeds, you should see the following:
GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "--host=x86_64-linux-gnu --target=arm-elf-linux". (no debugging symbols found) …
If you forgot to start debugging the application before this step, you get the following:
ERROR: Could not extract PID of application on device/emulator. Are you sure the application is already started? Consider using --start or --launch= if not. If your Android.mk file is malformed or contains $(info) blocks, you get the following: cp: target
./obj/local/armeabi/gdb.setup' is not a directory /home/Dev/NDK/ndk-gdb: 639: cannot create start DebuggingTest/jni/Android.mk end DebuggingTest/jni/Android.mk ./obj/local/armeabi/gdb.setup: Directory nonexistent /home/Dev/NDK/ndk-gdb: 640: cannot create start DebuggingTest/jni/Android.mk end DebuggingTest/jni/Android.mk ./obj/local/armeabi/gdb.setup: Directory nonexistent start: invalid option: -x Try
start --help' for more information.
If ndk-gdb is already running, you get the following:
ERROR: Another debug session running, Use --force to kill it.
Resolve your ERRORs before continuing. ndk-gdb MUST run successfully.
Running ndk-gdb
does not only ensure us that we are doing everything right so far, but also creates app_process
, gdb.setup
and libc.so
files in the obj/local/armeabi/ sub-directory of our project. Those files will be needed in later steps.
- In your Terminal, type CTRL+Z to stop ndk-gdb.
- In Eclipse, select Run → Terminate. 4. Create C/C++ Debug Configuration. We need to create a debug configuration for stepping into C/C++ source code.
- In Eclipse, click the little arrow next to the bug and select "Debug Configurations…".
- Double-click "C/C++ Application" in the tree structure on the left. This will create a template for a new C/C++ Application Debug Configuration.
- In the "Name:" field, name it "DebuggingTest C and CPP Debug" to make sure you know this Configuration applies specifically to the DebuggingTest project, and targets your C/C++ source.
- In the "Main" tab:
- Click "Browse…" on the "C/C++ Application:" field. Navigate to "/home/Test/testing/DebuggingTest/obj/local/armeabi/app_process" and click "OK".
- Click "Browse…" on the "Project:" field.
- Select "DebuggingTest" and click "OK".
- Check the "Disable auto build" box.
- At the bottom of the form, you'll see "Using GDB (DSF) … - Select other…". Press the "Select other…" button.
- In the pop-up, check the "Use configuration specific settings" box.
- Select "Standard Create Process Launcher" in the list and press "OK".
- In the "Debugger" tab:
- Click the combo-box on the "Debugger:" field and select "gdbserver".
- Uncheck the "Stop on startup at:" box.
- In the "Main" sub-tab:
- Click "Browse…" on the "GDB debugger:" field.
- Navigate to "/home/Dev/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb" and click "OK". This debugger is distributed with the Android NDK.
- In the "GDB command file:" field, type "/home/Test/testing/DebuggingTest/obj/local/armeabi/gdb2.setup". The gdb2.setup file does not exist yet, but we'll create it shortly.
- Check the "Use full file path to set breakpoints" box.
- In the "Connection" sub-tab:
- Set "Type:" to TCP
- Set "Port number:" to 5039
- Click "Apply" to save your changes.
- Click "Close"
- In the Eclipse toolbar, click the little arrow next to the bug and select "Organize Favorites…".
- Click "Add…"
- Select "DebuggingTest C and CPP Debug" and click "OK".
Your new debug configuration has now been created and added to your favorites. You can access your favorites by clicking the little arrow next to the bug in the toolbar. "DebuggingTest C and CPP Debug" should be at the top of the list.
- In your File Explorer, navigate to "/home/Test/testing/DebuggingTest/obj/local/armeabi/".
- Copy the "gdb.setup" file and then paste it into the same folder. The result should be a file named "gdb (copy).setup".
- Rename "gdb (copy).setup" to "gdb2.setup".
- Open gdb2.setup by double-clicking the file.
- Replace "set solib-search-path ./obj/local/armeabi" with "set solib-search-path /home/Test/testing/DebuggingTest/obj/local/armeabi".
- Replace "file ./obj/local/armeabi/app_process" with "file /home/Test/testing/DebuggingTest/obj/local/armeabi/app_process".
- Remove the line that reads "target remote :5039".
- Save and Close the file. 5. Create ndk-gdb-eclipse. One last Eclipse housekeeping item. Eclipse will run the gdb binary itself, so we have to remove the execution of gdb from ndk-gdb. We'll save the original content by doing another Copy-Paste-Rename.
- In your File Explorer, navigate to "/home/Dev/NDK".
- Copy the "ndk-gdb" file and then paste it into the same folder. The result should be a file named "ndk-gdb (copy)".
- Rename "ndk-gdb (copy)" to "ndk-gdb-eclipse".
- Open ndk-gdb-eclipse by doing a right-click → Open With Other Application …
- Select Text Editor from the list of applications
- In the file, locate the line that reads "$GDBCLIENT -x
native_path $GDBSETUP
" (probably at the very bottom) and comment it out by prefixing it with a "#" character.- Save and Close the file.
When Debugging native sources within the Eclipse IDE, we'll use ndk-gdb-eclipse
instead of ndk-gdb
.
- Put a breakpoint in the DebuggingTestActivity.java file at line 20 (System.out.println("hello world!")).
- Insert a breakpoint in your main Activity BEFORE any calls into native code are made. onCreate() is generally the best place for this.
- Start the DebuggingTest application in Debug mode by clicking on the little arrow next to the bug and selecting "DebuggingTest Java Debug".
- You'll see a pop-up on the screen labeled "Confirm Perspective Switch". Press "Yes" if you'd like it to switch to your Debug Perspective. I would recommend doing so.
- At this point, you should have hit the breakpoint you set.
Warning: The breakpoint we just hit sits inside of the onCreate
function. This function will be called AFTER all static loadLibrary
calls have been made. Notice that outside of the onCreate function there is a System.loadLibrary("DebuggingTestJNI")
inside of a static block. This loadLibrary call will execute before we enter our onCreate
function, ensuring that our native symbols are loaded by the time we hit our initial breakpoint. It is imperative that we are stopped at a breakpoint before proceeding!
- In your Terminal, navigate to the DebuggingTest directory and type the following command:
ndk-gdb-eclipse
← Remember that we created this file back in step 6- If successful, the command should complete without any response.
- Go back to Eclipse and run your C/C++ debugger by clicking the little arrow next to the bug and selecting "DebuggingTest C and CPP Debug"
- Note: When I do this, I see dozens of errors in my Eclipse console, but things still seem to be working…
- Switch back to your Java Perspective.
- Click the double arrows at the top right of right of your Eclipse window and select Java.
- Open DebuggingTest/jni/com_sample_test_DebuggingTestActivity.cpp
- Set a breakpoint in the first JNI function that will be called by your main Activity.
- Click Run → Resume (F8)
- You'll get the Perspective Switch message again, so feel free to switch back to the Debug Perspective.
You should have just hit the breakpoint we just set in the native code!
Congratulations!!!
At this point you should be able to take what you've learned and adapt it to existing projects you may have.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With