• _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经过加密运算和解析,把数据返还给内存,有内存数据给显示器,刷新到显示器上。

     操作系统:

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

    为什么要管理?

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

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

  • 相关阅读:
    鸿运主动安全监控云平台任意文件下载漏洞复现 [附POC]
    机智云无需代码就能搞定IoT小程序开发和管理
    图神经网络 | Python实现基于时空图卷积GNN + LSTM 模型预测(多变量方法)
    详解设计模式:组合模式
    看红帽巨佬解析⭐《一、G1垃圾回收期简介》⭐
    深入解析 qsort 排序(上),它为什么是万能排序?
    关于在代码中vector的一些使用
    数据库重构之路,以 OrientDB 到 NebulaGraph 为例
    容灾恢复 | 记一次K8S集群中etcd数据快照的备份恢复实践
    什么是GPIO的推挽输出和开漏输出
  • 原文地址:https://blog.csdn.net/qq_66581313/article/details/128039236