在 Android Studio 中调试动态加载的本机库?

Debug a dynamically loaded native library in Android Studio?

我有一个看起来像这样的项目:

- project
    - app
       - src.../cpp/
       - src.../java/
    - other modules...

cpp代码是在build.gradle中使用cmake构建的:

externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}

buildTypes {
   ...
    debug {
        debuggable true
        jniDebuggable true
        externalNativeBuild {
            cmake {
                arguments "-DCMAKE_BUILD_TYPE=Debug"
                abiFilters "armeabi-v7a", "armeabi", "x86"
            }
        }
    }
}

productFlavors {
    ...
    experimental {
        externalNativeBuild {
            cmake {
                targets "sqlite_gcd_func"
            }
        }
    }
}

其中 CMakeLists.txt 是:

cmake_minimum_required(VERSION 3.6)

add_library( # Specifies the name of the library.
         sqlite_gcd_func
         # Sets the library as a shared library.
         MODULE
         # Provides a relative path to your source file(s).
         src/Experimental/cpp/GreatCircleDistance.cpp )
# Specifies a path to native header files.
include_directories(src/Experimental/cpp/include/)

生成的 .so 库通过 SQL:

作为扩展加载到 SQLite
Select load_extension('libsqlite_gcd_func', null)

之后库中定义的函数可用于 SQL 查询。

一切正常。

调试不行; CPP代码中设置的断点不触发。

我认为这是因为代码是在 运行 时动态加载的;我还尝试使用 java 通过以下方式直接加载模块:

java.lang.System.loadLibrary("sqlite_gcd_func");

但是断点还是不行

我对 lldb 的了解很少;我假设我需要告诉它加载的模块(通过 lldb 中的 'image list' 可见)是一个已知模块,但不知道该怎么做(如果这甚至是问题的话)。

如能帮助 gradle/lldb/Android Studio 调试此代码,我们将不胜感激!

编辑:

我用类似的设置创建了一个更简单的项目,它是可调试的。在不可调试的情况下,当我进入 lldb 和 运行 'image list' 时,有问题的 .so 显示为:

C:\Users\ME\.lldb\module_cache\remote-android\.cacheD1C60AA-E947-56CA-CBA5-0AA7A46B955E-73E37532\libname.so

(即看起来像是从 AVD 复制的版本)。

而在我可以调试的那个中,它显示在:

C:\...\project\app\build\intermediates\cmake\debug\obj\x86\libname.so

即。构建区域中的实际库。

lldb 由于某些原因似乎没有使用本地应用程序版本。

知道是什么原因造成的吗?

原来这是由于AS中的一个老bug。显然,在过去,IML 文件中 "native-android-gradle" 部分中的 "SELECTED_BUILD_VARIANT" 可能会与实际选择的口味不一致。导致加载.so文件失败

更正后,此值现在似乎仍然是最新的,以下是 link 对(现已修复)错误的讨论:

https://issuetracker.google.com/issues/37114841

据我所知,项目同步 可能 也可以解决问题(对我来说不是)。

我有一个类似的问题,我无法调试动态加载的本机库。事实证明,Android 构建系统在将调试信息放入 APK 之前从我的库中剥离了调试信息。当我意识到我的 300MB 库在打包到 APK 后缩小到 30MB 时,我就清楚了。

您可以使用 Android Gradle Packaging Options 来禁用该行为。 将类似的内容添加到您的 build.gradle 文件中:

android {
    packagingOptions {
    // By default .so libraries are striped from debug information when creating APK
    // To prevent this make sure your .so files are matching that doNotStrip pattern
    // See Gradle pattern document for details:
    // https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/util/PatternFilterable.html
    doNotStrip "**"
    }
}

这与 Android Studio 2.3.3 相关。

缓存无效并重新启动。适合我。