Linux第十节课 - gdb + 冯诺依曼体系结构

科普:开发流程

一个项目开发:项目经理 + 产品经理 + 程序员 + 测试(可能有)--->(开发团队)

产品经理提出来需求 --->>> 项目经理分配任务 ---> 程序员开发 --->>> 测试部门提交--->>> 项目经理发布任务

gdb调试:

假设当前我们有mycode.c文件

cpp 复制代码
#include<stdio.h>

int addTOTop(int top)
{
  int res = 0;
  int i = 1;
  for(;i <= top;i++)
  {
    res += i;
  }
  return res;
}


int main()
{
  printf("debug begin\n");
  int top = 100;
  int sum = addTOTop(top);
  printf("sum:%d\n",sum);
  printf("debug end\n");
  return 0;
}

和对应的makefile文件用来做演示:

bash 复制代码
mycode:mycode.c
	gcc -o $@ $^ -g
.PHONY:clean
clean:
	rm -rf mycode
gdb mycode

可以查看mycode为名的可执行程序!(此时进入gdb交互模式)

gdb的基本操作:

  • 输入q可以退出!
  • 输入l / list可以查看该可执行程序的源码!(默认显示十行,如果此时未显示完全,继续按回车即可!)(但是有时候不是从第一行开始显示!如果想要从第一行开始显示,直接l0!)
  • l 1 从第一行开始;l 2 从第二行开始!
  • l 0之后只会默认显示10行;此时gdb会默认记录使用过的代码,因此此时直接回车会默认执行l选项!
  • l + 函数名可以查看对应函数的代码!例如 ---> l addTOP
  • r --->表示运行程序!
  • 设置断点:b 19(b+ 行号!)(在第19行处打断点)

1、查看断点的信息

  info b

此时可以查看断点信息!

  1. 第一行的Num表示断点的编号
  2. Enb表示是否开启
  3. Address表示断点的地址
  4. What显示断点位于程序的哪个位置

2、删除断点

  • 删除的时候使用d + 断点编号来删除(不能用行号!)

    d 1

如果我们设置好断点后将gdb关闭,然后重新打开gdb,此时我们设置的断点会消失!

设置完断点后再使用r运行程序,会自动运行到我们设置的断点处!

3、逐过程和逐语句

在VS中,F10为逐过程;F11为逐语句!

在gdb中,逐过程用n (next)表示(逐过程会直接跳过函数,不进入函数调用,且gdb会自动跳过空行,进入到下一段代码处

调试结束后断点还存在!且此时info b 会更新断点被调试次数的信息!

且gdb会自动记住历史命令! --- > 直接回车代表用上一条命令!

s

s表示(step) --->逐语句调试过程,可以进入到函数内部进行调试!

对于普通的语句来说,逐过程(n)和逐语句(s)是没有区别的!

4、查看对应变量值 (p + display)

vs中可以调用监视窗口,在gdb上使用p + 变量值查看对应的变量内容

p i

可以查看i的变量值!

如果我们想要长显示变量的值 (一直显示变量的值),可以使用display + 变量名

display i

作用等同于监视!

长显示最左边有对应的编号!如果我们想要取消长显示undispaly + 编号!

undispaly 3

可以对res取消显示!

5、跳过指定行

如果我们进入到函数内部,此时我们想要跳转出来 ,可以使用until指令使得跳过对应行:

until可以从一个函数跳转到指定行!

例如

until 10

此时代码会跳转到第11行!(如果第10行为空行!)

6、运行完函数后停止

如果此时我们只想函数运行下来后停止,不要再往后面走,只想要验证整个函数的运行情况,可以使用finish指令直接运行完整个函数!

作用:如果一个函数没有问题,则会正常运行完后停下来,如果一个函数有问题,此时会运行中断,帮助我们找到有问题的部分!

7、从一个断点处运行到另一个断点处

如果我们想要从一个断点处运行到下一个断点处:c(continue)

如果此时断点2运行到断点3报错,说明错误在断点2和断点3之间,可以在2和3之间大更细致的断点找错误(中间可以进入函数使用finish查找错误等等)

8、禁用断点

在vs中,当我们设置一个断点的时候,右键可以选择禁用该断点(虽然断点被创建但此时断点不发挥作用)

在Linux系统中:

bash 复制代码
disable 2

此时2号断点会被禁用!

此时可以发现2号断点的Enb状态由y变为n

如果我们此时想把断点1打开:

bash 复制代码
enable 1

此时Enb状态会变成y!

9、在指定位置打上断点

b + 函数名会直接将断点打在函数内部起始的第一个位置!例如:

bash 复制代码
b main

还可以直接对一个.c文件打断点:

bash 复制代码
b mycode.c:19

直接对mycode.c的第19行打断点!

还可以对文件名内的函数打断点:

bash 复制代码
b mycode.c:main

10、设置变量名

set可以设置一个变量名的值:

bash 复制代码
set var + 变量名 值

例如我们进入一个循环中,此时我们需要循环快速接近结尾:

bash 复制代码
set var i = 97

11、 补充

breaktrace (bt) --- 查看各级函数调用堆栈及参数(只有进入函数中才能查看!)

info locals --- 查看当前栈帧局部变量的值(只有进入函数中才能查看!)

认识冯诺依曼体系结构

一、先谈硬件

一个计算机要能正常工作,它的体系结构必须遵循冯诺依曼体系结构!

一般寄存器指的就是内存!

硬盘/U盘等可以叫做外存,外存的构造与内存相差特别大,一般硬盘/U盘当作输入输出设备!

输入设备: (计算机只认识二进制!因此人类无法直接访问内存!)鼠标,键盘,摄像头,话筒,磁盘(不一定用户自己输入,还可以从文件中读取),网卡(计算机从网络中收到消息 --- 网卡先收到!)

输出设备:(将二进制转化为人能读懂的字符/视频)显示器,磁盘(文件写完后保存到磁盘上),网卡(将信息发送给他人)

有的设备是纯输入 / 输出,有的设备既是输入又是输出!输入设备和输出设备统称为外设!

运算器:对我们的数据进行运算任务(算术运算 / 逻辑运算)

控制器:对我们的计算硬件流程进行一定的控制(什么时候输入,什么时候输出)

控制器 + 运算器就是中央控制器,也就是我们说的CPU!

这五个部分都是一个独立的个体!可以拆分下来!

各个硬件单元必须用线连接起来,这个"线"也就是总线!

总线分为两种:1、系统总线 2、IO总线

CPU和内存直接交互的线被称为系统总线!

内存和外设(输入输出设备)连接的总线被称为IO总线!

回忆:指针中分配地址有地址总线和控制总线

有的总显示裸漏在外面的可以看到,有的总线是集成在电路上看不到!

SSD:固态硬盘

HDD:机械硬盘

金字塔从上到下,容量越来越大,访问速率越来越慢

CPU内的寄存器,访问速度为纳秒级别;内存是微秒级别;硬盘是毫秒级别;

为什么要有存储器?

因为外设和中央处理器之间的代差太大了!可以参考木桶原理!(一个木桶的最高容水量取决于最短的那块板子!)

如果直接让外部设备直接和中央处理器交互,那么整个计算机直接的交互效率就以输入输出设备的效率为主(中央处理器很快就处理完数据,但是输入/输出设备会一直慢悠悠的输入/输出数据!)因此如果没有存储器,会导致整机效率非常低下!

CPU与内存和内存与输入输出设备直接也有代差,但是这个代差相较于外设和中央处理器之间小很多!最后整机效率以内存效率为主!

加了存储器之后,需要将输入设备传入存储器,存储器再交给运算器和控制器后进行计算,然后再返回给存储器,再交给输出设备(串行!)

输入设备可能会提前将数据预加载到存储器!CPU的加载和计算可以同时进行!

可以将存储器(内存)看做一个硬件级别的缓存空间!

一个程序要运行,必须加载到内存中运行!为什么?

一个程序中包含有代码和数据,必须被CPU去执行!而CPU只从内存中拿数据!(冯诺依曼体系结构规定!) --- > 所有的软件结构必须遵循硬件体系结构!

为什么我们当时写的进度条,默认显示的数据,是可能被缓存起来的?在那里缓存?

遵循冯诺依曼体系结构,从CPU输出到内存中,在内存中缓存,然后再刷新到输出设备中!

情景猜想:

QQ是在内存中的!(登录上QQ软件的时候!)

在"我"的输出设备中,发消息时最主要的还是将消息输出到网卡,显示器此时为同步的一份!

在"我"的CPU中,可能对数据进行压缩打包等一系列操作;

在"朋友"的CPU中,可能对数据进行解包解压等一系列操作;

如果我们此时想要发送一份实验报告给对方,是怎么实现的?

"朋友"收到实验报告后,并不能直接打开,而是需要下载!而且关闭QQ后再次打开,还能够继续下载!

CPU和内存是不能一直保存数据的,因此实验报告是被存放在了内存中!因此传送文件的本质就是从一个磁盘拷贝到另一个磁盘!

二、操作系统

概念:

操作系统是一款进行管理的软件!

任何一个计算机系统都包含一个基本的程序集合,称为操作系统(OS),操作系统可分为两部分:

  • 内核(进程管理,内存管理,文件管理,驱动管理)
  • 其他程序(例如函数库,shell程序等等)

目的:

底层的硬件都采用的冯诺依曼体系结构,而硬件与操作系统之间需要通过驱动程序连接起来!

1、管理好下面的软硬件资源!

2、为了给用户提供一个良好(稳定、高效、安全)的运行环境!

总结:操作系统通过管理好底层的软硬件资源(手段),为用户提供一个良好的执行环境(目的)

操作系统里面会有各种数据,但是,操作系统不会信任任何用户!(类似银行)

操作系统为了保障自己的数据安全,也为了保证给用户能提供服务,操作系统以接口的方式给用户提供调用的入口,来获取操作系统内部的数据!(类似于银行的小窗口!)

操作系统本质是C语言实现的!

接口是操作系统提供的用C语言实现的,自己内部的函数调用!这个接口也被称为系统调用

所有的访问操作系统的行为,都只能通过系统调用完成!

但是,系统调用用起来比较麻烦,因此有人对系统调用做了各种功能的封装 --- > 用户操作接口

相关推荐
co0t7 分钟前
计算机网络(14)ip地址超详解
服务器·tcp/ip·计算机网络
C++忠实粉丝8 分钟前
计算机网络socket编程(3)_UDP网络编程实现简单聊天室
linux·网络·c++·网络协议·计算机网络·udp
淡水猫.13 分钟前
Fakelocation Server服务器/专业版 ubuntu
运维·服务器·ubuntu
wenyue112120 分钟前
Ease Monitor 会把基础层,中间件层的监控数据和服务的监控数据打通,从总体的视角提供监控分析
运维·中间件·监控
量子网络26 分钟前
debian 如何进入root
linux·服务器·debian
时光の尘29 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
我们的五年33 分钟前
【Linux课程学习】:进程描述---PCB(Process Control Block)
linux·运维·c++
-一杯为品-38 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
运维老司机1 小时前
Jenkins修改LOGO
运维·自动化·jenkins
戎梓漩1 小时前
windows下安装curl,并集成到visual studio
ide·windows·visual studio