1、程序发布的两种版本(默认版本是release版本):
debug模式:增加了调试信息,可以调试。release模式:代码会得到优化,执行速度快,但也会保证结果。
给gcc/g++加上-g命令行参数,得到的就是debug版本
如果用gdb打开release版本的可执行程序,会有如下显示:
2、程序没有执行起来,调试可执行程序。
逐语句/逐过程调试:1.先打断点;2.让程序跑起来;3.到断点处停下来;4.逐语句/逐过程调试。
#include <stdio.h> typedef struct people{ int age; int high; }people; void
Add1(int a,int b){ int c=a+b; printf("%d\n",c); } void test_step3(){ printf("in
the step3\n"); } void test_step2(){ printf("in the step2\n"); test_step3(); }
void test_step1(){ printf("in the step1\n"); test_step2(); } int main(){
test_step1(); //1.查看数组变量 int array[4]={1,2,3,4};
printf("array[0]=%d\n",array[0]); //2.查看指针变量 int val=25; int* p=&val;
printf("val=%d *p=%d\n",val,*p); Add1(2,6); //3.查看结构体成员 people wang;
wang.age=20; wang.high=175; printf("wang.age=%d
wang.high=%d\n",wang.age,wang.high); people* p1=&wang; printf("p1->age=%d
p1->high=%d\n",p1->age,p1->high); return 0; }
执行gdb test1后,将展示如下结果,但是test1并没有被执行(test1是已经编译好的debug版本的可执行程序)
(1).list / l:查看源代码,由上往下查看,每次可查看10行代码
左侧的序号就是源代码中行号。
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。list / l 加上-,接着上次的位置往上列,每次列10行。
list/l 函数名:列出某个函数的源代码。
(2).r或run:运行程序
(3). break / b [源代码的行号]:在某一行设置断点
设置好断点后,让程序跑起来,
(4).s或step:进入函数调用
(5).n 或 next:单条执行。
(6).info break/i b :查看断点信息。
(7).disable breakpoints:禁用断点
(8).enable breakpoints:启用断点
(9). delete breakpoints n:删除序号为n的断点
(10).delete breakpoints:删除所有断点 (11).continue(或c):从当前位置开始连续而非单步执行程序。
(12). info(i) locals:查看当前栈帧局部变量的值
如果还没有执行某一局部变量的代码,可能该局部变量的值为乱码(未定义行为)。i locals查看的是当前函数栈帧中的局部变量。
(13)p 变量:打印变量值。
(14)breaktrace(或bt):查看各级函数调用及参数。
3.调试崩溃的程序产生的coredump文件
(1).coredump文件:核心转储文件,是程序在崩溃的一瞬间内存的映射。
(2).
core file
size:限制核心转储文件大小。如果其值为0:程序崩溃也不会产生coredump文件;如果值为unlimited:不限制核心转储文件大小,如果崩溃了,理论上
不管coredump文件多大,都会产生,但最主要还是由磁盘大小来决定,1.如果产生的coredump文件的大小,小于空闲的磁盘空间大小,则正常产生,2.如果产生的coredump文件的大小,大于空闲的磁盘空间大小,即使core
file size的值为unlimited,也不会产生coredump文件(原因在于磁盘空间不足)。
修改core file size的值:ulimit -c unlimited
>1越界访问可能会导致程序崩溃
如果core file size的值为unlimited,可能会产生coredump文件
coredump文件,默认名字就是core,数字(18964)表示产生崩溃 的进程号。
如果要通过gdb+coredump方式进行调试,可执行程序也应该是Debug版本。
>2非法指针可能会导致程序崩毁
空指针:
执行程序,产生coredump文件
野指针:
执行程序,产生coredump文件
4.自动化构建项目
4.1 make:是一个命令。makefile:是一个文件。mke根据makefile的文件内容,进行解析,编译程序(构建项目),从而生成可执行程序。
4.2 makefile的文件格式(定义编译程序的规则):
目标对象:需要生成什么内容。依赖对象:生成目标对象时,依赖的源码文件或目标文件。
4.3 make的工作方式:
1.只为生成第一个目标对象而服务,如果生成了目标对象,则后续文件当中的内容不解析:
如果为了生成第一个目标对象,需要先生成依赖对象,则在makefile文件当中查找生成依赖对象的方法,如果发现依赖对象不存在,则报错返回:
在当前路径下查找是否有依赖对象(1.o),如果没有,则在makefile当中查找是否有生成1.o的方法,如果也没有,则make会酌情的
帮助我们生成(可能会生成,也可能不会)。
此时make就不再帮我们生成.o文件。
在makefile文件中加上生成test.o的方法即可:
2.若依赖对象的最后一次修改时间小于目标对象的最后一次修改时间,则不生成。
3.make默认在当前路径下寻找文件名称为“makefile”或“Makefile”的文件来进行解析,如果找不到,则报错。
4.4 makefile文件当中的内置变量和自定义变量
$^:所有的依赖对象。$@:目标对象。
$<:第一个依赖对象。
自定义变量:可以自己给变量起名字,后续使用$符号进行解析。
伪目标:
其特性是总是被执行。