VS 的性能剖析器可以很方便在选定的代码之间(用断点或者别的什么控制)进行性能剖析,这个功能在大型项目里是十分重要的。linux 有比 win 下更强的,更深入的性能剖析器,但是很遗憾,pref 之类的这些剖析器都是输出整个程序运行的信息的,反而会让你找不到需要关键信息。
找了很久,最后在 VisualGDB 的相关手册中找到了实现类似功能的方法,参考链接。里提到了其实使用 valgrind 实现类似的功能的,而且很重要的一点是不需要特制的 valgrind,也就意味我不用插件,仅用 valgrind 也能做到类似的功能。
经过在 valgrind 的手册里查找,发现是 callgrind 提供了类似的功能。参考链接 , 从
6.2.1. Multiple profiling dumps from one program run
开始看
一般步骤
相关操作代码和功能可以在手册里进一步了解。这里大致的说一下步骤
-
编译好你的程序
-
起一个 valgrind 的进程
valgrind --tool=callgrind --vgdb-error=0 /your/progam/path
valgrind 初始化成功后会有类似提示
==103479== TO DEBUG THIS PROCESS USING GDB: start GDB like this ==103479== /path/to/gdb ./main ==103479== and then give GDB the following command ==103479== target remote | /usr/bin/vgdb --pid=103479 ==103479== --pid is optional if only one valgrind process is running
103479 是 valgrind 当前的进程id,每次都会不同,它也会提示你在 gdb 里输入
target remote | /usr/bin/vgdb --pid=103479
链接到 valgrind 的 gdbserver工具使用callgrind, '--vgdb-error=0'意思是 valgrind 在遇到0个错误的时候停下运行程序,也就是一开始就停止运行程序,因为后面需要把 gdb 挂上去
-
另起一个进程 gdb, 链接进 valgrind 的 gdbserver
gdb /your/progam/path
可以看到 gdb 启动后就在等待指令了
..... Reading symbols from ./main... (gdb)
这时候往 gdb 里输入
target remote | /usr/bin/vgdb --pid=103479
就能看到 gdb 提示进入远程调试了(进入 valgrind 的 gdbserver)Remote debugging using | /usr/bin/vgdb --pid=103479 relaying data between gdb and process 103479
也可以在启动 gdb 的时候直接一步到位
gdb ./main -ex "target remote | /usr/bin/vgdb --pid=103479"
-
打好断点,把程序停在想要开始进行性能测量的地方。怎么操作 gdb 这部分就跳过了
-
gdb 里清空 callgrind 之前的统计信息, gdb 里输入
monitor zero
-
恢复程序运行,然后停在想要结束性能测量的地方,并输出统计信息,在 gdb 里输入
monitor dump
进行 callgrind 的输出。可以在 valgrind 的运行目录看到
callgrind.out.pid.part-threadID
, 例如callgrind.out.102345.1
。接下来就可以在 kcachegrind 以图形界面查看结果,win 下可以用 qcachegrind 查看。
在 vs code 调试中使用 valgrind
在一般的 launsh.json 的 gdb 配置增加 valgrind 内容就好,例如
{
"name": "valgrind custom",
"type": "cppdbg",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
// "preLaunchTask": "valgrind-debug: custom",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "PATH",
"value": "$PATH:${command:cmake.launchTargetDirectory}"
}
],
"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
},
{
"description": "Connect to valgrind",
"text": "target remote | vgdb --pid=103479",
"ignoreFailures": true
},
]
}
注意修改为对应的 pid , 这里还搭配了 CMake Tool 插件使用,不使用的话将相关指令替换就可以了。
还有一些插件 Valgrind Task Integration
可以提供整合命令,但是卡在等待了 preLaunchTask
的返回,不知道为啥插件预设的设置无效。目前还是手动启动和输入 pid 吧。
在 vs code 的 Debug Console 窗口里则是输入指令需要额外加上前缀 -exec
-exec monitor zero