首先,vscode本身支持debug GNU-Linux相关标准,只是说目前调试手段千奇百怪,而且标准不统一,所以很多开发者都是采用最原始的printf方式debug,这样效率低下,而这次的方法相比所有方法可以说真妙。
在开始这个之前,有必要说一下设备本身需要的一些东西:
1. 必须要支持带符号的应用程序,这需要编译时-g选项
2. 嵌入式设备必须能通过多种途径执行gdbserver,这意味着必须有足够的静态存储器空间存放gdbserver或者能够支持远程挂载
3. 本文已经在Linux内核开启了nfs的子模块编译选项,设备内支持了nfs远程挂载操作,这便利了嵌入式设备的调试。
4. 本文已经调通了没有vscode的方式,在shell下执行gdb远程调试。
GDB远程调试
需要支持的流程:
1. 首先在设备上可以执行本编译链编译的gdbserver,宿主是被调试的设备,比如arm架构处理器,本文处理器是armv7。
2. gdbserver端的启动方式很简单,命令如下:
Ipad=192.168.11.187
/home/gdbserver ${Ipad}:12345 ${runobj}
其中/home是我的nfs挂载点,当然只要能静态存放的任意位置都可以。
Ipad是本机的ip地址,可以通过ifconfig等多种方式知道被调试设备的ip,不赘述。
12345是监听的端口,${runobj}是可执行程序的路径,这个程序一般很大,会通过工具链的strip工具裁剪掉调试信息以减而体积,当然未裁剪的程序可作为gdb端的参考程序。
启动后,gdbserver会打印开始监听。
3. 在调试端启动gdb,gdb为linux的elf格式文件,实际gdb宿主为linux系统,另外需要注意自己宿主的处理器架构,本文是x86服务器,因此任意的x86-linux服务器可以启动gdb。
gdb ${obj}
进入命令行后链接gdbserver:
target remote 192.168.11.187:12345
如果网络正确配置,则两边即可通信成功,gdb会进入start断点,输入continue或者c程序正式启动!
VSCODE如何调试参与进来
由于vscode需要执行x86-linux程序,因此vscode作为调试端落地于ubuntu图形系统
1. 首先安装基础的c/c++插件,通过插件市场安装“C/C++ Extension Pack”
需要注意的是本人也会用clangd去辅助阅读代码,这个插件的"C/C++ IntelliSense"和"clangd"是冲突的,因此解决方案本地安装“C/C++ Extension Pack”,而服务器上安装clangd,二者并不会因此冲突,只需断开远程连接则可正常使用debug功能。
2. 编辑vscode debug文件:.vscode/luanch.json
在vscode左侧点击小甲虫debug按钮,进入在工程目录下创建一个luanch.json文件,下面是我的关键参考,红色是需要注意的地方
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch", //这个是个title
//"preLaunchTask": "Build", //在launch之前运行的tasks.json任务名,实际就是build环节,这里我有构建环境,因此注释掉
"type": "cppdbg", // 这个选项对应安装的插件
"request": "launch",
"program": "/home/work/srv/Git/Maxwell/myfile", //需要运行的文件
"args": [],
"stopAtEntry": false, // 选为true则会在打开控制台后停滞,暂时不执行程序
"cwd": "${workspaceFolder}", // 当前工作路径:当前文件所在的工作空间
"environment": [],
"externalConsole": true, // 是否使用外部控制台,选false的话,我的vscode会出现错误
"MIMode": "gdb",
"miDebuggerPath": "/home/work/srv/arm-sigmastar-linux-uclibcgnueabihf/arm-sigmastar-linux-uclibcgnueabihf-9.1.0/bin/arm-sigmastar-linux-uclibcgnueabihf-gdb", // 完整拷贝过来全套工具链,vscode调用这个调试
"miDebuggerServerAddress": "192.168.11.187:12345", // 参考上面gdb调试端参数
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}]
}
3. 在小甲虫的sheet页,左上角能找到 确认好是这个luanch.json,然后点击右三角箭头启动gdb,如果没有问题,则除了完成上面的gdb远程连接流程外,vscode界面也会对应启动。
4. 如果停留在start函数,则在界面正上方点击蓝色的右三角箭头执行run,这个操作和标准gdb一致。
5. 如果要暂停gdb,则点击暂停按钮,能看到当前运行堆栈。
在Vscode上查看程序堆栈
1. 左下角有"Call Stack",标记了进程内各线程,点击展开可以查看各线程栈、变量
2. 在点击各栈帧时,一般会跳出对应代码,如果采用的是vscode server方式连接,则vscode调试环境直接是远程服务器,不需要做处理。但我的代码在服务器上,而调试器在本地,故为了方便调试,可以采用ln -s大法模拟,例如我的远程服务器根目录绝对为/home/remote,我使用cifs工具通过samba协议挂载远程目录到我本地/home/work/srv:
ln -s /home/remote /home/work/srv
因此我本地也模拟了一个/home/remote和服务器的/home/remote一摸一样的路径,vscode就可以正常访问到了,这是一个非常有用的技巧。