编译的过程:
(1)预处理 preprocessing
处理C程序中,以#开头的行
(arm-linux-)gcc -E main.c -o main.i
==> main.i 这个文件还是C源代码程序
(2)编译 compiling
把C源代码 编译成 汇编文件
(arm-linux-)gcc -S main.i -o main.s
==> main.s 这个文件是汇编文件
(3)汇编 assembling
把汇编程序 编译生成 目标文件(机器指令)
(arm-linux-)gcc -c main.s -o main.o
==> main.o 这个文件是 二进制文件
(4)链接 Linking
把各个目标文件.o 链接生成一个 可执行文件
(arm-linux-)gcc main.o 1.o 2.o -o main
==> main 就是可执行文件
——————————————————————————————————————
遇到BUG,解决方法:
1)找到BUG出现的位置
打印相关的调试信息,去缩小范围,定位错误的位置
行号、函数名、文件名、相关变量的值
printf("line = %d, func = %s, file = %s\n", __LINE__, __FUNCTION__, __FILE__);
2)具体情况具体分析
例子:
test.c
int sum()
{
A;
printf("line = %d, func = %s, file = %s\n", __LINE__, __FUNCTION__, __FILE__);
B;
printf("line = %d, func = %s, file = %s\n", __LINE__, __FUNCTION__, __FILE__);
C;
printf("line = %d, func = %s, file = %s\n", __LINE__, __FUNCTION__, __FILE__);
D;
}
2、gdb
gdb是一个单步调试的命令行工具,它可以使你的程序,在你输入命令之后才执行
而且可以打印中间变量的值,方便调试程序
调试方法:
1) gcc -g main.c -o main
2)调试程序
gdb main
3)gdb调试指令
b breakpoint 用于设置断点
断点:程序运行到此处,就会暂停,等待用户输入命令,才继续往下执行
b line_num 用于设置line_num所代表的那一行为断点
例子:
b 6 //设置第6行为断点
b 函数名 用于设置一个函数为断点
info b 查看断点的信息
delete breakpoint 断点序号 用来删除指定的断点
(断点序号:用info b查看,并不是行号)
r run 运行代码,直到遇到断点 或者 程序结束 (重新开始执行)
n next 下一步,单步执行
s step 下一步,单步执行
n和s的区别:仅在函数调用时 有区别
n:把函数调用当作成一步,直接把函数调用运行完
s:step into 会进入到函数内部来执行
p 变量名 打印该变量的值
l list 查看源代码文件(10行)
查看指定的文件
l 文件名:行号
或者
l 文件名:函数名
help 指令 查看某个指令的帮助文档
q quit 退出