说到Linux环境程序的调试,当然离不开gdb。但是程序编码阶段的调试大多人都首选printf,而非gdb,原因是gdb确实比较麻烦。
但是关键时候gdb还是很有用的,比如下面几个情况:
1.程序长时间运行会出现崩溃,走读代码bug难以定位。
这样的问题通过打印定位问题可不是好办法,特别是程序代码量比较大的时候,这时候可以利用linux的程序崩溃跟踪机制,gdb派上用场。
Linux环境下有这么一种进程退出跟踪机制,在程序崩溃时,把程序崩溃时的堆栈信息保存成文件,然后可以使用gdb打开该文件,查看程序堆栈信息,快速定位程序退出原因。
一般系统默认是不打开该机制的,使能该机制需要手动配置一下环境变量
ulimit -a
ulimit -c unlimited
环境变量是终端独立的,程序需要在该终端中运行,崩溃后会在程序执行目录生成名为core或者core.pid的文件,与系统配置有关。
发现程序退出后,就可以使用gdb定位问题了
gdb ./bin core
进入gdb调试之后,输入
bt
可以查看程序退出时的堆栈信息了,通过up、down退出和进入函数调用,同时也可以通过
p variable name
查看变量值。
注意编译时加 -g 和最好使用 -O0,这样方能查看更多程序信息。
2.程序长时间运行,发现有一个线程CPU占用率特别大,不清楚是哪个线程,这时也可以使用gdb进行跟踪定位。
不过使用gdb之前得知道该CPU占用率高的线程的进程号,top命令可以查看CPU使用率等信息,就跟windows下个资源管理器一样,
但一般都是整个进程的运行信息,如何查看各个线程的信息呢,在top运行起来后,输入大写H,就可以看到线程级的运行信息了,
各个线程的CPU使用率更是一目了然,PID即是我们需要的线程的进程号。打开gdb
gdb
之后输入
attach pid
该线程就被挂接到gdb调试环境中了,当然线程也就停止了,输入
bt
就可以根据堆栈信息得知该线程到底是哪个线程啦,最后别忘了取消对线程的挂接。
detach
程序继续运行。
当然gdb功能远不止这些,有待积累整理……