C程序调试 - oceaneys/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  - 继续执行