使用LLDB在VS Code中调试Android C_C++代码(无需Android源码)

2024-05-29 03:58

本文主要是介绍使用LLDB在VS Code中调试Android C_C++代码(无需Android源码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

需求分析

在使用GDB在VS Code调试Android C/C++代码(无需Android源码)文章中介绍了如何在VS Code中使用GDB来调试Android C/C++代码,在浏览Android文档Using Debuggers中发现,文档更新了,不建议使用GDB,应尽可能使用LLDB(注意:查看Android文档时,在右上角语言选择ENGLISH,才能浏览最新文档,而不是选择中文-简体)。同样文档中介绍了如何基于Android源码,在VS Code中使用CodeLLDB extension进行调试,下面我们将探索如何在VS Code中不使用Android源码进行调试。

探索过程

官方文档说明

在上述Android文档Using Debuggers中介绍了如何使用LLDB调试。与之前GDB类似,它提到的前置条件是使用Android源码中gdbclient.py或者lldbclient.py(lldbclient.py就是gdbclient.py的软连接)脚本。此脚本会生成VS Code的配置文件,将其设置到launch.json中,并在Android设备上启动lldb-server,在主机上启动lldb,然后将lldb连接到远程的lldb-server。

前人使用记录

在LLDB调试Android Native程序中详细阐述了使用LLDB调试的过程。总结成下面几个核心步骤:

  1. 从NDK中获得获取对应的平台的lldb-server;
  2. 将lldb-server放入设备并启动:./lldb-server p --server --listen unix-abstract:///data/local/tmp/debug.sock
  3. 本机lldb连接远程lldb-server,调试方式分为两种:a、 launch:直接启动要调试的程序; b、 attach:将调试器附到可调试进程中。

那么如何在VS Code中使用LLDB呢,接下来我们实际操作一下。

来实践一下吧

先决条件

1、安装Visual Studio Code以及在其中安装CodeLLDB extension,安装后lldb在此路径下~/.vscode/extensions/vadimcn.vscode-lldb-1.6.1/lldb/bin/lldb,在手动调试时候可以使用。

2、下载好Android NDK,方便使用其中lldb-server,它在<NDK_ROOT>/android-ndk-r21b/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/9.0.8/lib/<Platform>/<Arch>目录下。Platform代指本机系统,Arch代指要调试的Android的ABI。

3、编译项目时,需要添加调试信息,即在Android.mk中添加LOCAL_CFLAGS += -g,或者通过在ndk-build命令行上传递NDK_DEBUG=1。同时如果项目的Application.mk文件指定APP_OPTIM设置,必须将其设置为debug以禁用编译器优化。

调试设置

1、VS Code中打开需要调试的项目,点击运行>>启动调试(或直接按F5快捷键)。

选择环境

在弹出的窗口中选择LLDB,若无此选项请检查CodeLLDB extension是否安装。

第一次没有配置文件时,会弹出如下窗口,点击确认,将会在当前项目中.vscode中生成默认的launch.json文件。

确定

2、launch.json的设置属性如下所述。

name:调试配置的名字,在进行调试时,根据名字选择不同的配置。
type: 设置为"lldb",表示使用CodeLLDB extension提供的lldb进行调试。
program:要调试的程序。这应该指向带有调试符号的可执行文件的本地版本(非剥离版本),通常在项目的构建目录下的obj/local/armeabi-v7a中(对于64位构建,则位于obj/local/arm64-v8a中)。
request:分为attach和launch。
preLaunchTask:在启动调试器之前要执行的任务。
initCommands:初始化时相关的参数。

更多相关信息,请参考 vscode-lldb/MANUAL.md。

示例launch.json文件:

{"version": "0.2.0","configurations": [{"type": "lldb","request": "attach","name": "lldb attach","program": "${workspaceFolder}/test","preLaunchTask": "lldb build task","initCommands": ["platform select remote-android","platform connect connect://localhost:9090","settings set target.inherit-env false",],},{"type": "lldb","request": "launch","name": "lldb launch","program": "${workspaceFolder}/test","preLaunchTask": "lldb build task","initCommands": ["platform select remote-android","platform connect connect://localhost:9090","settings set target.inherit-env false","platform settings -w /data/local/tmp/","platform status"],},]
}

3、前面提到preLaunchTask任务,这些任务也可以用于支持调试。可以定义一个任务来编译代码,push程序到手机端,转发调试器端口等操作。
在.vscode中添加一个tasks.json文件。如下:

{"version": "2.0.0","tasks": [{"label": "build task","type": "shell","command": "source debug.sh"}]
}

注意task中"label"的值和launch中"preLaunchTask"的值一致。这里我们执行一个shell命令,将具体的任务放在debug.sh中处理。有关任务配置的更多信息,请参见VSCode文档。

4、在项目中新建debug.sh文件,内容如下:

#!/bin/bashndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=./Application.mk APP_BUILD_SCRIPT=Android.mk cleanndk-build NDK_DEBUG=1 NDK_PROJECT_PATH=. NDK_APPLICATION_MK=./Application.mk APP_BUILD_SCRIPT=Android.mk -j16adb push obj/local/arm64-v8a/test /system/bin/
adb shell chmod 777 /system/bin/testadb forward tcp:9090 tcp:9090gnome-terminal -- bash -c "adb shell '/data/local/tmp/lldb-server platform --listen *:9090 --server'"

a、首先使用ndk-build编译代码,里面增加了NDK_DEBUG=1,使其生成的程序包含调试信息;再将生成的程序push到/system/bin/目录下,同时赋予可执行权限。

b、设置端口转发
在开发机上设置端口转发,命令如下:

adb forward tcp:9090 tcp:9090

命令说明:表示通过adb映射tcp端口1234,命令中前面的是local的端口,后面的是remote的端口。命令中的端口号必须与lldb-server命令中的监听端口号相同,否则会导致lldb无法与lldb-server连接。

c、在目标设备上执行lldb-server

adb shell "/data/local/tmp/lldb-server platform --listen '*:9090' --server &" &

更多介绍可以查看lldb官方文档The LLDB Debugger。

启动调试

一切准备ok,接下可以开始调试了,在选择配置时可以选择lldb attachlldb launch,根据实际使用情况选择不同模式。
三种方式启动:
1、通过单击VS Code窗口左侧的Debug图标,启用“开始调试”面板;
2、从面板顶部的列表中选择“运行”,然后单击执行“启动调试”按钮;
3、直接快捷键F5。

一旦调试器开始连接,VSCode调试控制台将显示来自调试器的消息,并在必要时允许执行手动调试器命令(必须停​​止程序以执行调试命令)。调试面板将显示调试信息(变量监视,调用堆栈,断点等),调试器工具栏将提供对常见调试命令的访问。还支持基于鼠标光标的变量显示。

在这里插入图片描述

这篇关于使用LLDB在VS Code中调试Android C_C++代码(无需Android源码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012582

相关文章

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位

Springboot3 ResponseEntity 完全使用案例

《Springboot3ResponseEntity完全使用案例》ResponseEntity是SpringBoot中控制HTTP响应的核心工具——它能让你精准定义响应状态码、响应头、响应体,相比... 目录Spring Boot 3 ResponseEntity 完全使用教程前置准备1. 项目基础依赖(M

Java使用Spire.Barcode for Java实现条形码生成与识别

《Java使用Spire.BarcodeforJava实现条形码生成与识别》在现代商业和技术领域,条形码无处不在,本教程将引导您深入了解如何在您的Java项目中利用Spire.Barcodefor... 目录1. Spire.Barcode for Java 简介与环境配置2. 使用 Spire.Barco