Отладка библиотеки C ++ с помощью Android Studio - PullRequest
0 голосов
/ 25 октября 2018

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

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

EDIT 3:

В *Сессия 1068 *, которая открылась после достижения точки останова 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 не было секции CompileUnit.Как это возможно, чтобы не было определено source-map (вторая lldb команда), если libclorysdk.so был встроен в режиме Debug ?Можно ли явно установить его так, чтобы отладчик искал там исходные файлы библиотеки?

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

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

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

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

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

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

Примечание:

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

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

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

либо с -DCMAKE_BUILD_TYPE=DEBUG:

defaultConfig {
    externalNativeBuild {
        cmake {
            arguments "-DANDROID_TOOLCHAIN=gcc", "-DCMAKE_BUILD_TYPE=DEBUG"
            cppFlags "-std=c++14 -fexceptions -frtti"
        }
    }
}

externalNativeBuild {
    cmake {
        path file('src/main/cpp/CMakeLists.txt')
    }
}

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

0 голосов
/ 30 октября 2018

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

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

...