祝各位道友念头通达
GitHub Gitee 语雀 打赏

linux c下程序调试工具详解

/proc 目录

/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。

/proc/cpuinfo

查看CPU信息,核数

/proc/meminfo

查看CPU当前内存使用情况, 包括CMA,vmalloc等内存使用情况

/proc/iomem

记录外设物理地址的分配情况, https://www.jianshu.com/p/50cba3e2554c

/proc/vmallocinfo

这里面包含了所有外设程序物理地址和虚拟地址之间的占用和转换关系
比如如下是PCIE驱动的两个bar空间,对应的物理内存和虚拟内存的地址
image

/proc/interrupts

包含了所有程序的对应的中断, 查看一个程序申请的相关的中断可以在这里查看

cachestat 和 cachetop

node@root:~$ sudo cachestat
Counting cache functions... Output every 1 seconds.
    HITS   MISSES  DIRTIES    RATIO   BUFFERS_MB   CACHE_MB
   23834        0        0   100.0%          699       4360

HITS 是缓存命中的次数;
MISSES 是缓存未命中的次数;
DIRTIES 是表示新增到缓存中的脏页数;
BUFFERS_MB 表示 Buffers 的大小,单位为 MB;
CACHED_MB 表示 Cache 的大小,单位为 MB。

perf 性能分析工具

详细使用文档: https://zhuanlan.zhihu.com/p/141694060
perf stat

  • task-clock:任务真正占用的处理器时间,单位为ms。CPUs utilized = task-clock / time elapsed,CPU的占用率,值高,说明程序的多数时间花费在CPU计算上而非IO。
  • context-switches:上下文的切换次数。
  • CPU-migrations:处理器迁移次数。Linux为了维持多个处理器的负载均衡,在特定条件下会将某个任务从一个CPU迁移到另一个CPU。
  • page-faults:缺页异常的次数。当应用程序请求的页面尚未建立、请求的页面不在内存中,或者请求的页面虽然在内存中,但物理地址和虚拟地址的映射关系尚未建立时,都会触发一次缺页异常。另外TLB不命中,页面访问权限不匹配等情况也会触发缺页异常。
  • cycles:消耗的处理器周期数。
  • instructions:执行了多少条指令。IPC为平均每个cpu cycle执行了多少条
  • branches:遇到的分支指令数。
  • branch-misses:预测错误的分支指令数。

硬件设备查看

lspci |dmidecode|lshw|lscpu|lsusb

查看硬件信息,包括 CPU、BIOS、RAID、显卡、USB设备等

sysctl

在内核运行时动态地查看和修改内核的运行参数
last |w
登入记录,查看正在登录的用户

watch + 指令

监听指令运行状况

size

[root@process_comm#] size a.out
   text    data     bss     dec     hex filename
   2222     572       4    2798     aee a.out

可执行程序的一些数据存放分为好几个区域:
.text 存放运行的代码,运行前就确定了
.data 存放已经初始化的全局变量, 静态内存
.bss 静态内存分配, 存放全局变量
dec 和 hex 为统计总量
类似这种指令还有
readelf,ldd,nm,file,strip,strings,objdump

atop

atop 命令是一个终端环境的监控命令。它显示的是各种系统资源(CPU, memory, network, I/O, kernel)的综合,并且在高负载的情况下进行了彩色标注
yum/apt install -y atop

htop/top

htop
image
top
image
htop 主要参数说明

# Time:当前时间
# Uptime:系统运行时间
# Tasks:进程总数、当前进程运行数
# Load average:1、5、10分钟的负载情况
# Avg:系统CPU的平均值,和左侧的CPU结合看
# 左侧的CPU:监测cup每个核的运行状态

# PID: 进程ID
# USER: 进程运行所属用户
# PRI: 优先级,内核修改
# NI: 优先级,运行时指定, 越低级别越高,nice -n [优先级,-20~19] [执行指令], renice 可修改执行中的线程优先级
# VIRI: 进程所需虚拟内存大小
 1. 包括进程使用的库、代码、数据等
 2. 申请100MB内存,实际使用10MB, 则增长100MB
# RES: 占用物理内存
 1. 进程当前使用的内存大小, 但不包括交换内存(Swp)
 2. 申请100MB内存,实际使用10MB, 则增长10MB
 3. 对库占用而言,只统计加载的库文件所占内存大
 4. 包含进程的共享内存, 计算进程占用实际物理内存RES-SHR
# SHR: 占用的共享内存值
 1. 相关进程的总的共享内存
 2. 包含整个共享库的大小
 3. 计算某个进程所占用的物理内存大小公式: RES-SHR
 4. swap out 交换内存, 该值会将下来
# S: 运行状况, R(正在运行), S(休眠), Z(僵死状态)
# %CPU: 占用CPU使用率
# %MEM: 该进程占用的物理内存和总内存的百分比
 1. 如果该值和 RES的值一直增长, 很大概率说明内存未释放
# TIME+: 该进程所占用CPU的总时间
# COMMAND: 进程启动命令名称

free

其实使用htop, 包含了free

[root@tracing#] free -h
              total        used        free      shared  buff/cache   available
Mem:           3.7G        861M        235M        9.9M        2.6G        2.6G
Swap:            0B          0B          0B

iostat

https://www.cnblogs.com/ftl1012/p/iostat.html
安装: yum install sysstat -y

[root@tracing#] iostat
Linux 3.10.0-1160.49.1.el7.x86_64 (VM-24-7-centos)      11/28/2022      _x86_64_        (2 CPU)
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.68    0.01    0.73    0.04    0.00   97.54
Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
vda               3.15         1.50        27.04   16183374  292073156
scd0              0.00         0.00         0.00        360          0

说明:

# %user:CPU处在用户模式下的时间百分比。
# %nice:CPU处在带NICE值的用户模式下的时间百分比。
# %system:CPU处在系统模式下的时间百分比。
# %iowait:CPU等待输入输出完成时间的百分比。
 > 如果%iowait的值过高,表示硬盘存在I/O瓶颈
# %steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。
# %idle:CPU空闲时间百分比。
 1. 如果%idle值高,表示CPU较空闲
 2. 如果%idle值高但系统响应慢时,可能是CPU等待分配内存,应加大内存容量
 3. 如果%idle值持续低于cpu核数,表明CPU处理能力相对较低,系统中最需要解决的资源是CPU

taskset

将某个一个线程绑定到指定的CPU上去运行, 以减少线程上下文切换, 保证线程的实时性, 不同的linux系统设置稍微有不同

这个还需要对系统参数isolcpus做出修改, 如下:

嵌入式arm 如何将指定的用户态/内核态线程绑定到指定CPU

centos 如何指定 isolcpus参数, 隔离CPU 执行指定任务

对于centos来说, 直接修改 /etc/default/grub
GRUB_CMDLINE_LINUX, 在最后加上 isolcpus=1,2,3, 或者 isolcpus=1-3, 然后 grub2-mkconfig -o /boot/grub2/grub.cfg, 则系统再次启动之后, 就不会使用逻辑 核心2, 3, 4

cgroup

cgroups,其名称源自控制组群(control groups)的简写,是Linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如CPU、内存、磁盘输入输出等)
主要用途:

  1. 资源限制使用, 如内存使用上限/CPU使用限制
  2. 优先级控制, 如: CPU利用/磁盘IO吞吐
  3. 一些审计或统计
  4. 挂起进程/恢复执行进程

(Centos8 如何使用cgroups)[https://www.cnblogs.com/architectforest/p/13126905.html]

ftrace / systemtap / kpatch

1、ftrace
Linux当前版本中,功能最强大的调试、跟踪手段。其最基本的功能是提供了动态和静态探测点,用于探测内核中指定位置上的相关信息。
静态探测点,是在内核代码中调用ftrace提供的相应接口实现,称之为静态是因为,是在内核代码中写死的,静态编译到内核代码中的,在内核编译后,就不能再动态修改。在开启ftrace相关的内核配置选项后,内核中已经在一些关键的地方设置了静态探测点,需要使用时,即可查看到相应的信息。
动态探测点,基本原理为:利用mcount机制,在内核编译时,在每个函数入口保留数个字节,然后在使用ftrace时,将保留的字节替换为需要的指令,比如跳转到需要的执行探测操作的代码。

2、kpatch
kpatch是RedHat主导开发的“内核在线升级”工具,可在不重启系统、不中断业务的情况下实现内核在线升级。实现函数级别的执行流程替换。
其基本原理为:基于ftrace,类似于ftrace的动态探测点,利用mcount机制,在内核编译时,在每个函数入口保留数个字节,然后在打补丁时,将“被替换函数”入口保留的字节替换为跳转指令,跳转到kpatch的相关流程中,然后进入“新函数”的执行流程,实现函数级别的执行流程在线替换,最终实现“内核在线升级”的功能。

3、systemTap
另一个具有探测功能的工具,不得不提systemTap。
其原理跟ftrace不同,其基本原理为:在运行systemTap脚本时,动态解析内核,将指定探测点处的代码,替换为int 3指令,实现陷入,在陷入后实现相关信息的探测,探测完成后,int 3返回到原有的执行流程中执行。

4、ftrace和systemTap机制的主要区别
1)ftrace只能在函数入口(或出口?)实现探测,而systemTap可以在函数中的任意位置实现探测。
2)ftrace实现函数替换后,原有函数的执行流程被替换成新函数,新函数执行完成后可以不再返回原函数流程中执行。而systemTap利用的是int 3陷入机制,在探测后会自动跳转会原有流程执行。

posted @ 2022-11-28 13:53  韩若明瞳  阅读(344)  评论(0编辑  收藏  举报