*EDIT June 2020: Unbelievably I came to my own (3 year old) question here from google after trying to help a coworker debug native code in our app on his new mac. AndroidStudio 4.0 with Gradle 6 and debugging native code is still something like sorcery! We have 3 developers, only 1 machine is this working. Same code base, same version of AndroidStudio, all 3 running Catalina. I'm just baffled.
EDIT: This is still unresolved. I suspected based on the comments that my use of an old NDK (10d) might be a problem so I upgraded to 15c and dealt with all the issues to get my stuff to compile with clang and the new c++ library. Unfortunately ndk-gdb is broken in 15c and my attempts to hack the python to make it work didn't get me anywhere. I then used Android Studio 3.0 preview and I'm back to where I was before - I can see stack information but all the code is assembly in lldb. Work must go on - I am back to using logcat for debugging :(
I come to you with a bruised forehead from numerous hits on the wall.
I'll try to be concise and provide all relevant information at the same time. If there is any relevant info I haven't included please let me know.
Synopsis:
I am maintaining an Android app as part of my job. I have had to resort to logging to debug native code because although I can set breakpoints and hit them, I can't view the source or variable information.
I've spent many hours and google searches trying to understand what I'm missing, yet still no luck.
My build environment is OSX using Android NDK r10D, and gradle 3.2 to build the APK.
I'm trying to use AndroidStudio 3.0 beta 6 to install and debug the APK.
My Android.manifest includes in the tag:
android:debuggable="true"
Native Code:
This is sample output from compiling one of the native c++ files with -v for verbosity:
~/src/libraries/cBase$ make android
Building obj/Binary.ao
Using built-in specs.
COLLECT_GCC=arm-linux-androideabi-g++
Target: arm-linux-androideabi
Configured with: /s/ndk-toolchain/src/build/../gcc/gcc-4.8/configure --prefix=/tmp/ndk-User/build/toolchain/prefix --target=arm-linux-androideabi --host=x86_64-apple-darwin --build=x86_64-apple-darwin --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --with-gmp=/tmp/ndk-User/build/toolchain/temp-install --with-mpfr=/tmp/ndk-User/build/toolchain/temp-install --with-mpc=/tmp/ndk-User/build/toolchain/temp-install --with-cloog=/tmp/ndk-User/build/toolchain/temp-install --with-isl=/tmp/ndk-User/build/toolchain/temp-install --with-ppl=/tmp/ndk-User/build/toolchain/temp-install --disable-ppl-version-check --disable-cloog-version-check --disable-isl-version-check --enable-cloog-backend=isl --with-host-libstdcxx='-static-libgcc -lstdc++ -lm' --disable-libssp --enable-threads --disable-nls --disable-libmudflap --disable-libgomp --disable-libstdc__-v3 --disable-sjlj-exceptions --disable-shared --disable-tls --disable-libitm --with-float=soft --with-fpu=vfp --with-arch=armv5te --enable-target-optspace --enable-initfini-array --disable-nls --prefix=/tmp/ndk-User/build/toolchain/prefix --with-sysroot=/tmp/ndk-User/build/toolchain/prefix/sysroot --with-binutils-version=2.24 --with-mpfr-version=3.1.1 --with-mpc-version=1.0.1 --with-gmp-version=5.0.5 --with-gcc-version=4.8 --with-gdb-version=7.6 --with-python=/Users/User/mydroid/ndk/prebuilt/darwin-x86_64/bin/python-config.sh --with-gxx-include-dir=/tmp/ndk-User/build/toolchain/prefix/include/c++/4.8 --with-bugurl=http://source.android.com/source/report-bugs.html --enable-languages=c,c++ --disable-bootstrap --enable-plugins --enable-libgomp --disable-libsanitizer --enable-gold --enable-graphite=yes --with-cloog-version=0.18.0 --with-isl-version=0.11.1 --enable-eh-frame-hdr-for-static --with-arch=armv5te --program-transform-name='s&^&arm-linux-androideabi-&' --enable-gold=default
Thread model: posix
gcc version 4.8 (GCC)
COLLECT_GCC_OPTIONS='-Wextra' '-Wall' '-g' '-v' '-D' 'ANDROID' '-O0' '-g' '-c' '-MMD' '-MP' '-I' '/Users/spartygw/src/libraries' '-I' '/Users/spartygw/src/libraries/thirdparty' '-I' '/Users/spartygw/src/libraries/thirdparty/jpeg' '-I' '/Users/spartygw/src/libraries/thirdparty/zlib' '-I' '/Users/spartygw/src/include' '-I' '/Users/spartygw/android-toolchain/sysroot/usr/include' '-D' '__ARM_ARCH_5__' '-D' '__ARM_ARCH_5T__' '-D' '__ARM_ARCH_5E__' '-D' '__ARM_ARCH_5TE__' '-D' '__ANDROID__' '-D' 'DEBUG' '-o' 'obj/Binary.ao' '-march=armv5te' '-mfloat-abi=soft' '-mfpu=vfp' '-mtls-dialect=gnu'
/Users/spartygw/android-toolchain/bin/../libexec/gcc/arm-linux-androideabi/4.8/cc1plus -quiet -v -I /Users/spartygw/src/libraries -I /Users/spartygw/src/libraries/thirdparty -I /Users/spartygw/src/libraries/thirdparty/jpeg -I /Users/spartygw/src/libraries/thirdparty/zlib -I /Users/spartygw/src/include -I /Users/spartygw/android-toolchain/sysroot/usr/include -iprefix /Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/ -isysroot /Users/spartygw/android-toolchain/bin/../sysroot -MMD obj/Binary.d -MP -MQ obj/Binary.ao -D_GNU_SOURCE -D ANDROID -D __ARM_ARCH_5__ -D __ARM_ARCH_5T__ -D __ARM_ARCH_5E__ -D __ARM_ARCH_5TE__ -D __ANDROID__ -D DEBUG Binary.cc -mbionic -fpic -quiet -dumpbase Binary.cc -march=armv5te -mfloat-abi=soft -mfpu=vfp -mtls-dialect=gnu -auxbase-strip obj/Binary.ao -g -g -O0 -Wextra -Wall -version -fexceptions -frtti -o /var/folders/03/hpjtv8c969scgcc5121ybrwr0000gn/T//ccciFNCN.s
GNU C++ (GCC) version 4.8 (arm-linux-androideabi)
compiled by GNU C version 4.2.1 (Apple Inc. build 5666) (dot 3), GMP version 5.0.5, MPFR version 3.1.1, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/include"
ignoring nonexistent directory "/Users/spartygw/android-toolchain/bin/../lib/gcc/../../include/c++/4.8/backward"
ignoring duplicate directory "/Users/spartygw/android-toolchain/bin/../lib/gcc/../../lib/gcc/arm-linux-androideabi/4.8/include"
ignoring nonexistent directory "/Users/spartygw/android-toolchain/bin/../sysroot/usr/local/include"
ignoring duplicate directory "/Users/spartygw/android-toolchain/bin/../lib/gcc/../../lib/gcc/arm-linux-androideabi/4.8/include-fixed"
ignoring nonexistent directory "/Users/spartygw/android-toolchain/bin/../lib/gcc/../../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/include"
ignoring nonexistent directory "/Users/spartygw/src/include"
ignoring duplicate directory "/Users/spartygw/android-toolchain/sysroot/usr/include"
as it is a non-system directory that duplicates a system directory
#include "..." search starts here:
#include <...> search starts here:
/Users/spartygw/src/libraries
/Users/spartygw/src/libraries/thirdparty
/Users/spartygw/src/libraries/thirdparty/jpeg
/Users/spartygw/src/libraries/thirdparty/zlib
/Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/include
/Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/include-fixed
/Users/spartygw/android-toolchain/bin/../lib/gcc/../../include/c++/4.8
/Users/spartygw/android-toolchain/bin/../lib/gcc/../../include/c++/4.8/arm-linux-androideabi
/Users/spartygw/android-toolchain/bin/../sysroot/usr/include
End of search list.
GNU C++ (GCC) version 4.8 (arm-linux-androideabi)
compiled by GNU C version 4.2.1 (Apple Inc. build 5666) (dot 3), GMP version 5.0.5, MPFR version 3.1.1, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 7c7303e2f21bf352ab9993b8ba84df0b
^
COLLECT_GCC_OPTIONS='-Wextra' '-Wall' '-g' '-v' '-D' 'ANDROID' '-O0' '-g' '-c' '-MMD' '-MP' '-I' '/Users/spartygw/src/libraries' '-I' '/Users/spartygw/src/libraries/thirdparty' '-I' '/Users/spartygw/src/libraries/thirdparty/jpeg' '-I' '/Users/spartygw/src/libraries/thirdparty/zlib' '-I' '/Users/spartygw/src/include' '-I' '/Users/spartygw/android-toolchain/sysroot/usr/include' '-D' '__ARM_ARCH_5__' '-D' '__ARM_ARCH_5T__' '-D' '__ARM_ARCH_5E__' '-D' '__ARM_ARCH_5TE__' '-D' '__ANDROID__' '-D' 'DEBUG' '-o' 'obj/Binary.ao' '-march=armv5te' '-mfloat-abi=soft' '-mfpu=vfp' '-mtls-dialect=gnu'
/Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/as -v -I /Users/spartygw/src/libraries -I /Users/spartygw/src/libraries/thirdparty -I /Users/spartygw/src/libraries/thirdparty/jpeg -I /Users/spartygw/src/libraries/thirdparty/zlib -I /Users/spartygw/src/include -I /Users/spartygw/android-toolchain/sysroot/usr/include -march=armv5te -mfloat-abi=soft -mfpu=vfp -meabi=5 --noexecstack -o obj/Binary.ao /var/folders/03/hpjtv8c969scgcc5121ybrwr0000gn/T//ccciFNCN.s
GNU assembler version 2.24 (arm-linux-androideabi) using BFD version (GNU Binutils) 2.24
COMPILER_PATH=/Users/spartygw/android-toolchain/bin/../libexec/gcc/arm-linux-androideabi/4.8/:/Users/spartygw/android-toolchain/bin/../libexec/gcc/:/Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/
LIBRARY_PATH=/Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/:/Users/spartygw/android-toolchain/bin/../lib/gcc/:/Users/spartygw/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/lib/:/Users/spartygw/android-toolchain/bin/../sysroot/usr/lib/
COLLECT_GCC_OPTIONS='-Wextra' '-Wall' '-g' '-v' '-D' 'ANDROID' '-O0' '-g' '-c' '-MMD' '-MP' '-I' '/Users/spartygw/src/libraries' '-I' '/Users/spartygw/src/libraries/thirdparty' '-I' '/Users/spartygw/src/libraries/thirdparty/jpeg' '-I' '/Users/spartygw/src/libraries/thirdparty/zlib' '-I' '/Users/spartygw/src/include' '-I' '/Users/spartygw/android-toolchain/sysroot/usr/include' '-D' '__ARM_ARCH_5__' '-D' '__ARM_ARCH_5T__' '-D' '__ARM_ARCH_5E__' '-D' '__ARM_ARCH_5TE__' '-D' '__ANDROID__' '-D' 'DEBUG' '-o' 'obj/Binary.ao' '-march=armv5te' '-mfloat-abi=soft' '-mfpu=vfp' '-mtls-dialect=gnu'
Android.mk:
My Android.mk in the jni directory looks like this:
LOCAL_PATH := $(call my-dir)
############## libGabObjs ##################
include $(CLEAR_VARS)
LOCAL_MODULE = libGabObjs
LOCAL_SRC_FILES := libGabObjs_android.a
ifneq (,$(wildcard $(LOCAL_SRC_FILES)))
include $(PREBUILT_STATIC_LIBRARY)
endif
######################################
#####################################
############## libavcodec ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libavcodec.so
include $(PREBUILT_SHARED_LIBRARY)
#####################################
############## libavutil ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libavutil.so
include $(PREBUILT_SHARED_LIBRARY)
#####################################
############## libswscale ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libswscale.so
include $(PREBUILT_SHARED_LIBRARY)
#####################################
############## libspeex ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libspeex
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libspeex.a
include $(PREBUILT_STATIC_LIBRARY)
#####################################
############## libspeexdsp ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libspeexdsp
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libspeexdsp.a
include $(PREBUILT_STATIC_LIBRARY)
#####################################
############## libjpeg ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libjpeg
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libjpeg.a
include $(PREBUILT_STATIC_LIBRARY)
#####################################
############## libcrypto ############
include $(CLEAR_VARS)
LOCAL_MODULE := libcrypto
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libcrypto.a
include $(PREBUILT_STATIC_LIBRARY)
#####################################
############## libssl #############
include $(CLEAR_VARS)
LOCAL_MODULE := libssl
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libssl.a
include $(PREBUILT_STATIC_LIBRARY)
#####################################
############## libcutils #############
#include $(CLEAR_VARS)
#LOCAL_MODULE := libcutils
#LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libcutils.so
#include $(PREBUILT_SHARED_LIBRARY)
#####################################
############## libs ############
include $(CLEAR_VARS)
LOCAL_MODULE := vhc_jnilib
LOCAL_SRC_FILES := video_codec_jni.cpp \
MyBaseThread.cc \
MicMonitor.cpp \
framework.cpp \
GabrielJni.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../../libraries/ \
$(LOCAL_PATH)/../../../libraries/thirdparty/
LOCAL_STATIC_LIBRARIES := \
libGabObjs \
libssl \
libcrypto \
libjpeg \
libspeex \
libspeexdsp
LOCAL_SHARED_LIBRARIES := \
libavcodec libavutil libswscale
A_DEFINES := -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -D__ANDROID__ -DDEBUG $(ADDDEF)
DEFINES :=$(DEFINES)
LOCAL_LDLIBS = -lOpenSLES -lz -llog -landroid
LOCAL_CPPFLAGS := -D_FILE_OFFSET_BITS=64 -DDEBUG -D__ANDROID__
LOCAL_CFLAGS = -DFIXED_POINT -DEXPORT="" -g -O0 -fexceptions -funroll-loops -UHAVE_CONFIG_H -I../../libraries
include $(BUILD_SHARED_LIBRARY)
####
####
#### now build older vhcjnilib for lollipop and older
####
####
#####################################
############## libavcodec_lollipop ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec_lollipop
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libavcodec_lollipop.so
include $(PREBUILT_SHARED_LIBRARY)
#####################################
############## libavutil_lollipop ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libavutil_lollipop
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libavutil_lollipop.so
include $(PREBUILT_SHARED_LIBRARY)
#####################################
############## libswscale_lollipop ##############
include $(CLEAR_VARS)
LOCAL_MODULE := libswscale_lollipop
LOCAL_SRC_FILES := ../../../../lib/third-party/arm-android/libswscale_lollipop.so
include $(PREBUILT_SHARED_LIBRARY)
#####################################
############## libs ############
include $(CLEAR_VARS)
LOCAL_MODULE := vhc_jnilib_lollipop
LOCAL_SRC_FILES := video_codec_jni.cpp \
MyBaseThread.cc \
MicMonitor.cpp \
framework.cpp \
GabrielJni.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../../libraries/ \
$(LOCAL_PATH)/../../../libraries/thirdparty/
LOCAL_STATIC_LIBRARIES := \
libGabObjs \
libssl \
libcrypto \
libjpeg \
libspeex \
libspeexdsp
LOCAL_SHARED_LIBRARIES := \
libavcodec_lollipop libavutil_lollipop libswscale_lollipop
A_DEFINES := -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -D__ANDROID__ -DDEBUG $(ADDDEF)
DEFINES :=$(DEFINES)
LOCAL_LDLIBS = -lOpenSLES -lz -llog -landroid
LOCAL_CPPFLAGS := -D_FILE_OFFSET_BITS=64 -DDEBUG -D__ANDROID__
LOCAL_CFLAGS = -DFIXED_POINT -DEXPORT="" -g -fexceptions -funroll-loops -UHAVE_CONFIG_H -I../../libraries
include $(BUILD_SHARED_LIBRARY)
Application.mk:
APP_STL := stlport_static
APP_PLATFORM := android-10
APP_ABI := armeabi-v7a
APP_OPTIM := debug
My build.gradle file:
//////////////////////////////////////////////////////////////////////////////
// need this for password dialog
import groovy.swing.SwingBuilder
buildscript {
System.properties['com.android.build.gradle.overrideVersionCheck'] = 'true'
repositories {
jcenter()
}
dependencies {
// Current Gradle version.
final GradleVersion gradleVersion = GradleVersion.current()
// Gradle version 3.0+ requires a different classpath
final GradleVersion gradle3 = GradleVersion.version('3.0')
// Compare versions.
if (gradleVersion >= gradle3) {
println "Your Gradle version is at least 3.0"
classpath 'com.android.tools.build:gradle:2.2.0'
} else {
println "Your Gradle version is older than 3.0"
classpath 'com.android.tools.build:gradle:2.1.0'
}
}
}
apply plugin: 'com.android.application'
android {
lintOptions {
disable 'LongLogTag','ProtectedPermissions','AppLinksAutoVerifyError','MangledCRLF'
}
defaultConfig {
applicationId "com.mycompany.myapp.myclass"
}
compileSdkVersion 23
buildToolsVersion "23.0.2"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
signingConfigs {
release {
// We can leave these in environment variables
storeFile file(String.valueOf(System.getenv("PKCS12_FILE")))
keyAlias "mykey"
// These two lines make gradle believe that the signingConfigs
// section is complete. Without them, tasks like installRelease
// will not be available!
storePassword "notYourRealPassword"
keyPassword "notYourRealPassword"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
debug {
debuggable true
jniDebuggable true
}
}
}
dependencies {
compile 'com.android.support:support-v4:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
}
task askForPasswords {
doLast {
def pw = ''
if(System.console() == null) {
new SwingBuilder().edt {
dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) {
vbox { // Put everything below each other
label(text: "Signing the APK...Enter the keystore password:")
def input1 = passwordField()
button(defaultButton: true, text: 'OK', actionPerformed: {
pw = new String(input1.password);
dispose();
})
}
}
}
} else {
// Must create String because System.readPassword() returns char[]
// (and assigning that below fails silently)
pw = new String(System.console().readPassword("Keystore password: "))
}
android.signingConfigs.release.storePassword = pw
android.signingConfigs.release.keyPassword = pw
}
}
tasks.whenTaskAdded { theTask ->
if (theTask.name.equals("packageRelease")) {
theTask.dependsOn "askForPasswords"
}
}
task getVersion() {
println GradleVersion.current().getVersion()
}