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语言实现的,自己内部的函数调用!这个接口也被称为系统调用

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

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

相关推荐
丁卯4041 小时前
Go语言中使用viper绑定结构体和yaml文件信息时,标签的使用
服务器·后端·golang
chengooooooo1 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
人间打气筒(Ada)2 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231112 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql
Moonnnn.3 小时前
51单片机学习——动态数码管显示
笔记·嵌入式硬件·学习·51单片机
落笔画忧愁e3 小时前
FastGPT快速将消息发送至飞书
服务器·数据库·飞书
小冷爱学习!3 小时前
华为动态路由-OSPF-完全末梢区域
服务器·网络·华为
南宫生4 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
技术小齐4 小时前
网络运维学习笔记 016网工初级(HCIA-Datacom与CCNA-EI)PPP点对点协议和PPPoE以太网上的点对点协议(此处只讲华为)
运维·网络·学习
ITPUB-微风4 小时前
Service Mesh在爱奇艺的落地实践:架构、运维与扩展
运维·架构·service_mesh