一、Linux调试工具gdb使用:
源代码经过编译链接生成可执行文件一般有两个版本:
- debug版本 可调式版本 链接的时候最后加上-g ,里面添加了debug_*段,
编译阶段加入debug信息,链接过程不会加入debug信息。
- 默认的release 发行版本
debug版本的可执行程序的生成:
gcc -o main main.c -g
调试命令:
l : 显示源代码(默认显示的是main函数所在文件的源代码)
list filename :num 显示指定文件,num行附近的源代码
b linenum 给指定行添加断点
b funactionname 给指定函数添加断点
b filename:linenum 给指定文件指定行号添加断点
info b 显示断点信息
d bpnum(断点号) 删除断点
disable bpnum 将断点设置为无效
enable bpnum 将断点设置为有效
b linenum if 添加一个条件断点
执行过程控制:
r 启动调试
n 执行下一步
s 进入函数中执行(逐语句)
finish 退出函数执行
c 继续运行
q 退出调试
p valname 查看变量的值
p &valname 变量的地址
p *ptr 指针指向的地址存储的值
{
int arr[10] = { …… };
int *ptrarr = arr;
}
p arr 显示属组所有的元素
r *ptrarr@num 通过指向数组的指针显示所有元素
p 结构体变量的名称 显示结构体变量所有成员的值
p 结构体变量.成员名 显示结构体变量中某个成员的值
p prt_struct à a 通过指针显示结构体变量某个成员的值
p functional(a,b) 将函数测试运行
bt 显示函数调用栈 显示函数调用流程
二、Linux上文件系统:
1、库文件:
库文件就是某些功能代码的集合,将某些特定的常用的代码,放到库里面,以后用的时候,直接使用库就好了,不用再重新写了。
windows: .lib .dll
Linux: .a .out
2、静态库:(中间文件的集合)
链接阶段直接将库中的内容合并到最终的可执行文件中,在程序运行的时候,在可执行文件中,就会有静态库的一个副本,将静态库的内容合并到可执行文件中。所以,静态库生成的可执行文件最终执行的时候,并不依赖于库文件。
生成:gcc -c *.c à *.o
ar crv libxxxx.a .o à libxxxx.a(静态库)(前三个字母必须是lib)
3、库的使用:
(1)gcc -o main main.c -L(库的路径) -l(库名称) (库名称是除lib以外的)
(2)gcc -o main main.c 路径/libxxxx.a
4、动态库(共享库)不可单独执行的可执行文件
连接阶段只在可执行文件文件中使用的库,仅仅是让可执行文件知道所用的功能代码在哪个库中,运行时,由操作系统动态的单独的加载到内存上执行,本身是可执行的,但是不可单独执行,只能由程序引用来执行,动态库是单独存在于磁盘上,所以程序在运行的时候,需要将动态库单独的加载到内存上。
库的生成:
gcc -shared -fPIC -o libxxxx.so *.c
5、库的使用:
gcc -o main main.c -L(库的路径) -l(库名称) (库名称是除lib以外的)
操作系统加载动态库的路径:
/lib /usr/lib
- 将动态库移动到/lib 或者 /usr/lib 但是只有root用户只有权限进行操作
- 设置环境变量,使得操作系统加载库的时候,除了在默认路径下搜索,还需要在用户指定的路径下搜索。
将写好的库放在用户权限可操作的目录下,可以新建一个lib文件夹,在家目录下。
export LD_LIBRARY_PATH=/home/stu/lib 只针对于当前的终端有效
使环境变量永久有效:修改配置文件:/home/user/.bashrc