热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用AndroidStudio调试C++库

如何解决《使用AndroidStudio调试C++库》经验,为你挑选了2个好方法。

我正在开发一个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')
...
}

所以我不认为我们在项目中使用aars app.gradle.该aars的运到客户端,但我们使用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内置在调试模式下大约10MB而libclorysdk.so我解压缩生成的*.apk文件后提取的文件只有350KB.如前所述这里,运行greadelf --debug-dump=decodedline libclorysdk.so在调试版本输出引用的源文件,但如果命令在运行*.apk中提取库,它什么也不输出.

有没有办法阻止Android Studio剥离*.sos?我试过如何避免剥离Android应用程序的本机代码符号,但没有任何影响,*.apk文件大小与以前相同,调试本机库仍然无法正常工作.

我正在使用Gradle 3.1.4.

编辑5:

该剥离液的作品,但在我的情况下,它打在库中的断点之前需要清理并生成.部署*.so未剥离的s允许您在本机库中进行调试会话和步骤.

注意:

如果库是使用Qt for Android工具链构建的,那么*.so部署到$SHADOW_BUILD/android-build的库也会被剥离($SHADOW_BUILD通常以编译目录开头build-*).因此,为了调试它们,您应该从生成android-build每个文件的目录之外复制它们*.so.



1> Peter..:

调试信息记录源文件构建时的位置.

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

CompileUnit行显示源文件.假设它说:

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

我们假设您的机器上有源:

"Users/me/Sources/Clory"

所以你可以告诉lldb:在Users/me/Sources/Clory中找到以/ BuildDirectory/Sources/Clory为根的源文件.

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

您可以在Android Studio的lldb控制台中使用这些命令,也可以将其放入.lldbinit文件中以供一般使用.


似乎libclorysdk.so没有调试信息.尝试使用调试信息重建sdk或使用sdk的调试版本(如果可用).在Android Studio中使用这些lldb命令.在`Java_clory_engine_sdk_CloryNative_nativeInit`函数中设置断点.开始调试.当您在断点处停止时,请使用Android Studio的lldb窗口运行上面的lldb命令.

2> Martin Zeitl..:

如果没有可用的调试符号,则可能必须在调试模式下构建引用的库.

要么-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看起来比较合适,以免覆盖现有的映射.


推荐阅读
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • ECMA262规定typeof操作符的返回值和instanceof的使用方法
    本文介绍了ECMA262规定的typeof操作符对不同类型的变量的返回值,以及instanceof操作符的使用方法。同时还提到了在不同浏览器中对正则表达式应用typeof操作符的返回值的差异。 ... [详细]
author-avatar
小旭zZ
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有