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有两个值(知道就行后面会解释)

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

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

相关推荐
IpdataCloud21 分钟前
IP数据云 识别和分析tor、proxy等各类型代理
运维·服务器
五味香22 分钟前
Linux学习,ip 命令
linux·服务器·c语言·开发语言·git·学习·tcp/ip
落落落sss1 小时前
MQ集群
java·服务器·开发语言·后端·elasticsearch·adb·ruby
我救我自己1 小时前
UE5运行时创建slate窗口
java·服务器·ue5
朱容君2 小时前
Linux系统编程多线程之读写锁讲解
linux·开发语言
大风吹PP凉2 小时前
38配置管理工具(如Ansible、Puppet、Chef)
linux·运维·服务器·ansible·puppet
康熙38bdc2 小时前
Linux 进程间通信——共享内存
linux·运维·服务器
刘艳兵的学习博客2 小时前
刘艳兵-DBA033-如下那种应用场景符合Oracle ROWID存储规则?
服务器·数据库·oracle·面试·刘艳兵
jwybobo20072 小时前
redis7.x源码分析:(3) dict字典
linux·redis
scoone2 小时前
ssh登陆服务器后支持Tab键命令补全
linux·shell