Linux gcc day8 gdb进程概念

已经学习了

调试

Linux下的调试和windows下有区别吗?

1、调试思路上,一定时一样的

2、调试的操作方式、一定时不一样的-------》命令行调试gdb

注意编译报错问题

error: 'for' loop initial declarations are only allowed in C99 mode

note: use option -std=c99 or -std=gnu99 to compile your code

error: 'for' loop initial declarations are only allowed in C99 mode_'for' loop initial declarations are only allowed i-CSDN博客

实验

创建一个.c文件

cpp 复制代码
  1 #include <stdio.h>
  2 #include <time.h>   //可用man 3 time  查看用法

  3 void Print(int sum)
  4 {
  5     long long timestamp = time(NULL);//时间戳 
  6     printf("sum = %d  , timestamp=%lld\n",sum,timestamp);                               
  7 }
  8 int AddToVal(int from,int to)
  9 {
 10     int sum =0;
 11     int i;
 12     for( i= from; i < to; i++)
 13     {
 14         sum += i;
 15     }
 16     return sum;
 17 }
 18 
 19 int main()
 20 {
 21 
 22     int sum = AddToVal(0,100);
 23     Print(sum);
 24 
 25     return 0;
 26 }
~

可以用在线工具转换一下时间戳

如果出现bash 提醒证明没有安装,就需要

yum install -y gdb

gdb [文件名]

注意现在时不可以调试的

要知道我们的版本是要在debug下才可以调试,在release版本下是进行不了调试的

为什么要有debug版本和release版本

因为debug版本是个程序员调试的

release是给用户使用的

所以debug版本的体积肯定比release板的大
如何让它gcc编译出来就是debug版本呢?

gcc [文件.c] -o [修改名字] -g //-g就是指定为debug版本

修改makefile


readelf -S [可执行程序文件] //可以读取可执行程序二进制格式

//读到了很多不懂的东西,反正要知道可执行文件并不是简单的二进制,而是分了很多各区就可以

readelf -S 【可执行文件】


这样太多信息了

readelf -S 【可执行文件】| grep debug

gdb 操作

显示代码

(gdb) l 0 //从第0行显示 -list

(gdb) l 1 //从第1行显示

l 0 //执行命令后

按回车会自动显示下行代码因为会记住命令

打断点 breakpoint

(gdb) b n //给第n行打断点 ---形成编号,break也可以打断点

这里打了断点不像windows下可以看到断点,如何查看断点呢?

(gdb) info b//查看断点信息---看到编号

(gdb) d [编号] //去掉断点 delete

(gdb) r //运行起来并来到断点处

调试运行 r --run

逐过程 :n----next //到下一行

逐语句:s ----step

(gbd) c //运行至下一个断点处

bt //调用堆栈

finish //跑完逐语句的当函数

p //临时查看变量的值

display //长显示变量的值

undisplay

until N

为什么会来到18行?

总结下:

-------=======================================================------------------------

disable breakappoint [编号] //关闭断点,并不是取消断点

enable [编号] //打开断点

冯诺依曼体系结构

这里的存储器指的是谁?

内存:掉电易失

磁盘(外存):永久性存储能力

外设((输入设备和输出设备)或者仅输入仅输出):网卡和磁盘(都是输入输出 )

|----------------------|----|
| CPU:运算器+控制器+其他 (计算的) | 快 |
| 存储器(内存) (临时存储) | 较快 |
| 外设 (永久存储) | 较慢 |

CPU 其实只可以被动接受别人的指令,别人的数据- - -》执行别人的指令计算别人数据的目的

CPU有自己的指令集才可以认识到别人的指令

我们写代码,编译本质是做什么?将二进制可执行程序编译成指令,才可以让CPU认识

将外设上的数据预先存进内存里,定期再刷新,就可以很好的解决cpu和外设读取写入数据的差异

操作系统帮我们做策略(帮我们管理软硬件,临时数据的处理,刷新数据,清理,增加)

所以开机要加载操作系统

硬件和软件的完美结合就是计算机

将外设数据搬到内存中,内存中的数据写入到外设中的过程叫IO的过程INPUT/OUTPUT
总结:

在数据层面

cpu不和外设直接沟通,只和内存打交道

为了提高整机效率

example:

进度条 明明调用了printf为什么没被打印出来?显示屏是外设,代码加载到cpu不是直接输出到外设而是加载到内存中定期刷新的,这也是体系结构可以解释的

cpu的控制器:状态捕捉

cpu运算器:算术运算和逻辑运算

操作系统

是一个进行软硬件的管理

对于管理者的理解:

管理者不需要和被管理者直接交互依旧能够把被管理对象管理起来
管理者:需要具备重大事宜决策能力

如何做到的?

管理本质是管理者对数据的管理

我和管理者不需要有交互,但是我的所有数据,早就在管理者手上而且一直在更新

硬件做管理本质先描述再组织,描述后有了对应的内核的数据结构,再用特定数据结构将对象管理起来

总结:

1、做管理本质上是对数据进行管理

2、拿数据是有特定的驱动程序进行的

3、操作系统拿到数据之后要对数据进行描述(磁盘是磁盘的,键盘是键盘的),对应的设备再组织用特定的数据结构组织进行管理(先描述再组织)、

------------============================================----------------------------

银行与计算机软硬件体系结构的比较

系统调用层(保护操作系统)

shell(指令操作)c库(编程操作)。。。。等:

当我们向显示器打印是不是硬件写入?

显示器属于输出外设,在程序运行时,调用库中的printf, 根据冯诺依曼体系结构,从外设数据打入内存中,再由CPU处理返回给内存再打印到外设上,所以当我们调用printf,c++中的cout并不是直接打入硬件上的, 其实是printf调用了操作系统接口,让操作系统帮我们访问硬件打印的

其实硬件写入是一件成本很高的事情,我们第一次学习hello world就是输出到显示屏,不是库写的多好,而是操作系统给我们提供了接口

软硬件结构图:

系统调用和库函数概念

1、在开发角度,操作系统对外会表现为一个整体 但是会暴露自己的部分接口,供上层开发使用,这部分 由操作系统提供的接口,叫做系统调用。
2、系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

什么是进程?

struct task_struct 内核结构体 -》 内核对象task_struct 对象--》将该结构和你的代码和数据关联起来--》先描述,在组织的工作

注意:

进程=内核数据结构(task_struct)+进程对应的磁盘代码

为什么会有PCB(task_struct)结构体呢?

管理的本质是对数据做管理, 所以就要先拿到数据,拿到的数据可能很多、乱、杂。所以要对数据进行归类,根据先描述再组织,和面向对象的思想,提取对应的数据进行(按照统一标准)管理

操作系统是一个软件,它早就加载到内存中一直运行着,当要启动一个程序所谓的把磁盘上的程序加载到内存

----===---=====----============-----------------=================-----=================

见见进程:

windows下:

实验Linux

如何查看进程呢?

ps ajx //查看所有进程可以加一些指令一起和管道使用

ps ajx | grep [你要查的进程] //grep 行过滤

小技巧:

Linux中,进程都拥有以下的ID

  • Process ID(PID)
    Linux中标识进程的一个数字,它的值是不确定的,是由系统分配的(但是有一个例外,启动阶段,kernel运行的第一个进程是init,它的PID是1,是所有进程的最原始的父进程),每个进程都有唯一PID,当进程退出运行之后,PID就会回收,可能之后创建的进程会分配这个PID
  • Parent Process ID(PPID)
    字面意思,父进程的PID
  • Process Group ID(PGID)
    PGID就是进程所属的Group的Leader的PID,如果PGID=PID,那么该进程是Group Leader
  • Session ID(SID)
    和PGID非常相似,SID就是进程所属的Session Leader的PID,如果SID==PID,那么该进程是session leader

杀掉进程

kill -9 [PID编码] //进程ID

第一个系统调用getpid

查看运行起来后,才会使用系统调用接口,才获取进程中的标识

注意:

=========================================================================

根目录下有一个文件proc是一个内存级的文件

注意

下面的这个数字目录其实是进程编号就是刚刚在运行代码的PID

就可以找到

ls -d //如果查看的是一个目录就只显示目录名不显示子文件

exe是进程对应的可执行文件(磁盘)

进程是加载磁盘上exe

如果在运行中删除exe,就是已经写入内存中了,将exe删除会发生什么?

另一种调用方式(了解)

getppid()

探讨一下

如果我们结束这个进程会发生什么呢?

总结:

在命令行上启动的进程,一般它的父进程没有特殊情况的话,都是bash

父bash交给子bash去执行,出问题没有影响到父进程

比如写了个代码是错误的,父bash创建子bash执行,直接报错此时子bash搞砸了,子bash结束了返回报错问题,但是父bash还是可以用

Linux如何创建子进程(见见🐖跑)

man 2 fork //系统调用手册

学习返回值

这个id有两个值(知道就行后面会解释)

两个死循环可以同时执行就证明了有两个进程

并发式编程 不同系统和语言不一样

相关推荐
飞雪20071 小时前
Alibaba Cloud Linux 3 在 Apple M 芯片 Mac 的 VMware Fusion 上部署的完整密码重置教程(二)
linux·macos·阿里云·vmware·虚拟机·aliyun·alibaba cloud
路溪非溪1 小时前
关于Linux内核中头文件问题相关总结
linux
海绵不是宝宝8172 小时前
连接远程服务器上的 jupyter notebook,解放本地电脑
服务器·jupyter·github
Lovyk4 小时前
Linux 正则表达式
linux·运维
Fireworkitte5 小时前
Ubuntu、CentOS、AlmaLinux 9.5的 rc.local实现 开机启动
linux·ubuntu·centos
sword devil9005 小时前
ubuntu常见问题汇总
linux·ubuntu
ac.char5 小时前
在CentOS系统中查询已删除但仍占用磁盘空间的文件
linux·运维·centos
繁星¹⁸⁹⁵6 小时前
通过update-alternatives可以实现cuda的多版本切换
服务器
淮北也生橘127 小时前
Linux的ALSA音频框架学习笔记
linux·笔记·学习
开航母的李大9 小时前
软件系统运维常见问题
运维·服务器·系统架构·运维开发