gcc编译
gcc编译可以分为四个步骤,预处理、编译、汇编、链接。
- 预处理命令:gcc -E hello.c -o hello.i
- 编译命令:gcc -S hello.i -o hello.s
- 汇编命令: gcc -c hello.s -o hello.o
- 链接命令:gcc hello.o -o hello
gcc命令一些参数
- 指定头文件目录
gcc -I./headfile hello.c -o hello.out
- 编译时添加调试语句
需要使用gdb调试代码时需要添加该参数
gcc hello.c -o a.out -g
- 编译优化
n取值范围是[0,3],n越大优化越多
gcc -On hello.c -o a.out
- 显示所有警告信息
gcc -Wall hello.c -o a.out
- 动态添加宏定义
下面就是添加了一个名为OPEN的宏
gcc -D OPEN hello.c
静态库和动态库
使用gcc -c main.c会生成一个main.o文件,查看该文件的elf文件头信息可以发现该文件的类型为可重定向目标文件,这类文件在链接之后会变为可执行文件。
在链接时使用静态库需要指明静态库的名称
例如我需要使用libm.a这个静态库(包括一些数学函数),就要使用以下命令,lib**.a对应-lxx。
gcc -static -o main.out main.o -lm
目前编译时会默认使用动态链接,动态链接是不会将动态库打包到二进制文件中的,静态链接会将静态库打包到二进制文件中,因此静态链接生成的可执行文件一般体积较大。动态库后缀为so,例如libm.so,静态库后缀为a,例如libm.a。
gdb调试程序
- 在使用gdb调试程序时首先要保证文件是可调试的。在编译时添加-g参数。
gcc -o main.gdb main.c -g
- 调试无参程序
gdb 可执行文件名 #进入gdb命令模式
(gdb) run #运行程序
- 调试有参程序
gdb 可执行文件名 #进入gdb命令模式
(gdb) set name kunkun # 设置名为name的参数的值为kunkun
(gdb) run #运行程序
- 调试core文件
程序在运行时出现异常终止或者崩溃,操作系统会将程序当时的内存状态信息保存在core文件中,用于后续的排错,这个过程称为core dump。
ulimit -c # 检查是否可以生成core文件,返回值为0代表无法生成core文件,core文件中可能会保存一些私密信息,有泄露的风险
ulimit -c 10 # 开启生成core文件的功能,设置大小为10块( 一个块就是0.5kB)
对于有core文件生成的程序,使用以下命令调试得到错误出现的位置
gdb 可执行文件名 core文件名
(gdb) bt #显示异常出现的位置
gdb中断点的使用
- 查看已有的断点
info breakpoints
- 添加断点
b n # 在第n行添加断点
b function_name # 在函数添加断点
break main_out.gdb:n if b==0 #在第n行如果b的值为0就添加一个断点
rbreak file:regex #根据正则表达式的规则设置断点,作用于符合正则表达式的函数名
tbreak file:n #在第n行设置临时断点,使用一次后删除
ignore breaknum times #设置跳过断点次数,breaknum:断点的序号,可以使用info breakpoints命令得到序号,times:跳过该断点的次数。
watch b #根据表达式值产生断点,当a变化时会打印a的变化数据
- 禁用和启动断点
disbale/enable #禁用/启动所有断点
disable/enable breaknum #禁用/启动断点号为breaknum的断点
- 删除断点
clear #删除当前行所有的breakpoints
clear linenum #删除linenum行的断点
clear functionname#删除函数上的断点
delete #删除所有的breapoints,watchpoints,catchpoints
delete breaknum #删除指定断点号的断点
gdb调试程序命令
- run:执行程序,到断点中断。
- c/continue:继续运行程序到下一个断点停止
- n/next:运行下一条语句
- p/print 变量名:打印变量
- p/print *node@n:打印指针指向的数据, n代表长度,如果不加@n只会打印数组第一个数据。
- set $index=0;print node[$index++]:按照索引打印数组
- 按照指定格式打印数据(正斜杠+字母,例如/t代表二进制格式)
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。