Linux下的C语言程序的调试(附案例)
写在前面本文以将gdb调试为主,顺便提一下strace和valgrind。正文strace个人感觉跟gdb相比,strace更偏向于查看,查看某程序的系统调用有哪些,统计系统调用的次数以及消耗了多少时间,还可以追踪信号。gdb总览gdb可以直接调试程序,也可以将程序和core文件一块调试,也可以调试服务程序,只需要指定对应服务程序的进程id就行了...
写在前面
本文以将gdb调试为主
#gdb使用
gdb 应用程序 core文件
#gdb之前,需要编译的时候加入 -g选项,编译之后源码位置不要改动
#对于有些开源库,可能自带debuginfo的rpm包,安装就能直接使用
gdb的使用
要使用gdb调试程序,首先编译的时候要加上-g选项,不管是g++还是gcc都要加上-g选项。下面列举一些常用命令:
- l,即list,列出十行代码并标注行号。
- r,即run,运行程序,直到结束。
- n,即next,执行一条语句。
- b,即break,设置断点,b后面跟行号,表示在第几行设断点;b后面跟函数跟函数名,代表在该函数设置断点,除此之外还可以指定在某个文件的第几行设置断点。
- p,即print,后面跟变量名称可以打印变量的值。
- bt,即backtrace,列出调用堆栈。
- finish,表示退出函数。
- q,即quit,结束调试。
关于core文件保存
ulimit -c unlimited
echo core-%e-%p-%t > /proc/sys/kernel/core_pattern
#另外说一下原始的core文件保存路径
#cat /proc/sys/kernel/core_pattern
#结果如下
/var/core/core_%e_%p
#一定要确保/var/core文件夹存在,并且不限制core文件的大小,core文件就会创建在这个目录下
mkdir /var/core
1、上面的命令:使得core文件生成无大小限制,并将core文件生成到当前目录,临时保存,当前会话有效
2、core文件 永久保存,在/etc目录中的sysctl.conf文件中最后添加如下内容: kernel.core_pattern=core-%e-%p-%t
3、ulimit 设置永久保存参考
Linux中ulimit参数的永久生效。-u -s -c_-觅-的博客-CSDN博客_ulimit设置永久生效
一些调试技巧
普通程序 (GDB 表示是gdb下的命令)
1、run(GDB)
一次性执行完程序,后面可以跟参数
2、start (GDB)
执行当前程序,从第一行代码开始执行,通常配合n命令即next,即执行下一条语句,还有s命令即Step Into单步跟踪,进入函数内部调试。
3、bt (GDB)
打印当前堆栈,对于看段错误十分有利
4、frame n (GDB)
进入当前堆栈的第n层,通常配合bt打印的堆栈层级
5、p 变量名(打印指针类型要加 * 号,如果是void*类型的指针,前面要加上(类型)才能打印)打印当前层的变量,通常配合frame使用
6、b 函数名(即断点)
打断点
7、c(即continue)
继续运行,通常配合b
服务进程
1、pgrep 服务名(SHELL命令)
先查看服务进程id,用于gdb调试,调试时使用:
gdb 服务名 进程号
gdb -p 进程号
2、info threads / info inferiors(GDB)
查看当前线程/查看当前进程
3、thread n(n代表第几个线程)(GDB)
使用,用于切换监控的线程
4、pstack pid(进程号)(SHELL命令) 或者 thread apply all bt (GDB)
查看该进程的所有线程堆栈信息
调试子进程
1、进入gdb后需要设置一些东西
set follow-fork-mode child
set detach-on-fork on
一个示例程序
test.c
#include<stdio.h>
#include<unistd.h>
void test()
{
printf("test8");
}
void main()
{
int i = 0;
printf("test1");
printf("test2");
printf("test3");
printf("test4");
printf("test5");
printf("test6");
printf("test7");
test();
}
编译命令
gcc -o test.out test.c -g
调试命令
gdb test.out
进入界面,输入
fs cmd
可以打印代码框
输入
l
#list,打印代码
打印当前代码
输入
b 9
#break,在第9行打断点
r
#run,直接跑程序
输入
n
#next,跑下一行命令
一直敲回车运行下一条命令,直到运行到test函数前
敲命令
s
#Step Into, 进入函数内部调试
可以看到函数来到了第五行
输入r运行完程序,输入quit退出gdb。
更多推荐
所有评论(0)