一.编译

1
2
3
4
5
6
7
sudo apt install gcc g++ gdb

gcc -E main.c -o main.i # -E生成预处理后的文件
gcc -S main.i -o main.s # -S生成汇编文件
gcc -c main.c -o main.o # -c生成目标文件
# 一步到位,直接生成可执行程序
gcc main.c -o main

条件编译

1
2
3
#if			#endif
#ifdef #endif
#ifndef #endif
  1. 调试信息
1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main(){
#ifdef DEBUG
printf("一些调试信息");
#endif
return 0;
}
//-D参数进行DEBUG宏定义 将会输出调试信息
gcc main.c -o main -DDEBUG
  1. 避免头文件重复包含
1
2
3
4
5
6
7
#ifndef WANGDAO
#define WANGDAO
struct Student{
int age;
float weight;
};
#endif

二.调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
gcc main.c -o main -Wall -g
# 进入jdb
jdb main
# 查看代码
list
# 设置命令行参数
set args A B C

# 在调试页面查看源代码
layout src
# 查看汇编代码
layout asm
# 切换到上一个布局
layout prev
# 切换到下一个布局
layout next
# 查看寄存器值
layout regs
  1. 走一走
1
2
3
4
5
6
7
8
9
run/r
# 执行下一行代码 遇到函数调用,直接执行整个函数
next/n
# 单步调试,会进入到函数里面
step/s
# 执行完当前函数,回到调用者
finsh
# 执行到下一个断点
continue/c
  1. 停一停
1
2
3
4
5
6
7
8
9
10
11
# 设置断点
break/b
b main #通过函数名打断点
b 7 #通过行号打断点
# 查看断点信息
info break/i b

# 删除断点
delete/d 1 #断点编号
# 忽略断点 常用于循环
ignore/i 断点编号 次数
  1. 看一看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 打印sum的值
print/p sum
# 打印指针指向数组的信息 @长度
print *p@10
# 修改值
print sum=100
# 自动展示表达式
display sum
# 查看有多少自动展示表达式
info display
# 删除自动展示表达式
undisplay 编号
# 显示所有局部变量
info locals
# 显示实参
info args
# 查看寄存器值
info registers

Coredump文件

1
2
3
4
5
6
7
8
9
# 允许生成core文件
ulimit -a
ulimit -c unlimited

sudo vim /etc/sysctl.conf
# %e:executable-name %s:signal %t:time
kernel.core_pattern = %e_core_%s_%t
# 让配置生效
sudo sysctl -p

常用命令

1
2
3
4
5
6
7
8
gdb 可执行程序 core文件
# 查看栈信息
backtrace/bt
# 查看具体栈帧
frame 1
info locals #查看局部变量
info args #查看实参
info registers #查看寄存器值

三.Makefile

自动编译、增量编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
目标: 依赖
命令
main: main.o add.o sub.o mul.o div.o
gcc main.o add.o sub.o mul.o div.o -o main
main.o: main.c algs.h
gcc -c main.c -Wall -g
add.o: add.c algs.h
gcc -c add.c -Wall -g
sub.o: sub.c algs.h
gcc -c sub.c -Wall -g
mul.o: mul.c algs.h
gcc -c mul.c -Wall -g
div.o: div.c algs.h
gcc -c div.c -Wall -g

make [目标]

伪目标

1
2
3
.PHONY: clean
clean:
rm -rf *.o main