调试器可以正常工作,我可以进入Java_clory_engine_sdk_CloryNative_nativeInit函数,但我还想进一步调试对应于Clory::Engine类的库,正如我之前提到的,这是我们拥有源代码访问权限的内部库。 例如,
Clory::Engine::instance
是库的一部分,我想指定给Android Studio CloryEngine.cpp
文件的位置,以便我可以使用调试器进入Clory::Engine::instance
,从而调试这个静态成员函数。我正在使用Android Studio 3.1.4。
这可能吗?
编辑:
clory-sdk.gradle
文件指定了CMakeLists.txt
文件,该文件配置了C++层。externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
我正在使用一个内部应用程序,该应用程序使用 Clory SDK。在 app.gradle
文件中,我使用:
dependencies {
...
compile project(':clory-sdk-core')
compile project(':clory-sdk')
...
}
所以我认为我们没有在app.gradle项目中使用aar。aar会被发送到客户端,但在此之前我们将使用app.gradle项目来测试我们的小型SDK功能。JNI层位于clory-sdk-core项目中。
编辑2: 这是处理JNI层的CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_BUILD_TYPE Debug)
add_library(
clory-lib
SHARED
# JNI layer and other helper classes for transferring data from Java to Qt/C++
src/main/cpp/clory-lib.cpp
src/main/cpp/JObjectHandler.cpp
src/main/cpp/JObjectResolver.cpp
src/main/cpp/JObjectCreator.cpp
src/main/cpp/DataConverter.cpp
src/main/cpp/JObjectHelper.cpp
src/main/cpp/JEnvironmentManager.cpp
)
find_library(
log-lib
log
)
target_compile_options(clory-lib
PUBLIC
-std=c++11
)
# Hardcoded for now...will fix later...
set(_QT_ROOT_PATH /Users/jacob/Qt/5.8)
if(${ANDROID_ABI} MATCHES ^armeabi-v7.*$)
set(_QT_ARCH android_armv7)
elseif(${ANDROID_ABI} MATCHES ^x86$)
set(_QT_ARCH android_x86)
else()
message(FATAL_ERROR "Unsupported Android architecture!!!")
endif()
set(CMAKE_FIND_ROOT_PATH ${_QT_ROOT_PATH}/${_QT_ARCH})
find_package(Qt5 REQUIRED COMPONENTS
Core
CONFIG
)
target_include_directories(clory-lib
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src/main/cpp
)
set(_CLORYSDK_LIB_PATH ${CMAKE_CURRENT_LIST_DIR}/src/main/jniLibs/${ANDROID_ABI})
target_link_libraries(clory-lib
${log-lib}
-L${_CLORYSDK_LIB_PATH}
clorysdk
Qt5::Core
)
这个库clorysdk
实际上是我们内部的库,我之前提到过,其中包含Clory::Engine::instance
,我想要用调试器进入它。它是使用qmake
构建的,并且在调试模式下构建(在有效的qmake调用中添加了CONFIG+=debug
)。
编辑3:
在打中断点Java_clory_engine_sdk_CloryNative_nativeInit
后打开的LLDB
会话中,我得到了以下信息:
(lldb) image lookup -vrn Clory::Engine::instance
2 matches found in /Users/jacob/.lldb/module_cache/remote-android/.cache/6EDE4F0A-0000-0000-0000-000000000000/libclorysdk.so:
Address: libclorysdk.so[0x0001bb32] (libclorysdk.so..text + 8250)
Summary: libclorysdk.so`Clory::Engine::instance(Clory::Engine::Purpose)
Module: file = "/Users/jacob/.lldb/module_cache/remote-android/.cache/6EDE4F0A-0000-0000-0000-000000000000/libclorysdk.so", arch = "arm"
Symbol: id = {0x0000005e}, range = [0xcb41eb32-0xcb41ebc0), name="Clory::Engine::instance(Clory::Engine::Purpose)", mangled="_ZN4Clory2Engine8instanceENS0_7PurposeE"
Address: libclorysdk.so[0x0001b82c] (libclorysdk.so..text + 7476)
Summary: libclorysdk.so`Clory::Engine::instance(Clory::RuntimeConfiguration const&, Clory::Engine::Purpose)
Module: file = "/Users/jacob/.lldb/module_cache/remote-android/.cache/6EDE4F0A-0000-0000-0000-000000000000/libclorysdk.so", arch = "arm"
Symbol: id = {0x000000bd}, range = [0xcb41e82c-0xcb41e970), name="Clory::Engine::instance(Clory::RuntimeConfiguration const&, Clory::Engine::Purpose)", mangled="_ZN4Clory2Engine8instanceERKNS_20RuntimeConfigurationENS0_7PurposeE"
(lldb) settings show target.source-map
target.source-map (path-map) =
首先,在命令
image lookup -vrn Clory::Engine::instance
的结果中没有CompileUnit
部分。如果libclorysdk.so
是在Debug模式下构建的,为什么没有定义source-map(第二个lldb命令)?是否可以显式设置以便调试器在那里搜索库的源文件?编辑4: 经过更多搜索,我发现创建APK的过程实际上会从调试符号中剥离
*.so
库。在调试模式下构建的libclorysdk.so
大约有10MB,而我从生成的*.apk
文件解压缩后提取的libclorysdk.so
文件只有350KB。
如此处所述,在调试版本上运行greadelf --debug-dump=decodedline libclorysdk.so
会输出对源文件的引用,但如果在*.apk
提取的库上运行该命令,则不会输出任何内容。有没有办法阻止Android Studio剥离*.so文件?我尝试了如何避免Android应用程序本机代码符号被剥离,但没有效果,*.apk文件与之前相同大小,调试本机库仍然无法工作。我正在使用Gradle 3.1.4。
编辑5: 剥离解决方案有效,但在我的情况下,在打中断点之前需要清理和构建才能进入库。部署未被剥离的*.so允许您拥有调试会话并进入本机库。
注意:
如果使用Qt for Android工具链构建库,则部署到$SHADOW_BUILD/android-build的*.so也会被剥离(其中$SHADOW_BUILD是通常以build-*开头的构建目录)。因此,为了调试它们,您应该从生成每个*.so之外的android-build目录中复制它们。
readelf --string-dump=.debug_str mylib.so
来查看源文件应该存在的位置。 - Michaelndk
或cmake
配置?还是你使用的库被打包为aar
格式? - ahasbiniCMakeLists.txt
吗?为了更清晰和纠正我是否理解错误,你的项目包含app
模块是一个常规应用程序,其中在app.gradle
中定义了plugin: 'com.android.application'
。clory-sdk-core
和clory-sdk
也是项目模块,它们的gradle
文件包含plugin: 'com.android.library'
,唯一的区别是clory-sdk
包含CMakeLists.txt
文件和 C/C++ 代码。 - ahasbiniclory-sdk-core
包含CMakeLists.txt
,而不是clory-sdk
。因此,clory-sdk-core.gradle
包含externalNativeBuild {cmake {path "CMakeLists.txt"}}
,而clory-sdk
将clory-sdk-core
作为依赖项:dependencies {compile project(':glas.ai-sdk-core')}
。我已发布了编辑,并添加了CMakeLists.txt
以获得更清晰的说明。 - Jacob Krieg