在Ubuntu中用不了Visual Studio, 又不习惯在终端中调试,那就用宇宙第一编辑器vscode来调试代码吧~


1、必要的插件

安装插件:C/C++,其作用是提供对接gdb的接口【参考文献1
在这里插入图片描述

2、生成可调试GDB文件

任务描述:利用CMakeLists.txt设置生成支持调试的.gdb文件,进而可以对代码进行调试【参考文献2

2.1 在CMakeLists.txt中设置gdb指令

# 生成可调试执行文件
SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
......// 此处省略300个字
add_executable(DebugTest ${PROJECT_SOURCE_DIR}/main.cpp )

2.2 在build目录下编译

mkdir build
cd build
cmake ..
make

2.3 测试生成文件

通过上述两步会在build目录下生成一个可调试的可执行文件DebugTest。这时可以用linux自带的gdb调试(命令行调试模式)测试一下,生成的可执行文件是否可用。在build目录下打开终端,输入gdb ./DebugTest,进入gdb调试模式后如下图:

$ gdb ./DebugTest
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./demo...done.
(gdb) 

此时输入list指令可以看到打印出全部代码,代码过长键入回车键可以继续输出,直到全部显示出来【参考文献2】。

(gdb) list
1	#include <iostream>
2	#include "a/a.h"
3	#include <opencv2/opencv.hpp>
4	
5	#define NUM 100
6	
7	int main()
8	{
9		cv::Mat tt;
10		cv::imshow("", tt);
(gdb) 
11		cv::waitKey(0);
12		std::cout << NUM << std::endl;
13		
14		std::cout << "Hello World!" << std::endl;
15	
16	    a();
17	
18		cv::Mat img = cv::imread("/home/sz/Desktop/test/test.jpeg");
19		cv::imshow("Src", img);
20		cv::waitKey(0);
(gdb) 
21		cv::destroyAllWindows();
22	
23		return 1;
24	}(gdb) 
Line number 25 out of range; /home/sz/Desktop/test/test.cpp has 24 lines.
(gdb) 

上图就是我们的示例代码。

输入start指令开始调试。

(gdb) start
Temporary breakpoint 1 at 0x83b6: file /home/sz/Desktop/test/test.cpp, line 8.
Starting program: /home/sz/Desktop/test/build/demo 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
 
Temporary breakpoint 1, main () at /home/sz/Desktop/test/test.cpp:8
8	{
(gdb) 

其他指令如下【参考文献2

逐行调试:
n

进入函数调试:
s

查看变量数据
p 变量名

退出调试:
q

传入参数【参考文献3
set args “argv1” “argv2”
上述的argv1,argv2分别代表参数一,参数二。

3、配置.vscode

3.1 生成.vscode文件(注意前面的小黑点.)【参考文献4

1、打开源代码main.cpp,按 F5 ,然后选择第一项 C++ (GDB/LLDB)(图片来自参考文献4)
图来自参考文献4(图片来自参考文献4)

2、然后选择 C/C++: g++.exe 生成和调试活动文件...(图片来自参考文献4)
在这里插入图片描述
(图片来自参考文献4)

3、由于代码是分成多个文件,所以vscode不能直接处理,此时会报错(如果源文件只有一个main.cpp,那么这里就不会报错)。现在选择 打开"launch.json" ,并仍然选择 C++ (GDB/LLDB) ,你会发现生成了 .vscode ,并且这个文件夹下面有 launch.json 和 tasks.json 两个文件
在这里插入图片描述(图片来自参考文献4)
在这里插入图片描述(图片来自参考文献4)
在这里插入图片描述(图片来自参考文献4)

3.2 配置 tasks.json

打开 tasks.json,将 "args": [ ... ] 中的 "${file}", 注释掉,并在下面添加一行 "${fileDirname}\\*.cpp", ,表示编译的文件是源文件main.cpp所在文件夹下的所有.cpp文件,具体的可以看下图。

然后注意一下这个 "label" 标签的值 "C/C++: g++.exe 生成活动文件" ,它是编译源文件这个任务的名称,下一步会用到。【参考文献4

另外也可以看看下面的的两个参数 "-o","${fileDirname}\\${fileBasenameNoExtension}.exe" ,这表示编译生成的可执行文件的名字是DebugTest,生成的位置在工作空间的build文件夹下。因此将 "${fileDirname}\\${fileBasenameNoExtension}.exe"改为"${workspaceFolder}/build/DebugTest",目的是指明可调试的可执行程序的位置。

{
    "version": "2.0.0",
    "tasks": [{
            // "label": "compile",
            "label":  "C/C++: g++.exe 生成活动文件",
            "command": "g++",
            "args": [
                "-g",
               // "${file}",
               "${fileDirname}\\*.cpp",
                "-o",
                // "${fileDirname}/${fileBasenameNoExtension}"
                "${workspaceFolder}/build/DebugTest"
            ],
            "problemMatcher": {
                "owner": "cpp",
                "fileLocation": [
                    "relative",
                    "${workspaceRoot}"
                ],
                "pattern": {
                    "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                    "file": 1,
                    "line": 2,
                    "column": 3,
                    "severity": 4,
                    "message": 5
                }
            },
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

3.3 配置 launch.json

3.3.1 基础配置

打开 launch.json ,点击右下角的 添加配置 ,选择 C/C++: (gdb) 启动 ,在生成的代码中添加一行 "preLaunchTask": "C/C++: g++.exe 生成活动文件", ,这就是3.2中 tasks.json 那个 "label" 的值,"preLaunchTask" 代表预启动的任务,表示每次调试或运行之前就会先对源文件进行编译。

另外,你也可以选择不添加 "preLaunchTask": "C/C++: g++.exe 生成活动文件", ,这样的话,就需要运行程序前先对程序进行编译,编译的快捷键是 ctrl+shift+B ,然后才能 ctrl+F5 运行或 F5 调试。【参考文献4】(图片来自参考文献4)
在这里插入图片描述 (图片来自参考文献4)

3.3.2 可执行文件路径配置

launch.json 中,"program" 标签需要的参数是可执行文件的路径。在3.2中我们提到生成可执行文件的位置在工作空间的build文件夹下。因此,这里的 "program" 的值改为 "${workspaceFolder}/build/DebugTest"

{
    "version": "0.2.0",
    "configurations": [
        {
            "preLaunchTask":  "C/C++: g++.exe 生成活动文件",
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/ROSEFusion",
            "args": ["./example_camera.yaml", 
                            "./example_data.yaml",
                             "./example_controller.yaml"],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description":  "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        },
     ]
}
3.3.3 传参配置

launch.json 中的 "args": [] 标签代表传递给程序的命令行参数,如果main()函数需要命令行参数,可以在这里添加。如上图所示,给main()函数传递了三个参数,分别为./example_camera.yaml, ./example_data.yaml./example_controller.yaml

至此,返回main.cpp,设置断点,F5就可以愉快地(bushi)调试代码了~
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐