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

  1. gcc -c test.c 生成 test.o 文件

  2. ar rcs 静态链接库名称 目标文件1 目标文件2 ...

    • 静态库命名必须是 libxxx.a 的格式,

  3. 使用

    • gcc -c main.c 生成 main.o

    • gcc main.o -static -L /path -lxxx

编译动态库.so

  1. 直接以源文件方式创建

    • gcc -fpic -shared 源文件名... -o 动态链接库名

  2. 以目标文件(.o)方式创建,注意要加 -fpic

    • gcc -c -fpic add.c

    • gcc -shared add.o xxx.o -o libxxx.so

  3. 使用

    • gcc main.c libxxx.so -o main.exe

    • 这时候的可执行文件还不能执行,找不到动态库,两种办法:

      1. 把生成的libxxx.so 复制到移动到标准库目录,如: /usr/lib、/usr/lib64、/lib、/lib64

      2. 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调试

  1. 可调试执行异常崩溃的程序

    • 在 Linux 操作系统中,当程序执行发生异常崩溃时,系统可以将发生崩溃时的内存数据、调用堆栈情况等信息自动记录下载,并存储到一个文件中,该文件通常称为 core 文件,Linux 系统所具备的这种功能又称为核心转储(core dump)。幸运的是,GDB 对 core 文件的分析和调试提供有非常强大的功能支持,当程序发生异常崩溃时,通过 GDB 调试产生的 core 文件,往往可以更快速的解决问题。

  2. 通过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 查看宏信息

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

GDB 内如何修改变量

  • print、set

GDB watch作用及使用

  1. watch打下观察断点,用来监控某个变量或表达式的值,借助观察断点可以监控程序中某个变量或者表达式的值,只要发生改变,程序就会停止执行。

  2. rwatch 命令:只要程序中出现读取目标变量(表达式)的值的操作,程序就会停止运行;

  3. awatch 命令:只要程序中出现读取目标变量(表达式)的值或者改变值的操作,程序就会停止运行。

GDB调试core文件

多线程程序调试,

如果有访问同一变量,调试可能报错。

可以使用set scheduler-locking on锁定操作系统调度器,只允许调试线程执行

参考: https://www.cyningsun.com/10-11-2017/multithread-debug.html

最后更新于

这有帮助吗?