studio programacion ndk móviles libro desarrollo curso aplicaciones android c++ android-studio jni android-studio-3.0

programacion - Depuración de la biblioteca de C++ con Android Studio



ndk android studio (2)

La información de depuración registra la ubicación de los archivos de origen cuando se crearon.

(lldb) image lookup -vrn Clory::Engine::instance

La línea CompileUnit muestra el archivo fuente. Supongamos que dice:

"/BuildDirectory/Sources/Clory/CloryEngine.cpp"

Supongamos que tiene la fuente en su máquina aquí:

"Users/me/Sources/Clory"

Así que puedes decirle a lldb: encuentra el archivo fuente enraizado en / BuildDirectory / Sources / Clory en Users / me / Sources / Clory en su lugar.

(lldb) settings set target.source-map /BuildDirectory/Sources/Clory Users/me/Sources/Clory

Puede usar estos comandos en la consola lldb de Android Studio o colocarlos en un archivo .lldbinit para uso general.

Estoy trabajando en un proyecto de Android que utiliza una clase de Java que es un contenedor en una biblioteca de C++ . La biblioteca de C ++ es una biblioteca interna de la empresa y tenemos acceso a su código fuente, pero en el proyecto de Android solo está enlazado dinámicamente, por lo que se usa solo en forma de encabezados ( .h ) y objetos compartidos ( .so ). Al tener acceso al código fuente de la biblioteca, ¿es posible especificar a Android Studio la ruta al código fuente para que pueda ingresar dentro de la biblioteca usando el depurador?

El depurador funciona. Puedo Java_clory_engine_sdk_CloryNative_nativeInit función Java_clory_engine_sdk_CloryNative_nativeInit , pero también me gustaría depurar más la biblioteca correspondiente a la clase Clory::Engine que, como mencioné, es una biblioteca interna a la que tenemos acceso al código fuente.

Por ejemplo, la Clory::Engine::instance es parte de la biblioteca y me gustaría especificar a Android Studio la ubicación del archivo CloryEngine.cpp para que pueda CloryEngine.cpp la CloryEngine.cpp Clory::Engine::instance con el depurador, por lo que depura esta función miembro estática.

Estoy usando Android Studio 3.1.4.

es posible?

EDITAR:

El archivo clory-sdk.gradle especifica el archivo CMakeLists.txt que configura la capa C ++.

externalNativeBuild { cmake { path "CMakeLists.txt" } }

Así que estoy usando una aplicación interna que usa el SDK de Clory . Dentro del archivo app.gradle utilizo:

dependencies { ... compile project('':clory-sdk-core'') compile project('':clory-sdk'') ... }

así que no creo que estemos usando las aar para el proyecto app.gradle . Los aar se envían al cliente, pero estamos usando el proyecto app.gradle para probar nuestras pequeñas funcionalidades de SDK antes de hacerlo. La capa JNI está dentro del proyecto clory-sdk-core .

EDIT 2:

Aquí está el CMakeLists.txt que maneja la capa 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 )

La biblioteca clorysdk es en realidad nuestra biblioteca interna de la que estaba hablando, que contiene, por ejemplo, Clory::Engine::instance me gustaría intervenir con el depurador. Fue construido con qmake y se construye en modo de depuración ( CONFIG+=debug se agregó en la llamada qmake efectiva).

EDITAR 3:

En la sesión de LLDB que se abrió después de que llegó al punto de interrupción Java_clory_engine_sdk_CloryNative_nativeInit , obtuve lo siguiente:

(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) =

En primer lugar, no había una sección CompileUnit en el resultado del comando de image lookup -vrn Clory::Engine::instance . ¿Cómo es posible que no se haya definido ningún mapa de origen (segundo comando lldb ) si libclorysdk.so se creó en modo de depuración ? ¿Es posible configurarlo explícitamente para que el depurador busque allí los archivos de origen de la biblioteca?

EDITAR 4:

Después de buscar más, descubrí que el proceso de creación del APK en realidad *.so bibliotecas *.so de sus símbolos de depuración. libclorysdk.so integrado en el modo de depuración tiene aproximadamente 10 MB, mientras que el archivo libclorysdk.so que libclorysdk.so después de desarchivar el archivo *.apk generado es de 350 KB. Como se indica here , la ejecución de greadelf --debug-dump=decodedline libclorysdk.so en la versión de depuración genera referencias a los archivos de origen, pero si el comando se ejecuta en la biblioteca extraída *.apk , no genera nada.

¿Hay alguna manera de evitar que Android Studio elimine los *.so s? Intenté cómo evitar la eliminación de símbolos de código nativo para la aplicación de Android, pero no tuvo ningún efecto, el archivo *.apk tiene el mismo tamaño que antes y la depuración de las bibliotecas nativas todavía no funciona.

Estoy usando Gradle 3.1.4 .

EDIT 5:

La solución de extracción funciona, pero en mi caso necesitaba una limpieza y construcción antes de llegar a los puntos de interrupción en la biblioteca. La implementación de *.so s que no se eliminan le permite tener sesiones de depuración y pasar a las bibliotecas nativas.

Nota:

Si las bibliotecas se crean utilizando la cadena de herramientas Qt for Android , también se $SHADOW_BUILD/android-build los *.so implementados en $SHADOW_BUILD/android-build (donde $SHADOW_BUILD es el directorio de compilación que generalmente comienza con build-* ). Por lo tanto, para depurar aquellos, debe copiarlos desde fuera del directorio de android-build donde se genera cada *.so .


Si no hay símbolos de depuración disponibles, es posible que deba compilar la biblioteca a la que se hace referencia en el modo de depuración.

ya sea con -DCMAKE_BUILD_TYPE=DEBUG :

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

o agregue esto a CMakeLists.txt de la biblioteca:

set(CMAKE_BUILD_TYPE Debug)

Consulte la documentación de CMake y Simbolización con LLDB .

elsewhere , explica (lldb) settings set target.source-map /buildbot/path /my/path :

Reasignar nombres de ruta de archivo de origen para la sesión de depuración. Si sus archivos de origen ya no están ubicados en la misma ubicación que cuando se creó el programa, quizás el programa se creó en una computadora diferente, debe decirle al depurador cómo encontrar las fuentes en su ruta de archivo local. de la ruta del archivo del sistema de compilación.

también (lldb) settings show target.source-map , para ver qué se asigna. (lldb) set append target.source-map /buildbot/path /my/path parece bastante adecuado, para no sobrescribir las asignaciones existentes.