Linux—调试器-gdb使用—Linux项目自动化工具make/Makefile—详解

Linux调试器-gdb使用

gdb使用背景

  • 程序的发布方式有两种,debag模式和releasa模式
  • 如果是在Linux操作系统下,进行调试程序,需要在编译的时候,将程序编译成debag版本。
  • debag:是程序的一个调试版本,增加了一些调试信息,这些调试信息,可以帮助程序员调试代码。
  • release:这是程序的发布版本,客户一般拿的是这个版本,这个版本相对于debag版本,编译器是在编译的时候做了优化,程序运行更快。
  • Linux gcc/g++出来的二进制程序,默认是release版本。
  • 要使用gcc/g++调试,要想生成debag版本,必须在源代码生成二进制程序的时候,加上 -g 选项

gdb调试使用指令

  • gdb[可执行程序]:进入gdb调试模式。
  • l/list:查看源代码。
  • l [行号]:显示binFile源代码,接着上次的位置往下拉,每次显示10行。
  • l [函数名]:列出某个函数的源代码。
  • r或run:运行程序。
  • n或next:单条执行(逐过程执行)。
  • s或step:进入函数调用(逐语句执行)。
  • b(break) [源码文件中的行号]:在后一行设置断点。
  • break [函数名]:在某个函数开头设置断点。
  • i b (info break):查看断点信息。
  • c (continue):从当前位置开始连续而非单步执行程序。(继续执行,遇到下一个断点的时候就会停止执行)。
  • r (run):从开始连续而非单步执行程序。
  • delete [断点序号]:去除断点。
  • disable [断点序号]:使断点失效。
  • enable [断点序号]:使断点生效。
  • p(print) :打印表达式的值,通过表达式可以修改变量的值或者调用函数。
  • p [变量]:打印变量的值,不仅仅局限于普通变量,还可以打印指针变量,还可以打印对象。
  • set var:修改变量的值。
  • display [变量名]:跟踪查看一个变量,每次定下来都显示它的值。
  • undisplay:取消对先前设置的那些变量的跟踪。
  • q(quit):退出gdb。

gdb调试coredump文件

前提:本质上是在调试程序崩溃之后的内存镜像文件(内存镜像文件保存的是,程序在崩溃的一瞬间内存当中的值)。

  • 产生coredump文件的条件:
    1. linux操作系统中,需要设置core size 的大小----->(ulimit -c)。
    2. 磁盘大小。
  • 调试指令:gdb [可执行程序] [coredump文件]
  • bt :查看调用堆栈
    f [堆栈序号]:转跳到某个具体的堆栈
  • tips :
    11信号:解引用空指针,解引用野指针,越界访问内存。(Program terminated with signal 11,Segmentation fault.)
    6号信号:double free

Linux项目自动化工具make/Makefile

背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的
    规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂
    的功能操作
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编
    译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命
    令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一
    种在工程方面的编译方法。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

实例代码

C代码

   #include <stdio.h>
   int main()
   {
    
    
    printf("hello Makefile!\n");
    return 0; }

Makefile文件

   hello:hello.o
    gcc hello.o -o hello
   hello.o:hello.s
    gcc -c hello.s -o hello.o
   hello.s:hello.i
    gcc -S hello.i -o hello.s
   hello.i:hello.c
    gcc -E hello.c -o hello.i
   .PHONY:clean
   clean:
    rm -f hello.i hello.s hello.o hello

依赖关系

  • 上面的文件 hello ,它依赖 hell.o
  • hello.o , 它依赖 hello.s hello.s , 它依赖 hello.i
  • hello.i , 它依赖 hello.c

依赖方法

gcc hello. * -option hello. * ,就是与之对应的依赖关系

原理

make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,

  • make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  • 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello”这个文件,
    并把这个文件作为最终的目标文件。
  • 如果hello文件不存在,或是hello所依赖的后面的hello.o文件的文件修改时间要比hello这个文件新(可
    以用 touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。
  • 如果hello所依赖的hello.o文件不存在,那么make会在当前文件中找目标为hello.o文件的依赖性,如果
    找到则再根据那一个规则生成hello.o文件。(这有点像一个堆栈的过程)
  • 当然,你的C文件和H文件是存在的,于是make会生成 hello.o 文件,然后再用 hello.o 文件声明
    make的终极任务,也就是执行文件hello了。
  • 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文
    件。
  • 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,
    而对于所定义的命令的错误,或是编译不成功,make根本不理。
  • make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,
    我就不工作啦。

预定义变量

&^:依赖的所有对象 $@:目标对象

makefile清理

  • 工程是需要被清理的
  • 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,
    不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编
    译。
  • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被
    执行的。
  • 可以将我们的 hello 目标文件声明成伪目标,测试一下。

make当中也可以自定义变量

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45796387/article/details/114685721