从零开始学Linux之Linux调试器

从零开始学Linux之Linux调试器

       在讲调试器之前,我先强调下自己使用gcc时遇到的一些问题,在网上找了但都没有合适的解答,后来重新试了一遍又正常了,结果隔了一天又报错了,我先把gcc的整个流程来一遍。例如:在gcc编译器中编译如下一段代码:

1.gcc的使用


  1 #include<stdio.h>
  2 #include<string.h>
  3 void test()
  4 {
  5     printf("this is test function\n");
  6     return;
  7 }
  8 int main()
  9 {
 10     printf("hello Word\n");
 11     int i=0;
 12     for(i=0;i<5;i++)
 13     {
 14         printf("---------\n");
 15     }
 16     test();
 17     printf("over ~~\n");
 18     return 0;
 19 
 20 }

1.首先使用vim test.c指令先创建一个test.c文件,
2.进行预处理使用gcc -E test.c -o test.i进行预处理,预处理是展开所有代码,引入头文件,进行宏替换,删除注释等工作。
3.使用gcc -S test.i -o test.s进入编译阶段,编译阶段主要是检查语法语义错误,如果没有错误便将C语言解释为汇编语言。
4.使用gcc -c test.s -o test.o进入汇编阶段,将汇编代码解释成为二进制的cpu指令
5.在使用gcc test.o -o test.exe生成.exe文件将所有的指令打包在一起。在这里如果不是超级用户则需要进行一个提权操作,我这里总是出现问题,所以在这里要加一句chmod a+x test.o进行提权操作。
或者可以直接gcc -g test.c -o test.exe
生成exe文件后,我们进行调试操作的学习


2.gdb调试器的一些基本概念

       调试器的功能:调试,观察程序的运行过程,通常目的是为了排查程序的运行错误。
程序的错误分类:

1.编译错误
2.链接错误
3.运行时错误(运行中逻辑不对以及程序运行时崩溃)

       gdb ./test.exe进入调试,程序进行调试的前提是程序必须是一个debug版本的。gcc和g++默认生成release版本的,生成debug版本的需要加入-g。例如:gcc -g test.c -o test.exe

可执行程序的分类:

1.debug-调试版–不对代码进行优化,并且加入程序调试信息
2. release-发布版–不包含调试信息,并且对代码进行优化

3.gdb调试器的常用调试指令

3.1流程控制

1.run:直接运行程序;简写:r
2.start:开始逐步调试,停留在main函数的第一行;没有简写
在这里插入图片描述
3.list查看调试行附近的代码 list 11或者list test.c :11;简写:l

在这里插入图片描述
4.next:下一步-逐过程遇到函数直接运行完毕;简写:n
在这里插入图片描述
5.step:下一步,逐语句,遇到函数进入函数继续调试;简写:s
6.until:直接运行到指定位置 例如:until test.c:16
在这里插入图片描述
7.continue:继续运行从当前调试位置继续运行;简写:c;
8.break: 打断点: break test.c:13;简写:b;
在这里插入图片描述
另外的一种方式: break test:直接在函数处打断点
在这里插入图片描述
9.info break:查看断点信息 简写:ib
在这里插入图片描述
10.delete:删除断点 例如:delete 2简写:d
在这里插入图片描述
11.watchwatch变量名称;给变量打断点,当变量发生改变时停下来。没有简写
在这里插入图片描述
12.退出是quit

3.2内存控制

1.print:打印变量数据,设置或查看变量内容;简写:p
在这里插入图片描述
2.back trace:查看函数调用栈,通常检测程序运行崩溃的位置,栈顶位置的函数就是程序崩溃的位置,简写bt
举个栗子:
有如下的代码:

#include<stdio.h>
  2 #include<string.h>
  3 void test()
  4 {
  5     printf("this is test function\n");
  6    char *tmp=NULL;
  7    memcpy(tmp,"hello bit!",10);//此处肯定有错误
  8    printf("%s\n",tmp);
  9     return;
 10 }
 11 int main()
 12 {
 13     printf("hello word\n");
 14     int i=0;
 15     for(i=0;i<5;i++)
 16     {
 17         printf("---------\n");
 18     }
 19     test();
 20     printf("over ~~\n");
 21     return 0;
 22 
 23 }

       我们对此程序进行编译连接后进入调试模式,使用back trace或者bt命令查看调用栈的信息
在这里插入图片描述
       错误信息告诉我们在main()函数调用test函数时的的第7行出现崩溃。


2.make/Makefile

make/Makefile:项目的自动化构建工具
Makefile:是一个文本文件,记录一个项目的构建规则流程
Makefile的编写规则:
目标:依赖对象
\t为了生成目标对象要执行的命令。

1 test:test.c
2     gcc test.c -o test

预定义变量的使用: $@  $^  $ <,用于指令中,  $@表示目标对象,   $^表示依赖对象,  $ <表示对象的第一个。

1 test:test.c test1.c test2.c
2     gcc $^ -o $@
1 #$(lecard ./*.c) 获取当前目录下以.c结尾的文件的文件名称
2 src=#$(lecard ./*.c)
3 #保存到变量src中
4 #$表示对变量的使用
5 test:$(src)
6     gcc $^ -o $@

       make:是一个解释程序,对Makefile记录的构建规则流程逐步解释执行。
make的解释执行规则:

1.在命令行中敲击make指令,则表示运行make解释程序,程序会在当前目录下找到名称为makefile/Makefile的文件,解释执行其中的项目构建规则。
2.在规则中,找到要生成的第一个目标对象,判断目标对象是否已经存在,存在的话是否需要重新生成,根据源码文件的最后一次修改时间对比。执行对象生成命令。
3.make在每一个Makefile中只会找到第一个目标对象进行生成,生成后就会退出。

 7     test.o:test.c
 8     gcc $^ -o $@
 9 test1.o:test1.c
10     gcc $^ -o $@
11 test2.o:test2.c
12     gcc $^ -o $@
13 test: test.o test1.o test2.o
14     gcc $^ -o $@

在这里插入图片描述

4.make在生成目标对象的目标时先找到依赖对象,再寻找目标对象。

8 test: test.o test1.o test2.o
9     gcc  $^ -o $@ 
10 test.o:test.c
11     gcc -c $^ -o $@
12 test1.o:test1.c
13     gcc -c $^ -o $@
14 test2.o:test2.c
15     gcc -c $^ -o $@

在这里插入图片描述
或者:

8 test: test.o test1.o test2.o
9     gcc  $^ -o $@ 
10 %.o:%.c
11     gcc -c $< -o $@ #只汇编不链接

或者:
在这里插入图片描述

在这里插入图片描述

5.可以使用make clean指令删除.o文件

1 #$(lecard ./*.c) 获取当前目录下以.c结尾的文件的文件名称
2 src=$(wildcard ./*.c)
3 #保存到变量src中
4 #$表示对变量的使用
5 #test:$(src)
6 #   gcc $^ -o $@
7 #   将src变量的内容中的.c替换为.o然后存放到obj变量中
8 obj=$(patsubst %.c, %.o, $(src))
9 
10 test:$(obj)
11     gcc  $^ -o $@ 
12 
13 %.o:%.c
14     gcc -c $< -o $@
15 #.PHONY:clean#每次生成都是最新的
16 clean:
17     rm -rf $(obj) test

伪对象

       声明一个对象与外部文件无关,每次都要重新生成(不会因为当前文件是最新的不需要重新生成)如果有对象不管外部是否存在,都要执行语句,则可以声明为伪对象。
PHONY:clean

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值