目录
- 准备程序
- 配置vscode的json文件调试
- 使用GDB命令行调试
- 使用core文件调试
一般来说,Linux下做C++开发都是用vscode远程连接的方式,这时候调试有三种方式:配置vscode的json文件调试、GDB命令行调试、通过core文件调试。
关于这三种调试方法的示例都是基于cmake开发下,也适用不用cmake开发的情况,就不一一演示了,道理都是相通的。
准备程序
这是项目的整个目录,初始只有三个文件,main.cpp、sum.h、CMakeLists.txt
// main.cpp
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include <string.h>
#include "sum.h"
int main(int argc, char** argv)
{
int a = std::stoi(argv[1]);
int b = std::stoi(argv[2]);
std::cout << sum(a, b) << std::endl;
std::unordered_map<int, int> mp;
mp.insert({ 1, 2 });
std::cout << mp[1] << std::endl;
std::vector<int> vec;
vec.push_back(1);
std::cout << vec[0] << std::endl;
return 0;
}
// sum.h
#pragma once
#include <iostream>
int sum(int a, int b)
{
for (int i = 0;i < 10;i++)
a += b + i;
return a;
}
// CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(main)
# 添加调试信息
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++11")
# 链接头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
# 链接cpp文件
add_executable(main ./src/main.cpp)
# 生成可执行程序到bin目录下
set_target_properties(main PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin"
)
配置vscode的json文件调试
通过vscode配置json文件调试其实只需要一个launch.json文件即可,tasks.json是用来生成编译的,但是我们在linux下做开发要么用cmake命令编译,或者g++命令行编译,所以这个文件可以不需要。
第一步
打开main.cpp进行操作,其他文件不行。
第二步
点击 运行 -》添加配置 -》选择C++(GDB/LLDB)
这样就会在.vscode下生成一个launch.json文件
我们主要关心箭头指向的两个参数,
program:可执行程序的路径+名称
args:调试时需要给main函数传入的参数
我们这个程序的可执行文件会生成在bin目录下,调试时我们传入的参数为1、2,所以我们这个文件就可以这样写:
打开终端,通过cmake命令生成可执行文件。
cd build
cmake ..
make
之后就可以在main函数里打断点,点击F5或者运行-》启动调试 开始调试。
左侧会自动监视变量的值,可以看到a和b的值是我们传进去的1和2。
使用GDB命令行调试
推荐一些常用的GDB调试命令:
1、编译项目时添加-g选项,可执行程序会带有调试信息
2、gdb + 可执行程序文件名 开始调试程序
3、调试技巧
-
打断点:
1、break 文件名:行号
2、break 类名称::方法名 -
启动调试
1、start:从main函数第一行代码开始执行
2、run:程序开始执行直到命中断点 -
查看断点:info break
-
查看代码,默认查看十行:list,简写l
-
查看调用堆栈:backtrace,简写bt
-
打印变量名:print 变量名,简写 p 变量名
-
进入函数:step,简写s
-
单步调试:next,简写n
-
设置main传入的参数:set args 1 2,传入的参数为1和2
-
继续执行直到下一个断点或程序结束:continue,简写c
-
取消断点:clear + 断点编号或clear + 文件名:行号
-
退出:quit
使用core文件调试
使用core文件调试适用于程序挂掉的情况下,我们修改一下main.cpp的代码,让程序挂掉。
// main.cpp
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include <string.h>
#include "sum.h"
int main(int argc, char** argv)
{
int a = std::stoi(argv[1]);
int b = std::stoi(argv[2]);
std::cout << sum(a, b) << std::endl;
std::unordered_map<int, int> mp;
mp.insert({ 1, 2 });
std::cout << mp[1] << std::endl;
char* p = nullptr;
strcpy(p, "hello world"); // 让程序挂掉
return 0;
}
1、使用ulimit命令生成core文件并控制大小,使用以下命令将core文件大小设置为无限制,运行程序,会在bin目录下生成core文件
ulimit -c unlimited
2、gdb + 可执行程序名 + core文件名 调试
可以看到它在main.cpp的第22行挂掉,该行的代码是
strcpy(p, "hello world");
因为我们给一个空指针拷贝内容,程序崩溃。