GDB调试
使用
要调试一个程序 首先要给程序在编译的时候加调试信息:
gcc XXX.c -g (编译的时候加-g)
启动调试:
gdb 可执行的程序
例如: gdb a.out
退出调试 quit
常用的调试命令
命令 [缩写] | 解释 |
---|---|
file [f] | 装入要调试的可执行文件 |
list [l] | 查看部分源程序 |
run [r] | 运行程序 |
break [b] | 设置断点 |
info break [i b] | 查看断点信息 |
delete [d] | 删除断点 |
continue [c] | 继续执行程序 |
next [n] | 逐过程执行一行代码,不进入函数内部调试 |
step [s] | 逐语句执行一行代码,进入函数内部调试 |
print [p] | 打印指定变量的值 |
watch [wa] | 监视变量的值,一旦有变化,程序停住 |
help [h] | GDB的帮助命令 |
finish | 结束当前函数运行 |
gdb调试中查看内存
x/<n/f/u>
n、f、u是可选的参数
n是一个正整数,表示需要显示的内存单元的个数,也就是说从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义。
f 表示显示的格式,参见下面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
表示一个内存地址。
注意:严格区分n和u的关系,n表示单元个数,u表示每个单元的大小。
静态库
概念
静态库: 运要被包含到源程序中
优点: 运行速度快
缺点: 占用系统资源比较多
适用的场合: 对时间要求很高的场合
制作静态库:
1、将所有源程序全部生成.o文件
gcc -c add.c -o add.o
gcc -c mul.c -o mul.o
2、使用工具将所有.o打包生成静态库文件
ar rcs lib库名.a 所有.o文件
3、制作库的头文件,主要是进行函数声明,提示使用者这个库中 有哪些函数,如何使用?
书写: #ifndef MYLIB_H
#define MYLIB_H
/函数声明/
#endif //MYLIB_H
防止头文件重复包含
4、编译的时候gcc库包含的相关命令
-L | 库文件所在的目录 |
---|---|
-l(L的小写) | 包含要添加到程序的库,后面跟库名即可 |
-I(i的大写) | 指定头文件所在路径 |
gcc 2.c -L /home -l mylib -I …/
动态库
1、将所有源程序全部生成.o文件
gcc -c add.c -o add.o -fPIC
gcc -c mul.c -o mul.o -fPIC
2、使用工具将所有.o打包生成动态库文件,后缀名.so
gcc -shared -o lib库名.so 所有.o文件
3、制作库的头文件,主要是进行函数声明等,提示使用者这个库中 有哪些函数,如何使用?
书写: #ifndef MYLIB_H
#define MYLIB_H
/函数声明/
……
……
#endif //MYLIB_H
防止头文件重复包含
4、编译的时候gcc库包含的相关命令
-L | 库文件所在的目录 |
---|---|
-l(L的小写) | 包含要添加到程序的库,后面跟库名即可 |
-I(i的大写) | 指定头文件所在路径 |
5、运行时候会找不到动态库文件,解决办法:
1、临时办法,只在当前终端有效,终端重启以后就没用了
在终端输入以下命令:
export LD_LIBRARY_PATH=库所在目录的绝对路径
2、修改终端的配置文件 ~/.bashrc
§ vim ~/.bashrc
§ 把 export LD_LIBRARY_PATH=库所在目录的绝对路径
添加到文件的最后一行
§ 重启终端或者运行命令 source ~/.bashrc 使用配置文件生效
3、将动态库放到系统默认目录下 ===> /usr/lib
4、配置文件 /etc/ld.so.conf
§ vim /etc/ld.so.conf
§ 将库文件的绝对路径添加到库的最后一行
§ 使配置文件生效:ldconfig -v