代码之家  ›  专栏  ›  技术社区  ›  Jacob Krieg

用Android工作室调试C++库

  •  23
  • Jacob Krieg  · 技术社区  · 7 年前

    我在做一个 Android Java 类的包装器 C++ 图书馆。C++库是一个公司内部的库,我们可以访问它的源代码,但是在Android项目中,它只是动态链接的,所以它仅以报头的形式使用( h 所以呢

    调试器工作,我可以进入 Java_clory_engine_sdk_CloryNative_nativeInit Clory::Engine 类,正如我提到的,它是我们可以访问源代码的内部库。

    c_clory

    Clory::Engine::instance 是库的一部分,我想向Android Studio指定 CloryEngine.cpp Clory::引擎::实例 使用调试器,从而调试此静态成员函数。

    这可能吗?

    编辑:

    这个 clory-sdk.gradle CMakeLists.txt

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

    所以我使用一个内部应用程序 Clory软件开发包 app.gradle 我使用的文件:

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

    所以我不认为我们在使用 aar 代表 应用程序gradle aar公司 s已发送到客户端,但我们正在使用 项目来测试我们的小SDK功能,然后再这样做。JNI层在里面 clory-sdk-core 项目。

    这是你的名字

    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 实际上是我所说的我们的内部图书馆,它包含。 我想进入调试器。它是用 qmake 并且是在调试模式下构建的( CONFIG+=debug

    编辑3:

    LLDB Java\u clory\u引擎\u sdk\u CloryNative\u 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 源地图 已定义(秒) 有限责任公司 命令)如果 libclorysdk.so 是内置的 调试 模式?是否可以显式设置它,以便调试器在那里搜索库的源文件?

    编辑4:

    *.so libclorysdk.so文件 内置调试模式大约有10MB,而 libclorysdk.so文件 在解压生成的 *.apk 如前所述 here ,正在运行 greadelf --debug-dump=decodedline libclorysdk.so *阿普克先生 提取的库,它什么也不输出。

    *所以呢 什么?我试过了 How to avoid stripping for native code symbols for android app 但没有任何效果, 文件的大小与以前相同,并且调试本机库仍然不起作用。

    我在用 Gradle 3.1.4

    编辑5:

    stripping solution 工作,但在我的情况下,它需要一个干净的&在命中库中的断点之前生成。部署 *所以呢 未剥离的允许您在本机库中进行调试会话和步骤。

    如果库是使用 Qt for Android 已部署到 $SHADOW_BUILD/android-build $SHADOW_BUILD 生成目录通常以 build-* ). 因此,为了调试它们,您应该从外部复制它们 android-build 每个 *所以呢 已生成。

    2 回复  |  直到 7 年前
        1
  •  18
  •   Peter    7 年前

    调试信息记录生成源文件时源文件的位置。

    (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
    

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

        2
  •  9
  •   Martin Zeitler    7 年前

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

    或与 -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 文件和 Symbolicating with LLDB .

    elsewhere 它解释了 (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 似乎相当合适,以便不覆盖现有映射。