Библиотека отладки C++ с помощью Android Studio

Я работаю над проектом Android который использует класс Java который является оберткой для библиотеки C++. Библиотека C++ является внутренней библиотекой компании, и у нас есть доступ к ее исходному коду, но в проекте Android она только динамически связана, поэтому она используется только в форме заголовков (.h) и общих объектов (.so). Имея доступ к исходному коду библиотеки, можно ли указать Android Studio путь к исходному коду, чтобы я мог войти в библиотеку с помощью отладчика?

Отладчик работает, я могу войти в функцию Java_clory_engine_sdk_CloryNative_nativeInit, но я также хотел бы продолжить отладку библиотеки, соответствующей Clory::Engine которая, как я упоминал, является внутренней библиотекой, к которой у нас есть доступ к исходному коду.

c_clory

Например, 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 отправляется клиенту, но мы используем проект 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) =

Прежде всего, в результате image lookup -vrn Clory::Engine::instance команды image lookup -vrn Clory::Engine::instance не CompileUnit раздела image lookup -vrn Clory::Engine::instance. Как это возможно, чтобы не было задано никакой карты-источника (вторая команда lldb), если libclorysdk.so был libclorysdk.so в режиме отладки? Можно ли явно установить его так, чтобы отладчик искал там исходные файлы библиотеки?

РЕДАКТИРОВАТЬ 4:

После поиска я обнаружил, что процесс создания APK фактически удаляет библиотеки *.so из их символов отладки. Встроенный в режиме отладки libclorysdk.so занимает около 10 МБ, а файл libclorysdk.so который я извлек после разархивирования сгенерированного файла *.apk составляет всего 350 КБ. Как указано здесь, выполнение greadelf --debug-dump=decodedline libclorysdk.so в отладочной версии выводит ссылки на исходные файлы, но если команда выполняется в извлеченной библиотеке *.apk, она ничего не выводит.

Есть ли способ остановить Android Studio от зачистки *.so s? Я попробовал, как избежать удаления символов собственного кода для приложения Android, но не дал никакого эффекта, файл *.apk имеет тот же размер, что и раньше, и отладка собственных библиотек все еще не работает.

Я использую Gradle 3.1.4.

РЕДАКТИРОВАТЬ 5:

Решение для зачистки работает, но в моем случае ему потребовалась Clean & Build, прежде чем попасть в точки останова в библиотеке. Развертывание *.so которое не было удалено, позволяет вам проводить сеансы отладки и входить в собственные библиотеки.

Замечания:

Если библиотеки построены с Qt for Android цепочки инструментов Qt for Android, *.so развернутый в $SHADOW_BUILD/android-build, также $SHADOW_BUILD (где $SHADOW_BUILD - это каталог сборки, обычно начинающийся с build-*). Поэтому для их отладки вы должны скопировать их из директории android-build где генерируется каждый *.so.

Ответ 1

Отладочная информация записывает расположение исходных файлов, когда они были собраны.

(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 для общего использования.

Ответ 2

если нет доступных символов отладки, вам, возможно, придется построить указанную библиотеку в режиме отладки.

либо с -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 кажется вполне подходящим, чтобы не перезаписывать существующие сопоставления.

Ответ 3

Я запускаю общий поиск изображений -vrn xxx ", и путь к файлу является относительным путем , Даже если я помещу исходный код в относительную позицию, он все равно не может ввести точку останова. Что я могу сделать? Спасибо!

CompileUnit: id = {0xffffffff0338812a}, file = "./../../net/tools/quic/quic_simple_client_android.cpp", language = "c++"