gcc&gdb
GCC
gcc/g++编译参数
-I 指定头文件目录
-L 要链接的库所在的目录
-l 需要链接库的名称,注意不是库文件名称,比如库文件为 libtest.so,那么库名称为 test。
-w 禁止显示所有警告信息。
-Wall 会打开一些很有用的警告选项,建议编译时加此选项。
-Werror 把警告当做错误,出现任何警告即放弃编译。
-Wextra 打印一些额外的警告信息。
-D 可以定义宏,-Dname 定义宏name,默认定义内容为字符串“1”,相当于 C 语言中的 #define macro,-Dname=defn 定义宏name,并且内容为defn,这个defn目测必须是个变量
-fpic 编译生成动态库的时候可以加,不加也可以,但是每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy,不会达到真正共享的作用。 https://blog.csdn.net/derkampf/article/details/69660050?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
-shared 指定生成动态链接库。
-O0 、-O1 、-O2 、-O3 编译器的优化选项的 4 个级别,-O0 表示没有优化, -O1 为默认值,-O3 优化级别最高。编译静态库.a
gcc -c test.c 生成 test.o 文件
ar rcs 静态链接库名称 目标文件1 目标文件2 ...
静态库命名必须是 libxxx.a 的格式,
使用
gcc -c main.c 生成 main.o
gcc main.o -static -L /path -lxxx
编译动态库.so
直接以源文件方式创建
gcc -fpic -shared 源文件名... -o 动态链接库名
以目标文件(.o)方式创建,注意要加 -fpic
gcc -c -fpic add.c
gcc -shared add.o xxx.o -o libxxx.so
使用
gcc main.c libxxx.so -o main.exe
这时候的可执行文件还不能执行,找不到动态库,两种办法:
把生成的libxxx.so 复制到移动到标准库目录,如: /usr/lib、/usr/lib64、/lib、/lib64
so文件所在路径加入环境变量LD_LIBRARY_PATH,export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx,其中 xxx 为动态链接库文件的绝对存储路径。
GDB
GDB 主要功能
总的来说,借助 GDB 调试器可以实现以下几个功能:
1. 程序启动时,可以按照我们自定义的要求运行程序,例如设置参数和环境变量;
2. 可使被调试程序在指定代码处暂停运行,并查看当前程序的运行状态(例如当前变量的值,函数的执行结果等),即支持断点调试;
3. 程序执行过程中,可以改变某个变量的值,还可以改变代码的执行顺序,从而尝试修改程序中出现的逻辑错误。
GBD调试的四种方式
1. 直接使用 gdb 指令启动 GDB 调试器
运行gdb后指定调试程序
2. 调试尚未执行的程序
gdb a.out
3. 调试正在执行的程序
通过进程号调试正在运行的程序进程
pidof 文件名 获得进程号,多进程的会有多个进程号
gdb命令
4. 通过core调试
可调试执行异常崩溃的程序
在 Linux 操作系统中,当程序执行发生异常崩溃时,系统可以将发生崩溃时的内存数据、调用堆栈情况等信息自动记录下载,并存储到一个文件中,该文件通常称为 core 文件,Linux 系统所具备的这种功能又称为核心转储(core dump)。幸运的是,GDB 对 core 文件的分析和调试提供有非常强大的功能支持,当程序发生异常崩溃时,通过 GDB 调试产生的 core 文件,往往可以更快速的解决问题。
通过core调试nginx的例子
GDB常用参数
参 数
功 能
-pid number -p number
调试进程 ID 为 number 的程序。
-symbols file -s file
仅从指定 file 文件中读取符号表。
-q -quiet -silent
取消启动 GDB 调试器时打印的介绍信息和版权信息
-cd directory
以 directory 作为启动 GDB 调试器的工作目录,而非当前所在目录。
--args 参数1 参数2...
向可执行文件传递执行所需要的参数。
GDB断点调试常用命令
命令(缩写)
功 能
run(r)
启动或者重启一个程序。
list(l)
显示带有行号的源码。
continue(c)
让暂停的程序继续运行。
next(n)
单步调试程序,即手动控制代码一行一行地执行。
step(s)
如果有调用函数,进入调用的函数内部;否则,和 next 命令的功能一样。
until(u) until location(u location)
当你厌倦了在一个循环体内单步跟踪时,单纯使用 until 命令,可以运行程序直到退出循环体。 until n 命令中,n 为某一行代码的行号,该命令会使程序运行至第 n 行代码处停止。
finish(fi)
结束当前正在执行的函数,并在跳出函数后暂停程序的执行。
return(return)
结束当前调用函数并返回指定值,到上一层函数调用处停止程序执行。
jump(j)
使程序从当前要执行的代码处,直接跳转到指定位置处继续执行后续的代码。
print(p)
打印指定变量的值。
quit(q)
退出 GDB 调试器。
GDB调试多进程
https://www.cnblogs.com/diegodu/p/6223233.html
attach
gdb -p pid,调试正在运行的进程
set follow-fork-mode child|parent,让GDB跟踪父进程或子进程,调试master-worker初始化的时候可以用这个
GDB 查看宏信息
直接gdb调试没法查看宏定义变量

编译器默认没有把宏定义扩展信息编译进二进制文件。要在调试时查看宏定义信息,编译时需添加-gdwarf-2和-g3两个参数。

GDB 内如何修改变量
print、set

GDB watch作用及使用
watch打下观察断点,用来监控某个变量或表达式的值,借助观察断点可以监控程序中某个变量或者表达式的值,只要发生改变,程序就会停止执行。
rwatch 命令:只要程序中出现读取目标变量(表达式)的值的操作,程序就会停止运行;
awatch 命令:只要程序中出现读取目标变量(表达式)的值或者改变值的操作,程序就会停止运行。
GDB调试core文件
多线程程序调试,
如果有访问同一变量,调试可能报错。
可以使用set scheduler-locking on锁定操作系统调度器,只允许调试线程执行
参考: https://www.cyningsun.com/10-11-2017/multithread-debug.html
最后更新于
这有帮助吗?