本节目录
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 目标文件声明成伪目标,测试一下。