_gdb和进程概念

目录

gdb

 gdb指令:

下载指令:sudo yum install gdb

 ​编辑

 进行gdb调试:gdb加+可执行程序文件名

 退出gdb调试:输入q

 为什么软件发布要有两个版本?

gdb环境下的l

l +数字:

 打断点b 加数字

 查看断点 info b

删除断点 d 编号

 调试运行:r

 逐过程:next 

逐语句:step

c:表示从一个断点跳到下一个断点:

bt查看函数调用堆栈:

finish直接跑完这个函数停下来:

 回车执行上一个指令:

p命令查看变量对应的值

 display常显示变量

undisplay:取消常显示变量:

 until跳到指定行:

p+变量名打印变量值:

 set var+变量名:修改变量的值:

 info locals显示局部变量:

 进程:

冯诺依曼体系结构

cpu的组成:

思考题:

 操作系统:


gdb

在windows下的vs2013下,我们可以进行调试,方便我们了解程序的具体的运行步骤和存在的问题,那么在Linux中,也存在这样一种调试机制,gdb就是在Linux系统下的调试指令。

Linux下和Windows下的调试的区别

答:调试的思路一定是一样的。

调试的方法一定是不同的,因为我们正常使用的Linux系统是没有可视化界面的,一般是以命令行的形式,所以Linux的调试方法和Windows一定会有所不同。

我们创建一个文件来进行gdb的练习操作:

 我们创建一个普通文件mytest.c

我们使用vim对文件内容进行编辑

 我们为了方便gdb的使用,写了三个函数块,main函数调用AddToVal函数,这个函数返回sum值,接下来,我们调用Print函数,这个函数打印sum和时间戳。

接下来,我们创建一个文件Makefile,使用vim来编辑依赖对象和依赖关系

 我们对这些代码进行翻译:

mytest的依赖对象是mytest.c,表示mytest是由mytest.c生成的。

依赖方法是这样:使用gcc进行编译链接,把mytest.c源文件经过编译链接形成可执行程序mytest

.PHONY:表示声明我们的clean没有依赖对像。

依赖方法是删除mytest文件。

我们使用make,形成可执行程序

 gdb指令:

下载指令:sudo yum install gdb

 

经过下载安装之后,我们可以使用gdb指令。

 进行gdb调试:gdb加+可执行程序文件名

 退出gdb调试:输入q

 默认情况下,gdb无法对release版本进行调试,调试只能在debug版本下进行,在Linux系统下,gcc默认生成的可执行程序默认是release版本,所以无法进行调试,我们可以这样操作:

 加上 -g表示gcc形成的可执行程序是mytest文件。

总结:gcc在默认使用时,使用的是动态链接

生成的可执行程序默认是release版本。

 为什么软件发布要有两个版本?

答:release版本是留给用户使用的,用户并不需要调试或者了解调试方法,debug版本是留给程序员的。

debug版本相当于就是release版本下又添加了调试信息。

 debug版本下,我们的文件占的内存是9816.

 release版本下,我们的文件占的内存是8472.

gdb环境下的l

 可以显示文件的内容

 再输入空格,可以显示更多的文件的内容。

假如我们想要从最开始开始显示:

l +数字:

 表示从第一行开始显示

假设我们要从第0行数字开始显示:

 打断点b 加数字

例如:假设我们要在第9行设置一个断点,我们可以输入b 9

 查看断点 info b

 Num代表断点的编号

删除断点 d 编号

注意删除断点不能使用d +所在行

例如:假如我们要删除编号为1的断点,该断点在第九行,我们不可以用d 9 ,可以用d 1

 

我们删除断点之后再来查看断点:

 

 调试运行:r

我们设置几个断点:

 我们设置两个断点,一个在第20行,一个在第22行

我们输入r

 逐过程:next 

 我们现在指针指向第20行,我们输入n,n表示逐过程:

 函数的逻辑应该是进入sum函数,但是我们的n逐过程并不会直接进入函数。

逐语句:step

 我们输入s,逐语句进行调试:

 我们直接进入add函数。

c:表示从一个断点跳到下一个断点:

我们设置三个断点,分别在第19行 第20行 第21行

我们按下运行,跳到第一个7断点处

 我们输入c

跳到下一个断点的位置。

bt查看函数调用堆栈:

 我们设置22行的断点:

 我们按下r,进行调试运行:

 然后我们按下bt,查看函数调用的堆栈:

 调用的是main函数的堆栈

finish直接跑完这个函数停下来:

我们设置一个新断点

在第5行,我们按下bt查看函数调用的堆栈

 

 假如我们想要结束Print函数,我们输入finish

 回车执行上一个指令:

 我们输入l 1,然后再按回车

 相当于执行l 1指令。

p命令查看变量对应的值

 我们先设置断点在第9行(进入AddToVal函数的内部)

我们使用p来查看变量from和to的内容

 display常显示变量

 

 

 

 接下来,我们进行调试的时候,这些变量的值就能够常显示了。

对于地址,也是可以常显示了。

接下来,我们再进行调试:

 

undisplay:取消常显示变量:

 注意:undisplay修饰的是编号:

 

 我们继续调试:

我们常显示的变量就消失了。

 until跳到指定行:

例如:

 我们在第20行打一个断点

 我们进行运行:

 假设我们想要运行到第22行,我们输入until 22

 接下来,我们就运行到了第22行。

p+变量名打印变量值:

 我们设置第11行的断点,然后进行运行:

 我们可以打印几个变量

 

 set var+变量名:修改变量的值:

 info locals显示局部变量:

我们在这一行,假如我们要显示局部变量的话,可以这样做:

 

 进程:

冯诺依曼体系结构

 这里的存储器指的是内存,内存具有掉电易失的性质。

磁盘可以叫做外存,具有永久性的存储能力。

磁盘也叫做外设,外部设备,外设非为输入设备和输出设备。

鼠标键盘等都是输入设备,显示器,打印机都是输出设备。

运算器+控制器组成cpu,存取速度块

存储器是内存,存取速度较快

外设存取速度较慢。

cpu智能被动的接收数据,这个数据来自于哪里?

答:从临时存储和永久存储中取。

为什么cpu只接受内存传递的数据,而不与外设打交道?、

答:本质是为了提高效率,因为cpu的存取速度大于内存大于外设,假设由外设向cpu输入数据时,速度由外设来决定,而外设的存取数据的速度非常慢,内存中天然的没有数据,外设的数据就被传到了内存中,内存就有了数据,当cpu读取过数据后,再把数据返回给内存,内存再定时刷新给外设。

操作系统的作用:

操作系统就是内存和外设之间的桥梁,内存和外设的交互策略由操作系统来决定。

结论:

1:cpu不和外设打交道,和内存打交道

2:所有的外设,有数据需要载入时,只能载入到内存中,内存有数据需要输出时,只能输出到外设中去。

程序运行为什么要加载到内存中去?

答:因为cpu要处理我们的代码的话,只能从内存中接收数据,所以我们的程序运行必须加载到内存中去。

cpu的组成:

cpu包括运算器和控制器,控制器相当于提示器,提示我们运算完成,输出完成信号。

运算器包括逻辑运算和数学运算,逻辑运算就是if语句等判断语句,数学计算就是二进位制的计算。

思考题:

 

答:假如我们输入了你好,首先是我们的键盘作为输入设备,输入你好给内存,内存再把数据传递给cpu,cpu经过加密处理和运算再把对应的二进位制数据返还给内存,内存再把数据传递给网卡,网卡存储了两份,一份刷新给我们的显示器,一份通过网络传递到另外一个计算机的网卡上,网卡把数据传递给内存,内存把数据传递给cpu,cpu经过加密运算和解析,把数据返还给内存,有内存数据给显示器,刷新到显示器上。

 操作系统:

操作系统是一个进行软硬件资源管理的软件

为什么要管理?

答:通过合理的管理手段,为用户提供良好的环境。

 通过操作系统,实现硬件和软件的交互,方便用户操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值