在linux下开发难免会遇到bug,但是由于没有图形IDE,导致debug也变得困难,其实只要掌握一些常用的debug工具,一些错误就能很快解决,本文就介绍一些常用的工具用以调试:
log
输出log永远是最简单快捷的调试方式,可以快速定位bug,通过设置日志级别控制日志的输出详略程度,结合一些文本分析工具awk/sed/grep可以快速在大量日志中找到错误信息。
strace
是一个用来跟踪系统调用的简易工具。它最简单的用途就是跟踪一个程序整个生命周期里所有的系统调用,并把调用参数和返回值以文本的方式输出。Strace还可以跟踪发给进程的信号。支持attach正在运行的进程 strace -p <pid>, 当多线程环境下,需要跟踪某个线程的系统调用,可以先ps -efL|grep <Process Name> 查找出该进程下的线程,然后调用starace –p <pid>进行分析。
pstack
用来跟踪进程栈,比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方;
gdb
经典的调试工具,功能很强大,注意此时编译的时候应该使用-g选项,并用-Og进行优化。多线程下可以attach到进程来调试。
core dump文件
在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写到core文件中,例如我们平时的非法访问内存产生segment fault错误,利用gdb可以查看到到底是哪里发生了异常。有时候可以人为的向进程发送信号kill -11 <pid>,查看此时系统运行的状态,例如多线程下程序突然停住了,此时就可能发生了死锁,可以人为的产生信号,再来分析core dump。
valgrind
包含很多工具:
Memcheck。这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。这也是本文将重点介绍的部分。
Callgrind。它主要用来检查程序中函数调用过程中出现的问题。
Cachegrind。它主要用来检查程序中缓存使用出现的问题。
Helgrind。它主要用来检查多线程程序中出现的竞争问题。
Massif。它主要用来检查程序中堆栈使用中出现的问题。
Extension。可以利用core提供的功能,自己编写特定的内存调试工具。
默认使用的就是memcheck工具,在c++中指针的使用,一不留神就会产生异常,就可以利用memcheck进行检查。个人一般用--track-origins=yes来定位未初始化变量的位置。
tcpdump
抓包用的,在开发网络应用的时候很给力,结合awk/sed/grep可以快速查找网络数据包。
stackoverflow
这个网站是个程序设计领域的问答网站,基本碰到的问题都能在这里面找到答案! 技术氛围很强,从中能学到很多东西。
大型c++项目在linux下如何调试?
https://www.zhihu.com/question/26905808
逻辑错误用log,内存错误用gdb,单元测试用gtest,编译器用clang,log框架用log4cplus,性能热点用gprof,这样就没有搞不定的bug
补充一条,内存错误用valgrind,但我一直觉得习惯良好的C++代码永远不会犯内存错误
Linux上调试c++, 给大家推荐gdbgui.
大型网络项目,几十个厂家合作,我们的方法是gdb,core文件,tcpdump,valgrind,vim+各种正则表达式+完善的log,依靠这些工具调试完全能hold住啊,想想这个项目用IDE还是挺奇怪的啊。。还是不懂为什么要用IDE。。没用过IDE调试大型项目,求解释。。
1.开发机
方案一: 装一个xfce桌面加clion,使用vnc直接开发+调试
方案二: 安装remote gdb,开放调试端口,windows上使用clion attach上去(需要自己编译gdb,此外vscode和vs的remote debug都是残的)
2.线上环境
直接gdb(仅限 Core Dump)
更多时候看的log来定位问题
打log,gdb,strace,ltrace,pstack,stap脚本,perf
具体看调试的程序是不是线上的服务,能不能停,看情况选择方法
还有我大部分调的是C的,C++调的少