VSCode 调试 RISC

您所在的位置:网站首页 riscv编译器 VSCode 调试 RISC

VSCode 调试 RISC

2023-07-18 06:40| 来源: 网络整理| 查看: 265

前提

本文主要涉及 VSCode 的相关配置,编译及调试工具需要提前安装好。

已经安装好riscv-toolchain,包括riscv64-unknown-elf-gcc,riscv64-unknown-elf-gdb 已经安装好qemu,包括riscv32-softmmu,riscv32-linux-user,riscv64-softmmu,riscv64-linux-user 已经安装好g++,gdb 调试流程简介

对于我这样的新手,要调试一个项目源码最怕的就是开始,也就是怎么能把项目跑起来。

我们以一个简单的test项目,看看在 VSCode 里怎么跑起来。

拿到源码后,将其以文件夹形式,加入到 VSCode 中,文件 - 打开文件夹 - 选择 test 项目文件夹。项目就会在 VSCode 中打开,但是此时我们还无法编译运行,我们需要在 VSCode 上构建出一个 C 语言的编译与调试环境。

首先得安装一个插件C/C++,打开插件中心Ctrl+Shit+X,搜索,安装。

然后输入F5,会弹出对话框,选择C++(GDB),继续选择g++。VSCode 会自动创建.vscode文件夹,已经两个文件launch.json和tasks.json。

launch.json用来配置调试环境,tasks.json主要用来配置编译环境,当然也可以配置其他任务。task.json里配置的每个任务其实就相当于多开一个控制台。

配置tasks.json

因为我们先要编译源码,生成.out或者.exe文件,才能调试,所以先进行编译任务配置。

自动生成的文件是个配置模板,我们可以根据自己的实际情况进行配置,也有一部分可以保持默认。

12345678910111213141516171819202122232425// tasks.json{ // https://code.visualstudio.com/docs/editor/tasks "version": "2.0.0", "tasks": [ { // 任务的名字,注意是大小写区分的 //会在launch中调用这个名字 "label": "C/C++: g++ build active file", // 任务执行的是shell "type": "shell", // 命令是g++ "command": "g++", //g++ 后面带的参数 "args": [ "'-Wall'", "-g", // 生成调试信息,否则无法进入断点 "'-std=c++17'", //使用c++17标准编译 "'${file}'", //当前文件名 "-o", //对象名,不进行编译优化 "'${fileBasenameNoExtension}.exe'", //当前文件名(去掉扩展名) ], } ]}

如果项目是通过 Makefile 编译的,那就更加简单,只需要配置一个任务即可。

123456789101112131415{ "version": "2.0.0", "tasks": [ { //任务的名字方便执行 "label": "Make Project", "type": "shell", "command": "make", "args":[ //8线程编译 "-j8", ], }, ]}

运行该任务时就会执行make命令进行编译。

配置launch.json123456789101112131415161718192021222324252627282930313233// launch.json

{ "version": "0.2.0", "configurations": [ { //调试任务的名字 "name": "g++ - Build and debug active file", //在launch之前运行的任务名,这个名字一定要跟tasks.json中的任务名字大小写一致 "preLaunchTask": "C/C++: g++ build active file", "type": "cppdbg", "request": "launch", //需要运行的是当前打开文件的目录中, //名字和当前文件相同,但扩展名为exe的程序 "program": "${fileDirname}/${fileBasenameNoExtension}.exe", "args": [], // 选为true则会在打开控制台后停滞,暂时不执行程序 "stopAtEntry": false, // 当前工作路径:当前文件所在的工作空间 "cwd": "${workspaceFolder}", "environment": [], // 是否使用外部控制台 "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }]}

运行

经过以上配置后,我们打开main.cpp文件,在cout处打一个断点,按F5,即可编译,运行,调试。一定要打开main.cpp文件,不能随便打开文件就开始哦。因为我们在配置时使用了一些预定义,比如${file}表示当前文件,所以只有打开需要调试的文件才能开始。

程序将会在cout语句停下来。

我们可以注意一下界面下方的控制台,可以更直观了解launch.jason和tasks.jason。

右边的框,就是我们在tasks.jason中配置的任务,左边的框就是我们在tasks.jason中command以及args的内容,他就是帮我们提前写好编译的选项。然后在 shell 中运行。

编译调试 RISC-V 程序

了解以上这些,就可以按需配置所需的环境了。我们还是从tasks.jason开始。因为开发用的电脑是x86的,所以先要编译出riscv的程序,再用模拟器模拟出rsicv的环境,然后在模拟的环境中运行程序,最后才能开始调试。

假设已经安装好开头所提到的工具。首先配置tasks.jason:

1234567891011121314151617181920212223242526272829303132333435363738394041424344{ "version": "2.0.0", "tasks": [ { // 编译当前代码 "type": "shell", "label": "C/C++(RISCV): Build active file", // 编译器的位置 "command": "/opt/riscv/bin/riscv64-unknown-elf-g++", "args": [ "-Wall", // 开启所有警告 "-g", // 生成调试信息s "${file}", "-o", "${workspaceFolder}/debug/${fileBasenameNoExtension}" // 我选择将可执行文件放在debug目录下 ], // 当前工作路径:执行当前命令时所在的路径 "options": { "cwd": "${workspaceFolder}" }, "problemMatcher": [ "$gcc" ] }, { // 启动qemu供调试器连接 "type": "shell", "label": "Run Qemu Server(RISCV)", "dependsOn": "C/C++(RISCV): Build active file", "command": "qemu-system-riscv64", "args": [ "-g", "65500", // gdb端口,自己定义 "${workspaceFolder}/debug/${fileBasenameNoExtension}" ], }, { // 有时候qemu有可能没法退出,故编写一个任务用于强行结束qemu进程 "type": "shell", "label": "Kill Qemu Server(RISCV)", "command": "ps -C qemu-riscv64 --no-headers | cut -d \\ -f 1 | xargs kill -9", } ]}

tasks.jason是可以配置多个任务的,第一个任务用来编译成riscv架构下的程序,第二个任务用来启动 qemu,让程序在 qemu 上运行起来。

第一个任务中,command就是配置编译器riscv64-unkonown-elf-gcc的属性,第二个任务中,command是配置 qemu 模拟器qemu-system-riscv32的属性。第三个任务中,用来配置结束 qemu 模拟器的命令。

接下来配置launch.jason:

12345678910111213141516171819202122232425262728{ "version": "0.2.0", "configurations": [ { "name": "C/C++(RISCV) - Debug Active File", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/debug/${fileBasenameNoExtension}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true } ], // RISC-V工具链中的gdb "miDebuggerPath": "/opt/riscv/bin/riscv64-unknown-elf-gdb", // 这里需要与task.json中定义的端口一致 "miDebuggerServerAddress": "localhost:65500" } ]}

我们在配置x86下的调试环境时,launch.jason中有个"preLaunchTask": "C/C++: g++ build active file",属性,这个属性的目的是在启动调试之前,先执行任务名字为"C/C++: g++ build active file"任务,也是就编译的任务。

因为启动 qemu 会导致阻塞,所以这里没有加preLaunchTask,在启动调试之前,先把 qemu 运行起来。输入Ctrl+Shift+P,打开 VSCode 命令行。输入Run Task,

点击第一个,选择任务,我们可以看到出现的三个任务就是我们在tasks.jason中配置的三个任务。选择第一个 Build,编译出程序,再重复操作,选择第三个执行 QEMU 任务。

预定义变量

官网



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3