今日内容:gcc编译器、gdb调试器
一、Linux下文件编译与调试
1、安装gcc?使用命令sudo apt install gcc
2、如何处理网络图标不见?按照CSDN的教程
3、如何查看gcc版本?使用命令gcc- v
4、编译的过程
(1)预编译(.c->.i):预处理器将对源文件中的宏进行展开gcc -E test.c -o test.i,会发现int i=2+3*2+3
(2)编译(.i->.s):将C文件编译成汇编文件gcc -S test.i -o test.s
(3)汇编:将汇编文件编译成机器码as test.s -o test.o
(4)链接(.s->exe):将目标文件和外部符号进行连接,得到二进制文件gcc -o test test.o
(5)在整体编译完毕后,会生成一个名字为test的文件,输入命令./test,即可运行该文件
5、直接执行gcc操作,使用命令gcc test.c,之后生成a.out文件;如果不指定参数,系统默认生成的文件名叫做a.out,如果想要令生成的文件叫做其他名字,可以使用命令gcc test.c -o b.out
输入命令./a.out即可运行a.out文件
6、VIM中在命令模式下,输入x的功能和wq一样,输入X的功能是加密文件
7、在Linux中严格区分大小写
8、gcc的静态库和动态库
(1)ldd可以判断出函数依赖的动态库,例如输入命令:ldd /bin/ls,或者输入命令ldd test.c
意思是显示出ls命令的动态库
(2)库函数中不可以有main函数,因为库函数的功能是提供给被人调用,所以不能有main函数
(3)创建动态库
①gcc -fPIC -Wall -c add.c -o add.o 生成add.o文件,并启用wall警告
②命令gcc -shared add.o -o libadd.so创建动态库
③usr/lib是系统默认的lib搜索路径,普通用户没有权限,对该路径进行操作时,需要使用sudo权限
④头文件里边只是函数声明,
(4)动态库原理
①main.c调用libadd.so函数,最后生成一个可执行程序main
②动态库又被称作共享库,这样的话,可以减少系统内的内存存储
③现在静态库用的越来越少了,动态库用的比较多
④动态库的版本升级较为方便,静态库版本升级较为繁琐
⑤如果依赖的是静态库,那么编译的时候相当于直接把静态库的文件拷贝到main.a 文件里边了,所以在后续的执行过程中,就不再需要加载静态库了。因此,如果在编译完成后删除掉静态库,不会影响后续的执行过程。
⑥使用静态库带来的影响就是,静态库会占用大量的存储空间,包括在程序的编译过程中,会浪费大量的时间,在一个简单的程序执行过程中都需要加载静态库的内容,比较繁琐,因此现今已经很少使用静态库了。
⑦使用静态库的一个优点就是:容易部署,因为在执行过程中不再依赖其他动态库,所以很少会缺少依赖文件。但是升级较为困难。
9、gcc优化选项
(1)参数-O,来控制优化级别。优化选项还分O1、O2、O3等不同选项
(2)-O的编译优化选项不可以和-g一起使用,因为使用-g是为了调试程序
二、gdb调试器
1、如何看是不是安装了gdb?使用命令gdb-v
2、atoi什么意思?用法int atoi(const char *str),将字符串str转换成一个整数并返回结果,例如int atoi (512.23),转换结束后输出512
3、复习main(int argc,char *argv[])
4、gdb调试器,按q退出,在编译时选择gcc- g main.c才可以进入调试模式
之后摁gdb a.out可以进入调试过程
5、参数命令详解
(1)命令show paths,显示当前的工作路径
(2)命令pwd,显示当前路径
(3)命令ls不可以直接运行,需要使用命令shell ls
(4)打断点则需要在gdb中输入b 23,意思是在第23行打断点,断点过后还需要手动取消
(5)临时断点命令tb 3,意思是在第3行加一个临时断点。临时断点运行过后自动消失
(6)info b,重新启用断点
(7)改变断点的表达式,命令condition [断点号] <条件表达式>,例如 b 23 if i==2
(8)命令ignore [断点号]<num>,在程序执行过程中,忽略对应断点num次
(9)命令delete 7,意思是在第7行增加一个断点
(10)命令file,加载指定文件
(11)程序崩溃,gdb调试core文件
① gcc -g crash.c 先开启调试模式编译
②ulimit -a 查看设置
③ulimit -c unlimited 设置文件可启动文件数量
④gcc -g crash.c 重新编译
⑤./a.out 查看a.out文件
⑥ll 查看文件信息
⑦gdb a.out core 调试core文件
⑧bt 看堆栈信息
6、gdb调试命令列表
序号 | 命令格式 | 含义 |
1 | set args | 设置运行时的参数,如set args 2 |
2 | show args | 查看设置好的运行参数 |
3 | path dir | 设定程序的运行路径 |
4 | set environment var[=value] | 设置环境变量 |
5 | show environment [var] | 查看环境变量 |
6 | cd dir | 进入到dir目录,相当于shell中的cd命令 |
7 | pwd | 显示当前工作目录 |
8 | Shell conmand | 运行shell的command命令 |
9 | info b | 查看所设断点 |
10 | break[文件名:]行号或函数名<条件表达式> | 设置断点 |
11 | tbreak[文件名:]行号或函数名<条件表达式> | 设置临时断点,到达后被自动删除 |
12 | delete[断点号] | 删除指定断点,其断点号为“info.h”中的第一栏,若缺省断点号则删除所有断点 |
13 | disable[断点号] | 停止指定断点,使用“info.h”仍能查看此断点,同delete一样,省断点号则停止所有断点 |
14 | enable[断点号] | 激活指定断点,即激活被disable停止的断点 |
15 | condition[断点号]<条件表达式> | 修改对应断点的条件 |
16 | ignore[断点号]<num> | 在程序执行中,忽略对应断点num次 |
17 | step | 单步恢复程序运行,且进入函数调用 |
18 | next | 单步恢复程序运行,但不进入函数调用 |
19 | finish | 运行程序,直到当前函数完成返回 |
20 | c | 继续执行函数,直到函数结束或遇到新的断点 |
21 | list<行号>|<函数名> | 查看指定位置代码 |
22 | file[文件名] | 加载指定文件 |
23 | forward-search正则表达式 | 源代码前向搜索 |
24 | reverse-search正则表达式 | 源代码后向搜索 |
25 | dir dir | 停止路径名 |
26 | show directories | 显示定义了的源文件搜索路径 |
27 | info line | 显示加载到gdb内存中的代码 |
28 | print 表达式|变量 | 查看程序运行时对应表达式和变量的值 |
29 | x<n/f/n> | 查看内存变量内容,其中n为整数表示显示内存的长度,f表示显示的格式,n表示从当前地址向后请求显示的字节数 |
30 | display 表达式 | 设定在单步运行或其他情况中,自动显示的对应表达式的内容 |
31 | backtrack | 查看当前栈的情况,即可以查到调用哪些函数尚未返回 |
三、shell编程
相当于一门新的语言,所以刚开始学习的时候有点难
1、如何学习?
(1)基本数据类型
(2)基本语法规则