C程序调试 - HeavyYuan/A-CD-Record-Management-System GitHub Wiki
两种方法,但都需要重新构建编译。
-
在源文件中增加调试信息打印的宏开关。
-
在gcc编译时带上-Dmacro参数
#include <stdio.h>
int main()
{
#ifdef HEAVY
printf("heavy\n");
#endif
}
编译构建:
gcc -o test test.c -DHEAVY
输出:
heavy
-
定义调试打印级别
-
在合适的代码位置指定不同的打印级别
-
编译构建时带上参数: -DLEVEL=debuglevel
#include <stdio.h>
#define BASIC_DEBUG 1
#define EXTRA_DEBUG 2
#define SUPER_DEBUG 4
#ifndef LEVEL
#define LEVEL 0
#endif
int main()
{
printf("No debug info\n");
#if (LEVEL & BASIC_DEBUG)
printf("BASIC_DEBUG\n");
#endif
#if (LEVEL & EXTRA_DEBUG)
printf("EXTRAL_DEBUG\n");
#endif
#if (LEVEL & SUPER_DEBUG)
printf("SUPER_DEBUG\n");
#endif
}
编译构建:
gcc -o test test.c
运行结果:
No debug info
gcc -o test test.c -DLEVEL=1
运行结果:
No debug info
BASIC_DEBUG
gcc -o test test.c -DLEVEL=3
运行结果:
No debug info
BASIC_DEBUG
EXTRAL_DEBUG
gcc -o test test.c -DLEVEL=7
运行结果:
No debug info
BASIC_DEBUG
EXTRAL_DEBUG
SUPER_DEBUG
-
为程序增加全局调试变量,如:debug
-
在程序中增加调试信息,如:
if(debug){
sprintf(msg,...);
write_debug(msg);
}
- 优化程序代码,适配调试参数的输入,如:用户带参数-d启动程序,就开启了调试模式
个人经验看来,linux上的大型系统都用了类似这种方法,不需要重新编译构建程序,如libvirtd
#include <assert.h>
void assert(int expression);
expression 为零,assert会向stderr上打印诊断信息,并且abort程序
在编译构建程序时添加-g参数,可以获得更丰富的调试信息。
进入gdb调试:
gdb ./exec
基本命令:
h - 获取帮助
r - 运行程序
b - 设置断点
b fun
b fun:line
b file:line
n - 单步执行,不进入待执行的函数
s - 单步执行,进入待执行的函数
bt - 打印函数栈
构建时添加-g参数,可以获取更丰富的函数信息
p - 打印变量
l - 列出源代码(围绕当前位置)
c - 继续执行