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

时间:2017-04-23 11:54:25

标签: android c++ gradle cmake lldb

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

- 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并运行“图像列表”时,所讨论的.so显示为:

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

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

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

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

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

lldb似乎不会出于某种原因使用本地应用版本。

知道会导致什么原因吗?

2 个答案:

答案 0 :(得分:2)

事实证明这是由于AS中的旧错误。显然在过去,IML文件中“native-android-gradle”部分中的“SELECTED_BUILD_VARIANT”可能与实际选择的风格不一致。这导致无法加载.so文件。

一旦纠正,这个值现在似乎仍然是最新的,以下是对(现在修复的)错误的讨论的链接:

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

据我所知,项目同步可能也解决了问题(它不适合我)。

答案 1 :(得分:1)

我有一个类似的问题,我无法调试动态加载的本机库。事实证明,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相关。