• 正文
  • 相关推荐
申请入驻 产业图谱

QNX内存分析-pidin mem

09/21 08:45
127
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

上篇介绍了如何在VirtualBox中安装QNX系统,本篇来探究QNX系统中pidin mem指令给出的信息中,进程的内存使用是如何表现的。

1 预备知识

在开始正式研究pidin mem指令之前,先了解些预备知识。

1.1  ELF

ELF = Executable and Linkable Format(可执行与可链接格式),它是Unix 系的可执行文件、共享库、目标文件.o)统一用的容器格式。

一个 ELF 文件内部按 section(段) 组织:

section 装什么 在文件里
.text 机器指令(编译后的代码) 占空间
.rodata 只读数据,字符串常量、const 全局量 占空间,通常和 .text 一起映射
.data 已初始化且初值非零的全局/静态变量 占空间
.bss 未初始化、或初值为 0 的全局/静态变量 占 0 字节

pidin 的 code 列 = .text + .rodata

1.2 bss

bss = Block Started by Symbol ,1950 年代 IBM 704 上汇编器的一条伪指令名,意思是"从这里开始预留一块空间给符号"。

Unix 沿用了这个名字,现在指存放未初始化(或初值为 0)的全局变量和静态变量的那一段

它装的是这些东西:

int g_buffer[4096];        // 未初始化 → .bss
static int counter = 0;    // 初值为 0 → 编译器也塞进 .bss
int g_flag = 1;            // 初值非零 → .data

为什么文件里不占空间:内容反正全是 0,存 4096 个零字节纯浪费,所以 ELF 只在 section header 里记一个"长度 16K",加载器看到就直接映射一段零页。这是 ELF 设计的经典取巧。

.bss 没有文件后端,加载器只能"凭空造一段全零的私有内存" —— pidin 把它显示为 **zero ELF**,名字取得很贴切:ELF 对象里那个"zero 的部分"。


简单说:ELF 是文件格式,bss 是它里面"不占磁盘、加载时现造一段零页"的那个段;pidin 把 ELF 的 text 报成 code、data 报成 data、bss 单独报成 **zero ELF** 。

2 pidin mem

输入pidin mem后,会有如下打印,会列举出所有的进程和线程,这里截图开头的部分

表头含义

pid tid name prio STATE code data stack
进程号 线程号 名称 优先级+策略 状态 代码段 数据段 栈(已用/上限)

如果想知道一共多少个进程和线程,可以用top指令看一下:

可以看到有25个进程和113个线程。

下面先来看pidin mem的每个进程的分析。

2.1 进程[1]procnto-smp-instr分析

procnto属于内核进程,‌procnto 是**“Process Neutrino”**‌的缩写,即 QNX Neutrino 微内核与进程管理器的组合模块

    pid tid name                         prio STATE                      code  data        stack
      1   1 /proc/boot/procnto-smp-instr   0f READY                      788K  157K     28K/164K
      1   2 /proc/boot/procnto-smp-instr   0f READY                      788K  157K     28K/164K
      1   3 /proc/boot/procnto-smp-instr 255i INTR                       788K  157K       0/164K
      1   4 /proc/boot/procnto-smp-instr 255i INTR                       788K  157K       0/164K
      1   5 /proc/boot/procnto-smp-instr 254i INTR                       788K  157K       0/164K
      1   6 /proc/boot/procnto-smp-instr 254i INTR                       788K  157K       0/164K
      1   7 /proc/boot/procnto-smp-instr   1f NANOSLEEP                  788K  157K       0/164K
      1   8 /proc/boot/procnto-smp-instr  10r ???                        788K  157K     12K/164K
      1   9 /proc/boot/procnto-smp-instr  10r RECEIVE                    788K  157K     12K/164K
      1  10 /proc/boot/procnto-smp-instr  10r RECEIVE                    788K  157K     12K/164K
      1  11 /proc/boot/procnto-smp-instr  10r RECEIVE                    788K  157K     12K/164K
      1  12 /proc/boot/procnto-smp-instr  10r RECEIVE                    788K  157K     12K/164K
      1  13 /proc/boot/procnto-smp-instr  11r RECEIVE                    788K  157K     12K/164K
      1  14 /proc/boot/procnto-smp-instr  10r RUNNING                    788K  157K     12K/164K
      1  15 /proc/boot/procnto-smp-instr  10r RECEIVE                    788K  157K     12K/164K
      1  16 /proc/boot/procnto-smp-instr  10r RECEIVE                    788K  157K     12K/164K
            procnto-smp-instr             @ffff800000001000                 788K  157K

stack总计:28x2 + 12x9 = 56 + 108 = 164K ✓

2.1.1 逐行分析

第一行
1   1 /proc/boot/procnto-smp-instr   0f READY                      788K  157K     28K/164K

根据表头,对比来看

字段 含义
pid/tid 1 / 1 进程ID/线程ID,procnto 永远是 pid 1,它把微内核和进程管理器打在一个进程里
prio 0f 优先级 0(最低,只有 idle 线程用)+ f = FIFO 调度
STATE READY 就绪
code/data 788K / 157K 代码段、数据段的大小,进程级
stack 28K/164K 线程栈,当前线程栈 28K,进程中所有线程栈累计164K(进程的上限)
所有行对比看

这些线程的 prio/STATE/已用stack 逐个看:

tid prio STATE 线程stack 说明
1, 2 0f READY 28K idle 线程,每个 CPU 一个(这台机器 2 核)
3, 4 255i INTR 0 中断线程i 表示中断上下文,255 是最高优先级
5, 6 254i INTR 0 中断线程,254 稍低
7 1f NANOSLEEP 0 内核定时器线程
8 10r ??? 12K 内核内部线程,pidin 认不出状态,正常现象
9-13, 15, 16 10r RECEIVE 12K 阻塞在消息接收的服务线程(tid 13 是 11r,优先级 11)
14 10r RUNNING 12K 抓样瞬间正在跑
最后一行

最后一行,是 procnto 的映射明细行(缩进、带 @地址

procnto-smp-instr             @ffff800000001000                 788K  157K

注意地址 0xffff800000001000 —— x86-64 上 0xffff8... 开头是内核地址空间,印证了 procnto 的代码/数据运行在内核半区,而不是普通用户态地址(0x2ada... 那种)。

而且它只有这一条映射,没有 libc 等共享库,说明 procnto 是静态自包含的镜像。

2.1.2 总结procnto

procnto-smp-instr(pid 1)是微内核与进程管理器的合体。

那 16 行打印的是它的 16 个线程而非 16 份内存 —— code 788K、data 157K 每行都相同、只能算一次。

唯一一条映射行落在内核地址空间 0xffff800000001000 且没有任何共享库依赖。

整个"内核"只占 1109K。

组成 数值 来源
code 788K 映射行第 2 列,进程级
data 157K 映射行第 3 列,进程级
164K 28K×2 + 0×5 + 12K×9,逐线程相加
合计 1109K

2.2 进程[13687]slogger2分析

slogger2是系统日志服务(‌system logger service‌),它只有一个 tid → 单线程进程。

10r RECEIVE 是服务器的标准姿势:阻塞在 MsgReceive() 等客户端请求。

   16387   1 proc/boot/slogger2            10r RECEIVE                   1108K  476K    512K/512K
             slogger2                      @2ada120000                  64K  8192
             ldqnx-64.so.2                 @4ab6994000                 224K   12K
             libslog2.so.1                 @4ab69d0000                  20K  4096
             libsecpol.so.1                @4ab69d7000                  20K  4096
             libc.so.6                     @4ab69de000                 668K  8192
             libgcc_s.so.1                 @4ab6a91000                 112K  4096
             **heap**                      @18eaa81000 (       0)             84K
             **zero ELF**                  @2ada132000 (       0)            4096
             /shmem/slogger2/console.16387 @301f2ad000 (       0)             20K
             hmem/slogger2/devb_eide.53254 @301f2b2000 (       0)             68K
             /shmem/slogger2/io_hid.118791 @301f2c3000 (       0)             68K
             hmem/slogger2/devc_pty.200719 @301f2d4000 (       0)             68K
             /shmem/slogger2/dhcpcd.266259 @301f2e5000 (       0)             68K
             **zero ELF**                  @4ab69cf000 (       0)            4096
             **zero ELF**                  @4ab69d5000 (       0)            4096
             **zero ELF**                  @4ab69dc000 (       0)            4096
             **zero ELF**                  @4ab6a85000 (       0)             16K
             **zero ELF**                  @4ab6a8b000 (       0)             24K
             **zero ELF**                  @4ab6aad000 (       0)            4096

2.2.1 映射行的两种格式

后面的映射行有两种格式

格式 A —— 可执行文件与共享库

code 和 data 各占一列

slogger2   @2ada120000   64K  8192
对象名 加载地址 code data
slogger2 @2ada120000 64K 8192
可执行文件自身 用户态虚拟地址 只读可执行段 .text 可写数据段,8K
格式 B

格式一样,实际作用又可分为三类

    heap,堆shmem,共享内存zero ELF,零页

code 写进括号里,只剩一列 size

**heap**                      @18eaa81000 (       0)             84K
对象名 加载地址 offset(括号内) size
**heap** @18eaa81000 0 84K
双星号包裹 = 匿名内存 虚拟地址 mmap的偏移量 末列即 data,计入总数

判断方法:

    行内出现左圆括号就是格式 B,此时 code = 括号里的数(通常为 0),末列解析为 data否则末两列分别是 code 和 data

2.2.2 对19 条映射行逐条分析

2.2.2.1 ELF对象

前 6 条是 ELF 对象(格式 A,可执行文件 + 5 个共享库)

对象 code data 说明
1 slogger2 64K 8K 可执行文件本体,text 只有 64K
2 ldqnx-64.so.2 224K 12K 动态链接器,每个进程都加载
3 libslog2.so.1 20K 4K 日志库
4 libsecpol.so.1 20K 4K 安全策略库
5 libc.so.6 668K 8K code 的大头,占 60%
6 libgcc_s.so.1 112K 4K GCC 运行时
2.2.2.2 格式B部分

             **heap**                      @18eaa81000 (       0)             84K

第 7 条是堆(格式 B):**heap** 84K —— malloc 分配来的

共享内存

第 9–13 条注意名字被截断了:

             /shmem/slogger2/console.16387 @301f2ad000 (       0)             20K
             hmem/slogger2/devb_eide.53254 @301f2b2000 (       0)             68K
             /shmem/slogger2/io_hid.118791 @301f2c3000 (       0)             68K
             hmem/slogger2/devc_pty.200719 @301f2d4000 (       0)             68K
             /shmem/slogger2/dhcpcd.266259 @301f2e5000 (       0)             68K

name 列固定约 29 字符宽,超长从左边截

比如这两行的真名分别是

/dev/shmem/slogger2/console.16387/dev/shmem/slogger2/devb_eide.53254

这是 slogger2 给每个日志客户端开的共享缓冲区,68K 是默认尺寸,名字里的数字就是客户端 pid。

bss(zero ELF)

第8条-slogger2 本体的 bss

             **zero ELF**                  @2ada132000 (       0)            4096

第14~19条-各共享库的 bss

全是 **zero ELF**,也就是各 ELF 的 .bss(未初始化数据,文件里不占空间,加载时要匿名内存)。

2.2.3 按地址排序分析

可以将ELF对象与bss按地址进行排序:

# 地址 对象 code data 类别 说明
1 0x18eaa81000 **heap** (0) 84K 簇①,孤立
2 0x2ada120000 slogger2 64K 8K 主程序 簇② 起
3 0x2ada132000 **zero ELF** (0) 4K bss 属 slogger2(+64K+8K 吻合)
4 0x301f2ad000 /shmem/…/console.16387 (0) 20K shmem 簇③ 起
5 0x301f2b2000 /shmem/…/devb_eide.53254 (0) 68K shmem 紧邻上条
6 0x301f2c3000 /shmem/…/io_hid.118791 (0) 68K shmem 紧邻
7 0x301f2d4000 /shmem/…/devc_pty.200719 (0) 68K shmem 紧邻
8 0x301f2e5000 /shmem/…/dhcpcd.266259 (0) 68K shmem 紧邻
9 0x4ab6994000 ldqnx-64.so.2 224K 12K 共享库 簇④ 起
10 0x4ab69cf000 **zero ELF** (0) 4K bss 属 ldqnx(+224K+12K)
11 0x4ab69d0000 libslog2.so.1 20K 4K 共享库
12 0x4ab69d5000 **zero ELF** (0) 4K bss 属 libslog2(+20K)
13 0x4ab69d7000 libsecpol.so.1 20K 4K 共享库
14 0x4ab69dc000 **zero ELF** (0) 4K bss 属 libsecpol(+20K)
15 0x4ab69de000 libc.so.6 668K 8K 共享库
16 0x4ab6a85000 **zero ELF** (0) 16K bss libc 第一段(+668K)
17 0x4ab6a8b000 **zero ELF** (0) 24K bss libc 第二段,末尾正好接 libgcc
18 0x4ab6a91000 libgcc_s.so.1 112K 4K 共享库
19 0x4ab6aad000 **zero ELF** (0) 4K bss 属 libgcc(+112K)

简单分析下slogger2

地址是  0x2ada120000,code是64k,data是8k它的zero ELF的地址是0x2ada132000

两地址相减,0x32000 - 0x20000 = 0x12000,十进制73728,也就是72K,即slogger2的data和zero ELF是紧邻的

再来看下libc.so.6,注意到,libc的bss是拆成两段

libc.so.6地址是0x4ab69de000,code是668k,data是8k第一个zero ELF地址是0x4ab6a85000,自身16K与libc的地址相减是0x0a7000,十进制684032,也就是668K,即这个zero ELF是跟在libc的code之后的

第二个zero ELF地址是0x4ab6a8b000,自身24K与第一个zero ELF地址相减是0x6000,十进制24576,也就是24K,而第一个zero ELF自身只有16K

注意到libc的data是8K,这8K没有分析到具体位置,可以猜想,两个zero ELF中间的8K,可能就是libc的data的位置

2.2.4 求和验算

code:  64 + 224 + 20 + 20 + 668 + 112 = 1108K  ← 等于进程行 code ✓
data:  40K(6个对象的data: 8K + 12K + 4K + 4K + 8K + 4K) + 84K(heap)
     + 292K(shmem: 20K + 68K×4)
     +  60K(zero ELF 7条: 16K + 24K + 4K×5) = 476K  ← 等于进程行 data ✓

2.2.5 总结slogger2

slogger2 这个进程,pidin mem给出的内存占用情况是:

code:1108K(1044K 来自共享库,只有 64K 是它自己)data:476K ELF对象40K:slogger2的8K + so库的32Kheap 84K 共享内存292Kbss(zero ELF)  60K stack:512K

总计占用内存:1108 + 476 + 512 = 2096K

如何是考虑进程自身单独的,比如去除code中共享库,去除data中的共享内存,可以是 760K(64K 自身code + 40K ELF对象data + 84K heap + 60K bss + 512K stack)

2.3 进程[28676]pci-server分析

‌它是PCI 服务进程‌,全称即 ‌PCI Server‌,负责核心的 PCI 总线与设备管理服务

   28676   1 proc/boot/pci-server          10r RECEIVE                   1452K  684K   256K/1024K
   28676   2 proc/boot/pci-server          10r RECEIVE                   1452K  684K   256K/1024K
   28676   3 proc/boot/pci-server          21r RECEIVE                   1452K  684K   256K/1024K
   28676   4 proc/boot/pci-server          10r RECEIVE                   1452K  684K   256K/1024K
             pci-server                    @35d2837000                 156K  8192
             ldqnx-64.so.2                 @25c846a000                 224K   12K
             libpci.so.3.0                 @25c84a6000                 136K   16K
             libsecpol.so.1                @25c84ce000                  20K  4096
             libc.so.6                     @25c84d5000                 668K  8192
             libgcc_s.so.1                 @25c8588000                 112K  4096
             pci_slog2.so.3.0              @25c85a6000                 8192  4096
             libslog2.so.1                 @25c85aa000                  20K  4096
             pci_debug2.so.3.0             @25c85b1000                 4096  4096
             pci_hw-Intel_x86.so.3.1       @25c85b4000                 104K  4096
             mem/slogger2/pci_server.28676 @145ebf2000 (       0)             68K
             /dev/shmem/pci/pci_hw         @145ec03000 (       0)            4096
             /slogger2/pci_server.28676..0 @145ec04000 (       0)             68K
             /dev/shmem/pci/pci_db         @145ec15000 (       0)             36K
             /dev/shmem/pci/pci_sync       @145ec1e000 (       0)            4096
             **zero ELF**                  @25c84a5000 (       0)            4096
             **zero ELF**                  @25c84c8000 (       0)            8192
             **zero ELF**                  @25c84d3000 (       0)            4096
             **zero ELF**                  @25c857c000 (       0)             16K
             **zero ELF**                  @25c8582000 (       0)             24K
             **zero ELF**                  @25c85a4000 (       0)            4096
             **zero ELF**                  @25c85a8000 (       0)            4096
             **zero ELF**                  @25c85af000 (       0)            4096
             **zero ELF**                  @25c85b2000 (       0)            4096
             **zero ELF**                  @25c85ce000 (       0)            4096
             **zero ELF**                  @25c85d0000 (       0)             64K
             **heap**                      @50641ae000 (       0)             28K
             **heap**                      @50641b5000 (       0)            4096
             **heap**                      @50641b6000 (       0)            264K

2.3.1 有4个进程

   28676   1 proc/boot/pci-server          10r RECEIVE                   1452K  684K   256K/1024K
   28676   2 proc/boot/pci-server          10r RECEIVE                   1452K  684K   256K/1024K
   28676   3 proc/boot/pci-server          21r RECEIVE                   1452K  684K   256K/1024K
   28676   4 proc/boot/pci-server          10r RECEIVE                   1452K  684K   256K/1024K

tid 3 是 21r,比另外三个 10r 高—— 这是 PCI 的配置访问/中断响应线程,必须抢在其他工作线程前面。

stack总计:256x4 = 1024K ✓

2.3.2 有10个ELF对象

对象 code data 性质
pci-server 156K 8K 自己
libc.so.6 668K 8K 通用
ldqnx-64.so.2 224K 12K 通用
libpci.so.3.0 136K 16K PCI 专用
libgcc_s.so.1 112K 4K 通用
pci_hw-Intel_x86.so.3.1 104K 4K PCI 硬件驱动模块
libsecpol.so.1 20K 4K 通用
libslog2.so.1 20K 4K 通用
pci_slog2.so.3.0 8K 4K PCI 专用
pci_debug2.so.3.0 4K 4K PCI 专用
小计 1452K ✓ 68K

自己的 code 只占 156K,libc 一个就占668K。

2.3.3 格式B部分

共享内存

共享内存 180K(5 条,其中 2 条名字被左截断):

mem/slogger2/pci_server.28676   → /dev/shmem/slogger2/pci_server.28676    68K
/slogger2/pci_server.28676..0   → /dev/shmem/slogger2/pci_server.28676..0 68K
/dev/shmem/pci/pci_db                                                     36K
/dev/shmem/pci/pci_hw                                                      4K
/dev/shmem/pci/pci_sync                                                    4K

小计:68 + 68 + 36 + 4 + 4 = 180

bss(zero ELF)

bss 140K:11 条 **zero ELF**

             **zero ELF**                  @25c84a5000 (       0)            4096
             **zero ELF**                  @25c84c8000 (       0)            8192
             **zero ELF**                  @25c84d3000 (       0)            4096
             **zero ELF**                  @25c857c000 (       0)             16K
             **zero ELF**                  @25c8582000 (       0)             24K
             **zero ELF**                  @25c85a4000 (       0)            4096
             **zero ELF**                  @25c85a8000 (       0)            4096
             **zero ELF**                  @25c85af000 (       0)            4096
             **zero ELF**                  @25c85b2000 (       0)            4096
             **zero ELF**                  @25c85ce000 (       0)            4096
             **zero ELF**                  @25c85d0000 (       0)             64K

小计:4 + 8 + 4 + 16 + 24 + 4*5 + 64 = 140

堆 296K:3 条。

             **heap**                      @50641ae000 (       0)             28K
             **heap**                      @50641b5000 (       0)            4096
             **heap**                      @50641b6000 (       0)            264K

小计:28 + 4 + 264 = 296

data总计:68(库data)+ 180(shmem)+ 140(bss)+ 296(heap)= 684K ✓

2.3.4 按地址排序分析

# 地址 GiB 对象 code data 类别 说明
1 0x145ebf2000 81.5 /dev/shmem/slogger2/pci_server.28676 (0) 68K shmem 簇① 起
2 0x145ec03000 81.5 /dev/shmem/pci/pci_hw (0) 4K shmem 紧邻
3 0x145ec04000 81.5 /dev/shmem/slogger2/pci_server.28676..0 (0) 68K shmem 紧邻
4 0x145ec15000 81.5 /dev/shmem/pci/pci_db (0) 36K shmem 紧邻
5 0x145ec1e000 81.5 /dev/shmem/pci/pci_sync (0) 4K shmem 紧邻
6 0x25c846a000 151.1 ldqnx-64.so.2 224K 12K 簇② 起
7 0x25c84a5000 151.1 **zero ELF** (0) 4K bss 属 ldqnx(+224K+12K)
8 0x25c84a6000 151.1 libpci.so.3.0 136K 16K
9 0x25c84c8000 151.1 **zero ELF** (0) 8K bss 属 libpci(+136K)
10 0x25c84ce000 151.1 libsecpol.so.1 20K 4K
11 0x25c84d3000 151.1 **zero ELF** (0) 4K bss 属 libsecpol(+20K)
12 0x25c84d5000 151.1 libc.so.6 668K 8K
13 0x25c857c000 151.1 **zero ELF** (0) 16K bss libc ①(+668K)
14 0x25c8582000 151.1 **zero ELF** (0) 24K bss libc ②(末接 libgcc)
15 0x25c8588000 151.1 libgcc_s.so.1 112K 4K
16 0x25c85a4000 151.1 **zero ELF** (0) 4K bss 属 libgcc(+112K)
17 0x25c85a6000 151.1 pci_slog2.so.3.0 8K 4K
18 0x25c85a8000 151.1 **zero ELF** (0) 4K bss 属 pci_slog2(+8K)
19 0x25c85aa000 151.1 libslog2.so.1 20K 4K
20 0x25c85af000 151.1 **zero ELF** (0) 4K bss 属 libslog2(+20K)
21 0x25c85b1000 151.1 pci_debug2.so.3.0 4K 4K
22 0x25c85b2000 151.1 **zero ELF** (0) 4K bss 属 pci_debug2(+4K)
23 0x25c85b4000 151.1 pci_hw-Intel_x86.so.3.1 104K 4K
24 0x25c85ce000 151.1 **zero ELF** (0) 4K bss pci_hw ①(+104K)
25 0x25c85d0000 151.1 **zero ELF** (0) 64K bss pci_hw ②(中间夹 data 4K)
26 0x35d2837000 215.3 pci-server 156K 8K 本体 簇③,孤立
27 0x50641ae000 321.6 **heap** (0) 28K 簇④ 起
28 0x50641b5000 321.6 **heap** (0) 4K 紧邻
29 0x50641b6000 321.6 **heap** (0) 264K 紧邻

注意到:

    pci-server 自没有独立 bss(它的 data 8K 已涵盖)libc 和 pci_hw 各拆两段pci_hw 那 64K 是最大的单条 bss,应该是 Intel x86 PCI 控制器的设备表缓存堆 296K 是三段首尾相接,实际是一整块 296K 堆区被拆成三条列出(多半是不同分配批次或权限)
@50641ae000  28K  ─┐
@50641b5000   4K   ├─ 0x50641ae000 + 28K = 0x50641b5000 ✓
@50641b6000 264K  ─┘  0x50641b5000 +  4K = 0x50641b6000 ✓

2.4 进程[49157]fsevmgr分析

fsevmgr 全称可能是 ‌Flash Storage Event Manager‌(闪存存储事件管理器)

   49157   1 proc/boot/fsevmgr             10r SIGWAITINFO               1176K  228K    512K/584K
   49157   2 proc/boot/fsevmgr             10r RECEIVE                   1176K  228K     24K/584K
   49157   3 proc/boot/fsevmgr             10r RECEIVE                   1176K  228K     24K/584K
   49157   4 proc/boot/fsevmgr             10r RECEIVE                   1176K  228K     24K/584K
             fsevmgr                       @246afdd000                  24K  8192
             ldqnx-64.so.2                 @313fd8b000                 224K   12K
             libfsnotify.so.1              @313fdc7000                  40K   12K
             libqh.so.1                    @313fdd5000                  68K  4096
             libslog2.so.1                 @313fde9000                  20K  4096
             libsecpol.so.1                @313fdf0000                  20K  4096
             libc.so.6                     @313fdf7000                 668K  8192
             libgcc_s.so.1                 @313feaa000                 112K  4096
             **heap**                      @1a1fd8e000 (       0)             92K
             **zero ELF**                  @313fdc6000 (       0)            4096
             **zero ELF**                  @313fdd1000 (       0)            4096
             **zero ELF**                  @313fde6000 (       0)            8192
             **zero ELF**                  @313fdee000 (       0)            4096
             **zero ELF**                  @313fdf5000 (       0)            4096
             **zero ELF**                  @313fe9e000 (       0)             16K
             **zero ELF**                  @313fea4000 (       0)             24K
             **zero ELF**                  @313fec6000 (       0)            4096
             /shmem/slogger2/fsevmgr.49157 @428025e000 (       0)             12K

2.4.1 求和验算

code总计:24 + 224 + 40 + 68 + 20 + 20 +  668 + 112 = 288 + 108 + 780 = 1176K ✓

data总计:228K ✓

    ELF对象:8 + 12 + 4 + 4 + 12 + 4 + 4 + 8 = 56K格式B部分:92 + 4*5 + 8 + 16 + 24 + 12 = 172K

stack总计:512 + 24x3 = 512 + 72 = 584K ✓

2.4.2 按地址排序分析

# 地址 对象 code data 类别 说明
1 0x01a1fd8e000 **heap** (0) 92K 簇①起
2 0x0246afdd000 fsevmgr 24K 8K 本体 新簇,孤立
3 0x0313fd8b000 ldqnx-64.so.2 224K 12K 簇③起
4 0x0313fdc6000 **zero ELF** (0) 4K bss ← ldqnx
5 0x0313fdc7000 libfsnotify.so.1 40K 12K 紧邻
6 0x0313fdd1000 **zero ELF** (0) 4K bss ← libfsnotify
7 0x0313fdd5000 libqh.so.1 68K 4K 间隔 12K(= 上条 data)
8 0x0313fde6000 **zero ELF** (0) 8K bss ← libqh
9 0x0313fde9000 libslog2.so.1 20K 4K 间隔 4K
10 0x0313fdee000 **zero ELF** (0) 4K bss ← libslog2
11 0x0313fdf0000 libsecpol.so.1 20K 4K 间隔 4K
12 0x0313fdf5000 **zero ELF** (0) 4K bss ← libsecpol
13 0x0313fdf7000 libc.so.6 668K 8K 间隔 4K
14 0x0313fe9e000 **zero ELF** (0) 16K bss ← libc ①
15 0x0313fea4000 **zero ELF** (0) 24K bss ← libc ②(中间夹 data 8K)
16 0x0313feaa000 libgcc_s.so.1 112K 4K 紧邻
17 0x0313fec6000 **zero ELF** (0) 4K bss ← libgcc
18 0x0428025e000 /shmem/slogger2/fsevmgr.49157 (0) 12K shmem 新簇,孤立

2.5 进程[53254]devb-eide分析

devb-eide 的全称是 ‌Device Block Enhanced IDE Driver‌,即增强型 IDE 块设备驱动。它负责管理 IDE/ATA 接口的硬盘和光驱等设备。‌‌

   53254   1 proc/boot/devb-eide           10r SIGWAITINFO               2084K   67M     64K/308K
   53254   2 proc/boot/devb-eide           21r RECEIVE                   2084K   67M     16K/308K
   53254   3 proc/boot/devb-eide          254i INTR                      2084K   67M       0/308K
   53254   4 proc/boot/devb-eide           21r RECEIVE                   2084K   67M     20K/308K
   53254   5 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     24K/308K
   53254   6 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     24K/308K
   53254   7 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
   53254   8 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
   53254   9 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
   53254  10 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
   53254  11 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
   53254  12 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
   53254  13 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
   53254  14 proc/boot/devb-eide           10r RECEIVE                   2084K   67M     20K/308K
             devb-eide                     @4ada4c5000                 116K   12K
             ldqnx-64.so.2                 @1226756000                 224K   12K
             libsecpol.so.1                @1226792000                  20K  4096
             libslog2.so.1                 @1226799000                  20K  4096
             libcam.so.2                   @12267a0000                  96K  4096
             libc.so.6                     @12267ba000                 668K  8192
             libgcc_s.so.1                 @122686d000                 112K  4096
             io-blk.so                     @122688b000                 288K   12K
             libfsnotify.so.1              @12268d8000                  40K   12K
             pci_bkwd_compat.so.3.0        @12268e6000                  16K  4096
             libpci.so.3.0                 @12268ec000                 136K   16K
             pci_slog2.so.3.0              @1226914000                 8192  4096
             pci_hw-Intel_x86.so.3.1       @1226918000                 104K  4096
             cam-disk.so                   @1226944000                  12K  4096
             fs-qnx6.so                    @1226949000                 224K  4096
             **zero ELF**                  @1226791000 (       0)            4096
             **zero ELF**                  @1226797000 (       0)            4096
             **zero ELF**                  @122679e000 (       0)            4096
             **zero ELF**                  @12267b8000 (       0)            4096
             **zero ELF**                  @1226861000 (       0)             16K
             **zero ELF**                  @1226867000 (       0)             24K
             **zero ELF**                  @1226889000 (       0)            4096
             **zero ELF**                  @12268d3000 (       0)            8192
             **zero ELF**                  @12268e2000 (       0)            4096
             **zero ELF**                  @12268ea000 (       0)            4096
             **zero ELF**                  @122690e000 (       0)            8192
             **zero ELF**                  @1226916000 (       0)            4096
             **zero ELF**                  @1226932000 (       0)            4096
             **zero ELF**                  @1226934000 (       0)             64K
             **zero ELF**                  @1226947000 (       0)            4096
             **zero ELF**                  @1226981000 (       0)            4096
             m/slogger2/devb_eide.53254..0 @2afa750000 (       0)             68K
             m/slogger2/devb_eide.53254..1 @2afa761000 (       0)             68K
             /dev/shmem/pci/pci_db         @2afa772000 (       0)             36K
             /dev/shmem/pci/pci_sync       @2afa77b000 (       0)            4096
             /dev/shmem/pci/pci_hw         @2afa77c000 (       0)            4096
             **anonymous**                 @2afa77d000 (       0)            4096
             sysram&below4G                @2afa77e000 (       0)            4096
             sysram&below4G                @2afa77f000 (       0)            4096
             **anonymous**                 @2afa780000 (       0)             64M
             sysram&below4G                @2afe790000 (       0)            4096
             **heap**                      @3072480000 (       0)             44K
             **heap**                      @307248b000 (       0)            4096
             **heap**                      @307248c000 (       0)           2616K
             **heap**                      @307271b000 (       0)            244K
             **heap**                      @3072759000 (       0)             92K
             **heap**                      @3072774000 (    3000)            204K

2.5.1 求和验算

code总计:116 + 224 + 40 + 96 + 668 + 112 + 288 + 56 + 136 + 8 + 104 + 236  = 2084K ✓

data总计:108 + 164 + 172 + 4 + 64M + 12 + 3204 = 3664K + 64M = 67.58M = 67M ✓

ELF对象:12x4 + 4x9 + 8 + 16 = 108K

格式B部分

zero ELF:4x11 + 16 + 24 + 8x2 + 64 = 164K

共享内存:68x2 + 36 + 4x2 = 172K

**anonymous**:4 + 64M

sysram&below4G:4x3 = 12K

heap:44 + 4 + 2616 + 244 + 92 + 204 = 3204K

注意这里pidin mem显示的data是M单位,应该是取整了,67M,手动累加的是67.58M

stack总计:64 + 16  + 20x9 + 24X2 = 80 + 180 + 48 = 308K ✓

2.5.2 格式B新增的两种数据

另外这里多了两种数据:

sysram&below4G

不是 shmem 也不是匿名 —— 是物理内存的直通映射(devb-eide 做 DMA 必须能访问 4G 以下的物理地址,驱动把物理页直接映射进自己的地址空间)。三条各 4K,两条紧贴 64M 块、一条孤立在 64K 之外。

anonymous

一次性预分配,全系统最大的单块进程内存。它和前面的 shmem、sysram 是零间隙紧邻的(第 38 条结束地址正好是它的基址)。

2.5.3 格式B括号中的非0值

注意到,之前的格式B的括号中都是0,这次这个heap中不是0

 **heap**                      @3072774000 (    3000)            204K

这种非0的在后面的proc/boot/devc-con进程中也存在,是在memory这条中:

  139272   1 proc/boot/devc-con            10r RECEIVE                   1116K  176K    512K/512K
  139272   2 proc/boot/devc-con           254i INTR                      1116K  176K       0/512K
             devc-con                      @1fef20b000                  92K  8192
             ldqnx-64.so.2                 @303a8e9000                 224K   12K
             libsecpol.so.1                @303a925000                  20K  4096
             libc.so.6                     @303a92c000                 668K  8192
             libgcc_s.so.1                 @303a9df000                 112K  4096
             **zero ELF**                  @1fef224000 (       0)            4096
             memory                        @27b7d45000 (       0)            4096
             memory                        @27b7d46000 (   b8000)             32K
             **zero ELF**                  @303a924000 (       0)            4096
             **zero ELF**                  @303a92a000 (       0)            4096
             **zero ELF**                  @303a9d3000 (       0)             16K
             **zero ELF**                  @303a9d9000 (       0)             24K
             **zero ELF**                  @303a9fb000 (       0)            4096
             **heap**                      @5bc2980000 (       0)             84K

2.5.4 按地址排序分析

# 地址 对象 code data 类别 说明
1 0x1226756000 ldqnx-64.so.2 224K 12K 簇①起
2 0x1226791000 **zero ELF** (0) 4K bss ← ldqnx
3 0x1226792000 libsecpol.so.1 20K 4K 紧邻
4 0x1226797000 **zero ELF** (0) 4K bss ← libsecpol
5 0x1226799000 libslog2.so.1 20K 4K 间隔 4K
6 0x122679e000 **zero ELF** (0) 4K bss ← libslog2
7 0x12267a0000 libcam.so.2 96K 4K 间隔 4K
8 0x12267b8000 **zero ELF** (0) 4K bss ← libcam
9 0x12267ba000 libc.so.6 668K 8K 间隔 4K
10 0x1226861000 **zero ELF** (0) 16K bss ← libc ①
11 0x1226867000 **zero ELF** (0) 24K bss ← libc ②
12 0x122686d000 libgcc_s.so.1 112K 4K 紧邻
13 0x1226889000 **zero ELF** (0) 4K bss ← libgcc
14 0x122688b000 io-blk.so 288K 12K 间隔 4K
15 0x12268d3000 **zero ELF** (0) 8K bss ← io-blk
16 0x12268d8000 libfsnotify.so.1 40K 12K 间隔 12K
17 0x12268e2000 **zero ELF** (0) 4K bss ← libfsnotify
18 0x12268e6000 pci_bkwd_compat.so.3.0 16K 4K 间隔 12K
19 0x12268ea000 **zero ELF** (0) 4K bss ← pci_bkwd_compat
20 0x12268ec000 libpci.so.3.0 136K 16K 间隔 4K
21 0x122690e000 **zero ELF** (0) 8K bss ← libpci
22 0x1226914000 pci_slog2.so.3.0 8K 4K 间隔 16K
23 0x1226916000 **zero ELF** (0) 4K bss ← pci_slog2
24 0x1226918000 pci_hw-Intel_x86.so.3.1 104K 4K 间隔 4K
25 0x1226932000 **zero ELF** (0) 4K bss ← pci_hw ①
26 0x1226934000 **zero ELF** (0) 64K bss ← pci_hw ②
27 0x1226944000 cam-disk.so 12K 4K 紧邻
28 0x1226947000 **zero ELF** (0) 4K bss ← cam-disk
29 0x1226949000 fs-qnx6.so 224K 4K 间隔 4K
30 0x1226981000 **zero ELF** (0) 4K bss ← fs-qnx6
31 0x2afa750000 /dev/shmem/slogger2/devb_eide.53254..0 (0) 68K shmem 簇②
32 0x2afa761000 /dev/shmem/slogger2/devb_eide.53254..1 (0) 68K shmem 紧邻
33 0x2afa772000 /dev/shmem/pci/pci_db (0) 36K shmem 紧邻
34 0x2afa77b000 /dev/shmem/pci/pci_sync (0) 4K shmem 紧邻
35 0x2afa77c000 /dev/shmem/pci/pci_hw (0) 4K shmem 紧邻
36 0x2afa77d000 **anonymous** (0) 4K anon 紧邻
37 0x2afa77e000 sysram&below4G (0) 4K 物理内存 紧邻
38 0x2afa77f000 sysram&below4G (0) 4K 物理内存 紧邻
39 0x2afa780000 **anonymous** (0) 64M anon 紧邻
40 0x2afe790000 sysram&below4G (0) 4K 物理内存 间隔 64K → 簇③
41 0x3072480000 **heap** (0) 44K 簇④
42 0x307248b000 **heap** (0) 4K 紧邻
43 0x307248c000 **heap** (0) 2616K 紧邻
44 0x307271b000 **heap** (0) 244K 间隔 4K → 簇⑤
45 0x3072759000 **heap** (0) 92K 间隔 4K
46 0x3072774000 **heap** (3000) 204K 间隔 16K
47 0x4ada4c5000 devb-eide 116K 12K 本体 簇⑥,孤立

后续的进程分析类似,本篇就不继续分析了。

3 总结

本篇介绍了QNX系统中pidin mem指令输出中进程数据的内存分析。

相关推荐

控制科学与工程硕士,日常分享单片机、嵌入式、C/C++、Linux等学习经验干货~