Я работаю над Android
проект, который использует Java
класс, который является оберткой на C++
библиотека. Библиотека C ++ является внутренней библиотекой компании, и у нас есть доступ к ее исходному коду, но в проекте Android она только динамически связана, поэтому она используется только в виде заголовков (.час) и общие объекты (.так). Имея доступ к исходному коду библиотеки, можно ли указать Android Studio путь к исходному коду, чтобы я мог войти в библиотеку с помощью отладчика?
Отладчик работает, я могу зайти внутрь 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')
...
}
так что я не думаю, что мы используем aar
с для app.gradle
проект. aar
s отправляются клиенту, но мы используем app.gradle
проект, чтобы проверить наши маленькие функциональные возможности SDK, прежде чем делать это. Слой JNI находится внутри clory-sdk-core
проект.
РЕДАКТИРОВАТЬ 2:
Здесь CMakeLists.txt
который обрабатывает слой JNI:
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
и построен в режиме отладки (CONFIG+=debug
был добавлен в эффективный вызов qmake).
РЕДАКТИРОВАТЬ 3:
в LLDB
сессия, которая открылась после того, как Java_clory_engine_sdk_CloryNative_nativeInit
Точка останова, я получил следующее:
(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) =
Прежде всего не было CompileUnit
раздел в результате команды image lookup -vrn Clory::Engine::instance
, Как это возможно, чтобы не иметь источник-карта определены (второй lldb команда), если libclorysdk.so
был построен в отлаживать Режим? Можно ли явно установить его так, чтобы отладчик искал там исходные файлы библиотеки?
РЕДАКТИРОВАТЬ 4:
После поиска я обнаружил, что процесс создания APK фактически лишает *.so
библиотеки из их отладочных символов. libclorysdk.so
встроенный режим отладки имеет около 10 МБ, в то время как libclorysdk.so
файл, который я извлек после разархивирования сгенерированного *.apk
файл всего 350KB.
Как указано Вот, Бег greadelf --debug-dump=decodedline libclorysdk.so
в отладочной версии выводит ссылки на исходные файлы, но если команда запускается на *.apk
извлеченная библиотека, ничего не выводит.
Есть ли способ остановить Android Studio от зачистки *.so
s? Я старался Как избежать зачистки для собственных символов кода для приложения Android но не имел никакого эффекта, *.apk
Файл имеет тот же размер, что и раньше, и отладка собственных библиотек по-прежнему не работает.
я использую Gradle 3.1.4
,
РЕДАКТИРОВАТЬ 5:
раствор для зачистки работает, но в моем случае нужна была чистая & Постройте, прежде чем попасть в точки останова в библиотеке. Развертывание *.so
s, которые не удалены, позволяют вам иметь сеансы отладки и входить в собственные библиотеки.
Замечания:
Если библиотеки построены с использованием Qt for Android
набор инструментов *.so
с развернутым в $SHADOW_BUILD/android-build
также раздели (где $SHADOW_BUILD
каталог сборки обычно начинается с build-*
). Таким образом, чтобы отладить их, вы должны скопировать их извне android-build
каталог, где каждый *.so
генерируется.
Отладочная информация записывает расположение исходных файлов, когда они были собраны.
(lldb) image lookup -vrn Clory::Engine::instance
Строка CompileUnit показывает исходный файл. Предположим, это говорит:
"/BuildDirectory/Sources/Clory/CloryEngine.cpp"
Предположим, у вас есть источник на вашей машине:
"Users/me/Sources/Clory"
Таким образом, вы можете сказать lldb: найдите вместо него исходный файл с корнем в / BuildDirectory / Sources / Clory в Users / me / Sources / Clory.
(lldb) settings set target.source-map /BuildDirectory/Sources/Clory Users/me/Sources/Clory
Вы можете использовать эти команды в консоли lldb Android Studio или поместить в файл .lldbinit для общего использования.
если нет доступных символов отладки, вам, возможно, придется построить библиотеку, на которую ссылаются, в режиме отладки.
либо с -DCMAKE_BUILD_TYPE=DEBUG
:
externalNativeBuild {
cmake {
arguments "-DANDROID_TOOLCHAIN=gcc", "-DCMAKE_BUILD_TYPE=DEBUG"cppFlags "-std=c++14 -fexceptions -frtti"}
}
или добавить это к CMakeLists.txt
библиотеки:
set(CMAKE_BUILD_TYPE Debug)
увидеть CMake документация и Символизирующий с LLDB.
в другом месте это объясняет (lldb) settings set target.source-map /buildbot/path /my/path
:
Переопределите имена путей к исходному файлу для сеанса отладки. Если ваши исходные файлы больше не находятся в том же месте, что и при сборке программы — возможно, программа была собрана на другом компьютере — вам нужно указать отладчику, как найти источники по их локальному пути к файлу, а не по пути к файлу системы сборки.
есть также (lldb) settings show target.source-map
, чтобы увидеть, что отображается.
(lldb) set append target.source-map /buildbot/path /my/path
кажется достаточно подходящим, чтобы не перезаписывать существующие сопоставления.