Linux——gdb调试,makefile的编写

1,gdb调试

     前提:需要对应用程序进行调试,就必须在用gcc编译的时候添加参数-g生成调试信息。

     启动gdb调试命令: gdb 包含调试信息的应用程序名字。之后就可以使用gdb的命令进行操作

  •  gdb命令

      1)查看代码

             l 查看程序的源代码,默认显示的是包含main的那个文件,下面的命令显示指定的。

             l 需要查看的文件的名字:行号   显示指定文件的多少行

             l 需要查看的文件的名字:函数的名字  显示指定文件的函数,可能显示不全,按l显示后面的内容,回车是执行前面的命令。

      2)断点

            break|b 行号  ,在指定行打断点,也可以打条件断点,如下

            break|b 行号 if i == 15(指定自己的条件) ,作用是使程序达到条件的时候才往下执行。

            info|i  break|b, 查看断点信息包括断点编号,输出的信息中有一列Enb,含义标记断点是否有用。

            d 断点编号,删除断点。

      3)启动程序,调试

            start, 开始调试,即windows中IDE下的小虫子按钮,但是只执行一步,使用下面命令继续调试。

            n ,单步调试,一步步执行

            c ,一直直执行,直到断点结束

            s ,进入到函数体内部

            u ,跳出当前循环

            finsh,跳出当前函数,需要注意的是跳出去之前需要把这个函数中的断点全部删除。

     4)查看变量值即变量类型

            p 变量名 ,就可以查看变量的值的

            ptype  变量名,就可以查看变量的类型

      5)追踪变量及取消变量

           display 变量名,就可以追踪变量的值,注意取消追踪的时候不是直接undisplay 变量名就行,正确方法见下行。

           undisplay,所追踪变量的编号,这样来取消追踪,注意,这里的所追踪变量的编号以命令info|i display获取
      6)调试时设置变量值,按自己的意愿调试

           set var 变量名=值,可以通过这个命令来设置程序中变量的值,来达到跳过一些没必要了解的程序的执行信息。比如,有一个循   环for(i=0; i<100; i++) 调试到这一步的时候,执行语句 set var i = 50,就可以让程序从i=50开始停止执行。

      7)退出gdb模式

           quit, 退出gdb模式

2,makefile的编写

    makefile是一个项目的代码管理工具,如果项目很大,需要编译的文件很多,那么编译的时候gcc就需要写的很长很长,这个时候就需要使用到makefile了

  •  makefile的命名规则,Makefile或者makefile,只有这两种方式。        
  •  makefile的编写规则

        规则中的三要素:目标,依赖,命令。了解了三要素,下面介绍makefile的编写模式如下:

        目标:依赖条件(依赖条件是指需要编译的文件)

        Tab(这里的tab缩进是必须的) 命令(命令是指编译的命令)

       上面的两行就构成了编写makefile的一条规则。 

       第一种写法:

       app:main.c add.c sub.c

              gcc mian.c add.c sub.c -o app

       第二种写法:

          使用第一种写法存在以下缺陷,如果我们只修改了依赖文件中的一个文件,那么我们需要把所有的文件都重新编译,显然这是一种效率低的做法。使用将依赖拆分的方法就可以解决这个问题。      

//这条规则是终极目标
app:main.o add.o sub.o
    gcc mian.o add.o sub.o -o app
//下面三条规则是生成依赖
main.o:main.c
    gcc -c main.c

add.o:add.c
    gcc -c add.c

sub.o:sub.c
    gcc -c sub.c

              
  • makefile工作原理

       注意,程序执行第一行时,会找到依赖中的main.o,此时的目录下没有这个文件,就会往下找,寻找下面的规则是否可以生成。如果找到,就执行对应的命令来生成所需要的依赖,需要add.o和sub.o时也是如此,当所有的依赖全部找全时,就会执行终极的编译命令(终极目标的编译命令是最后执行的)。注意,这里的.c文件是和makefile放到了一个目录下,不然需要注意路径的问题。

      为什么第二种方法就不会产生不必要的编译呢?原因是因为,识别makefile的程序,会根据每条规则的第一行来比较依赖和目标的时间,当目标的时间晚于依赖时,就会执行下面的编译命令,否则跳过。和上面介绍的顺一样,这是从终极规则开始检索的,类似于树的深度搜索。

  • makefile中的变量

      makefile中的变量是不需要类型的,直接起名字赋值即可。使用变量时,需要用$进行取值,并且需要使用()把变量名括起来。

  • makefile中的模式

       就像数学公式一样,如果多条规则的格式差不多时,可以写一个模式来进行匹配,而不需要重复写多条规则。

       以上面第二种makefile代码为例,最后的三条规则可以写成一条模式如下:

        %.o:%.c

            gcc -c $< -o $@

        这条模式中%的作用是进行模式匹配,在终极规则中遇到XXX.o时,就会向下面的规则检索,此时%.o:%.c就会变成XXX.o:XXX.c,然后就执行命令行

        makefile中的自动变量(只能在命令行使用):

            $<  规则中(这条规则中的)的第一个依赖

            $@ 规则中(这条规则中的)的目标

            $^   规则中(这条规则中的)的所有依赖

      经过变量和模式的使用,优化第二种makefile的代码后如下:

obj = main.o add.o sub.o
target = app
$(target):$(obj)
   gcc $(obj) -o $(target)

//模式公式
%.o:%.c
  gcc $< -o $@
  •   makefile中的函数

       在makefile中所有的函数都是有返回值的。

       src=$(wildcard ./%.c) (wildcard是函数的名字,参数直接在空格后面写,后面是目录,利用的是匹配,找到所有目录下的.c文件,函数返回的是一个串,使用$()的形式把数据取出来)

       obj=$(patsubst ./%.c,./%.o, $(src))(patsubsts是函数的名字,是一个匹配替换模式,注意函数名和第一个参数之间使用空格隔开,后面的参数使用“,”隔开,这个函数的作用是将src中所有的.c文件都替换成.o文件)

#obj = main.o add.o sub.o
target = app
#makefile中自己维护的变量,下面的CC就是,可以根据用户需要赋值
#makefile中的函数的使用

src=$(wildcard ./*c)
obj=$(patsubst ./%.c, ./%.o, $(src))
CC=gcc

$(target):$(obj)
   $(CC) $(obj) -o $(target)

#模式公式
%.o:%.c
  $(CC) $< -o $@

#.PHONY是生成为目标,加上之后在执行make clean的时候就不会在和makefile目录下的clean文件比较
.PHONY:clean 
clean:
   -mkdir ./aa #前面加-的目的是执行失败之后,跳过这条命令
   rm $(obj) $(target) -f
hello:
   echo "hello world!"

      注意,最后两条条规则,没有依赖,倒数第二条的作用是删除.o文件和生成的应用程序。使用的时候,直接make clean即可调用。同样,执行make hello 就可以输出hello world!

      需要注意的是,如果不进行为目标设置,如果在makefile目录下,如果有一个名为clean的文件,那个make clean就不能被正常执行,因为前面说过makefile有自己的更新模式,实际上规则中的clean是没有生成的,所有目录中的clean永远是最新的,所以下面的rm命令永远不会执行。因此需要使用.PHONY来声明伪目标,这样在执行make clean命令时,就不会比较,然后直接执行rm命令。

   makefile写成上面的样子基本就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值