(七)gdb调试 及静态库共享库
·
一、gdb 常用调试命令
前提:编译程序必须加
-g参数,加入调试信息,gcc main.c -g -o main,否则 gdb 看不到源码。
| 命令 | 作用 |
|---|---|
l / l 行号 |
list,显示源码;l 10直接跳到第 10 行附近显示代码 |
b 行号 / b 函数名 |
break,设置断点 b 20 / b add |
info break |
查看所有断点信息,显示断点编号 |
delete 断点编号 |
删除指定断点;delete不加编号删除全部断点 |
r |
run,从头运行程序,遇到断点停下 |
n |
next,单步执行,不进入函数(越过函数) |
s |
step,单步执行,进入调用的函数内部 |
finish |
执行完当前函数,跳出函数,返回到调用处 |
c |
continue,继续运行,直到下一个断点 |
p 变量名 |
print,打印变量 / 表达式的值 p a |
bt |
backtrace,打印完整函数调用栈 |
bt n |
只打印前 n 层调用栈 |
q |
quit,退出 gdb |
小提示:gdb 敲回车会重复执行上一条命令。
二、C 库基础
头文件:stdio.h —— 函数声明(告诉编译器函数长什么样) 库文件:/usr/lib/libc.so.6 —— 函数实现,已经编译好的机器码集合。
.h:只放声明,没有实现代码- 库文件存放真正编译完成的二进制实现代码
库分为两大类:静态库 .a、共享 (动态) 库 .so
1、静态库 .a
本质:多个.o目标文件归档打包而成,使用ar工具制作。
ar 参数
c:创建库文件r:把目标文件添加进库v:verbose,显示操作过程
生成静态库示例
# 1.先把源码编译成目标文件 .o
gcc -c add.c -o add.o
gcc -c max.c -o max.o
# 2.打包生成静态库 libfoo.a
ar crv libfoo.a add.o max.o
使用静态库链接生成可执行程序
gcc main.o -L. -lfoo -o app
-L.:指定库搜索路径,.代表当前目录-lfoo:代表库名libfoo.a,去掉lib前缀和.a后缀
⚠️ 注意:同一个目录下同时存在
libfoo.a(静态) 和libfoo.so(动态),gcc优先链接动态库。
静态库优缺点
✅优点: 链接阶段把库代码完整复制进可执行文件;运行时不再依赖原库文件,删掉libfoo.a程序照样跑。
❌缺点:
- 可执行文件体积大,每份程序都拷贝一份库代码,内存浪费;
- 静态库更新后,所有使用该库的程序必须重新编译链接,才能用上新版本。
2、共享库(动态库).so
运行的时候才加载库到内存,多个进程可以共用内存里同一份库代码。
编译生成动态库示例
# -fPIC 生成位置无关代码,动态库必备参数
gcc -c -fPIC add.c -o add.o
gcc -c -fPIC max.c -o max.o
# 生成共享库 libfoo.so
gcc -shared add.o max.o -o libfoo.so
链接使用动态库
gcc main.o -L. -lfoo -o app
动态库优缺点
✅优点:
- 多个程序共享内存中一份库代码,节省内存;
- 更新
.so库文件,只要接口不变,程序不需要重新编译,重启程序就使用新版库。
❌缺点: 运行依赖.so文件,如果库丢失、版本不匹配,程序直接运行失败。
编译小技巧:gcc 可以一步编译,不需要手动生成
.o
# 直接用c源码链接静态库
gcc main.c -L. -lfoo -o app
LD_LIBRARY_PATH 环境变量
动态库运行时搜索路径。 gcc 编译时通过-L找库;程序运行时不会读取 - L 参数,操作系统会去系统库目录和LD_LIBRARY_PATH环境变量指定目录寻找.so。
# 设置临时环境变量,当前终端生效
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./app
补充:编译器默认自动链接 libc 标准库;数学库
libm需要手动加-lm。
补充对比小结
| 项目 | 静态库 .a |
动态共享库 .so |
|---|---|---|
| 链接时机 | 编译链接阶段拷贝代码 | 编译只记录引用,运行时加载 |
| 运行依赖 | 不依赖原库文件 | 必须存在对应 so 文件 |
| 内存占用 | 每个程序自带一份库代码,占用大 | 多进程共享内存一份库 |
| 库更新 | 程序需要重新编译链接 | 接口兼容时,无需重编译 |
| 制作工具 | ar | gcc -shared |
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)