C++调试方法总结(VS Code & VS & dbg)

发布时间 2023-03-22 21:16:53作者: raiuny

一、 VS Code C++程序调试


1.1 配置C++运行环境

安装C/C++插件后打开C++设置界面:

选择编译器、c和c++标准,以及inteliSenseMode之后会在当前.vscode目录下生成一个c_cpp_properties.json文件,打开后如下所示:
linux

windows

代码文件结构规定:

├── include
│   └── *.h
├── out
│   └── app.exe
└── src
    └── app.cpp

1.2 编写launch.json文件

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [

        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/../out/${fileBasenameNoExtension}", // 可执行文件所在目录
            "args": [], // 可添加可执行文件后的参数
            "stopAtEntry": false,
            "cwd": "${fileDirname}/..", // src所在目录
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build", 
		// 在dbg前需要进行一项构建任务,任务名叫build,因此在tasks.json中要定义label="build"的task
        }
    ]
}

1.3 编写tasks.json文件

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "build", // 根据launch.json可以指定不同的构建任务,名字应与前面的preLaunchTask一样
            "command": "g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-I",
                "include", // 需要包含的目录(头文件所在目录)
			// 如果用到静态库可以用-L指定静态库所在目录,-l指定要包含的静态库名称
                "-o",
                "${fileDirname}/../out/${fileBasenameNoExtension}" // 可执行文件输出目录
            ],
            "options": {
                "cwd": "${fileDirname}/.." //src所在目录
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}



二、 VS C++程序调试

思路同上,在解决方案的属性中设置一下,需要包含相应头文件目录、链接库目录lib or dll(.a or .so所在目录)、指定工程所需的静态链接名xx.lib or xx.a、动态链接库放在对应的位置,然后按F5调试即可。



三、 dbg 调试总结

dbg ./out/main.exe # 对main可执行文件进行dbg调试,这个属于启动调试
./out/main.exe # 先启动程序然后命令行输入dbg attach main进程的进程号,即可对main进行附加调试

3.1 breakpoint

打断点

b 行号
b 文件名:行号
b 函数名:行号
b 位置 if condition

i b # 查看断点
r # 运行
c # 继续

d 断点编号、断点范围、all全部断点 # 删除断点
clear 函数名、函数名带参数、行号、文件名:行号 # 删除断点
disable 断点编号(或者范围用n1-n2表示)
enable 断点编号或范围n1-n2
enable once 断点编号 # 只启用一次断点
enable count 数量n 断点编号 # 只启用n次断点
ignore 断点编号 次数n # 过断点n次后才启用

save breakpoints <file> # 保存断点
source <file> # 根据保存断点的文件恢复断点

3.2 examine

查看地址

x /2bx &cnt # 从cnt地址开始查看后面两个内存地址,用16进制表示
x /2bc &cnt # 用char表示,查看两个char字符
x /2bs &cnt # 用字符串,查看两个字符串,起点位置为&cnt

# 格式
x /<length><format> <address>

3.3 gdb执行命令

r # 启动
c # 继续
s # 单步进入
n # 单步跳出,下一步
finish # 完成本函数
where # 显示当前执行的具体函数和代码

kill # 停止程序
quit # 退出gdb,简写为q

attach 进程号 # 附加进程方式调试
detach # 退出附加调试

3.4 gdb查看命令

bt # backtrace 显示调用堆栈信息
bt 堆栈数 # 显示指定数量的堆栈
bt -堆栈数 # 从大到小的编号显示堆栈
bt full # 显示所有堆栈的局部变量
f # 显示当前栈帧
up n # 上移n个位置
down n # 下移n个位置
info locals # 查看当前帧的局部变量

print 变量名 # 查看变量值 (文件名:变量名)
ptype 变量 # 查看变量类型
ptype 数据类型 # 查看类型信息
set print pretty # 格式化结构体输出
set print array on/off # 数组友好显示与否

3.5 gdb远程调试

1. 启动gdbserver,指定端口号

gdbserver host:port program [arg1 arg2 ...]

2. 本地机器上打开gdb,连接到远程服务器

gdb program
target remote host:port
3. 本机上进行调试,和本地调试一样
(gdb) break main
(gdb) run
(gdb) next
(gdb) print variable
...

3.6 Release & Debug版本调试

g++ -g main.cpp -o main # 输出的为debug版本(无编译优化)
g++ main.cpp -o main # 输出的为release版本(release版本还会有编译优化的参数)

3.7 core文件调试分析

gcore xxx.core # 生成core文件
gdb debug模式下的可执行文件 core文件 (例: gdb ./debug/main xxx.core)
gdb对core文件调试分析:

  1. 用i thread查看线程情况;
  2. thread num切换到num编号的线程;
  3. f num打印num编号的栈帧信息,分析问题。