内存如何诊断SLUB问题

我们介绍了在RHEL6及较早的kernel上诊断slab泄漏问题的两种方法,可以说相当麻烦了,这是因为以前的slab没有提供原生的故障诊断机制。Linux kernel自2.6.23之后采用的Slub自带了故障诊断机制,就方便很多,然而习惯上仍然把slub称作slab。如何判断你的系统kernel是否在用slub呢?仅从kernel版本号是看不准的,比如RHEL6的kernel版本2.6.x仍然在使用slab,从RHEL7才开始采用Slub。有一个简单的判断方法,就是看是否存在/sys/kernel/slab目录,有就是slub,没有就是slab。

Slub的debug机制

了解slub的debug机制之前,先要弄清楚可能会出现哪些问题,无论是slab还是slub,问题无非是以下几类:

Slub提供了red zone和poisoning等debug机制来检测以上问题。

(图)SLUB对象的格式
* 绿色的 Payload表示分配出去的 slub object;
* slub debug机制需要占用额外的内存,比如 Red zone,还有,为了追溯 slub object的分配和释放过程,需要额外的空间来存放 stack trace,即图中的 Tracking/Debugging;
* 图中的 FP是 Free Pointer的缩写,处于 free状态的 object是以链表的形式串在一起的,FP就是链表指针。

怎样开启slub debug

Slub本身包含了完整的debug功能,缺省是关闭的,需要的时候打开就行了。

开启slub debug有两种方式:

  1. 【启动时开启】
    在kernel command line中加入以下参数:
    slub_debug=,
    它会在重启时生效。
    注:
    slub_debug后面不跟任何参数表示打开所有的debug功能;
    slub_debug= 对所有的slab打开指定的debug options;
    slub_debug=, 对指定的slab打开指定的debug options;
    slub_debug=, 对指定的slab打开所有的debug options。
  2. 【运行中开启】
    在运行系统上可以通过以下文件对指定的slab打开指定的debug option:
    /sys/kernel/slab//

Debug options如下:

debug option

sysfs debug file

功能

F

sanity_checks

激活完整性检查功能,在特定的环节比如free的时候增加各种条件判断,验证数据是否完好。

Z

red_zone

用于检测overrun。通过在slub object后面插入一块额外的红色区域(橄榄球术语),一旦进入就表示有错。

P

poison

用于检测use-after-free和use-uninitialised。给slub对象填充特征字符,比如在分配时填充0x5a,在释放时填充0x6b,根据特征字符是否被覆盖来检测是否出错。更多的poison字节定义参见: /lib/modules/$(uname -r)/build/include/linux/poison.h

U

store_user

在slub object后面添加一块额外的空间,记录调用alloc/free的stack trace

T

trace

在slub object alloc/free时,向系统日志中输出相关信息,包括stack trace

开启debug option会降低系统性能,所以尽量只开启必要的选项。

在kernel commandline中开启slub debug与在运行系统上开启是有区别的。有些debug option不能在运行系统上开启,比如red_zone、store_user需要额外的存储空间来保存debug信息,如果不是从一开始就开启,那么以前分配出去的slub对象就没有debug数据区,会导致对齐问题,而且debug代码也很难分辨新老slub对象;再比如poison,如果不是从一开始就开启,那么以前分配出去的slub对象就没有填充特征字符,debug代码也辨别不了哪些slub对象是有填充的、哪些是没有填充的。所以,在运行系统上开启slub debug,如果指定的slab里面已经有了object,那么只能动态开启sanity_checks和trace,惟有当指定的slab还是空的,其它的debug option才可以动态开启。我们实际使用的时候,尽管去试好了,如果某个debug option不允许动态开启,命令就不会成功,比如:

1

2

# echo "1" > /sys/kernel/slab/task_struct/red_zone

-bash: echo: write error: Device or resource busy

要进行slub debug,有一个重要特性不可不知,那就是slab merging。

Slab merging

很多slab的大小和参数是相似的,slub会把这些不同的slab合并到一起,好处是可以减少内存碎片,提高内存使用效率,这个称为slab merging(合并)。

怎么知道一个slab有没有发生合并呢?通过查看以下文件:
/sys/kernel/slab//aliases
aliases表示参与合并的slab的数量(自己除外),如果大于0就意味着发生了合并。

slabinfo工具(见下一节的介绍)可以具体列出哪些slab合并到了一起:

1

2

3

4

5

6

7

8

# slabinfo -a

:t-0000024 <- xfs_bmap_free_item fstrm_item scsi_data_buffer avtab_node fsnotify_event_holder

:t-0000032 <- pte_list_desc xfs_log_item_desc dnotify_struct kmalloc-32 sd_ext_cdb xfs_mru_cache_elem inotify_event_private_data fanotify_response_event

:t-0000040 <- khugepaged_mm_slot Acpi-Namespace dm_io

:t-0000048 <- nsproxy ftrace_event_field ip_fib_alias Acpi-Parse shared_policy_node ksm_stable_node ksm_mm_slot fasync_cache

:t-0000056 <- ip_fib_trie uhci_urb_priv

...

Slab merging会干扰debug,因为不同的slab合并到了一起,出了问题以后很难分辨是哪一个slab导致的。关闭slab merging的方法有两个:

slabinfo工具

随内核源程序提供了一个slabinfo工具,但是需要自己手工编译。源程序的位置是在源代码树下的 tools/vm/slabinfo.c,编译方法是:
$ gcc -o slabinfo tools/vm/slabinfo.c
或者进入 tools/vm 目录下直接执行make:
$ make slabinfo

slabinfo工具能做的事情见它的帮助信息:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

# slabinfo -h

slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.

slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]

-a|--aliases Show aliases

-A|--activity Most active slabs first

-d|--debug= Set/Clear Debug options

-D|--display-active Switch line format to activity

-e|--empty Show empty slabs

-f|--first-alias Show first alias

-h|--help Show usage information

-i|--inverted Inverted list

-l|--slabs Show slabs

-n|--numa Show NUMA information

-o|--ops Show kmem_cache_ops

-s|--shrink Shrink slabs

-r|--report Detailed report on single slabs

-S|--Size Sort by size

-t|--tracking Show alloc/free information

-T|--Totals Show summary information

-v|--validate Validate slabs

-z|--zero Include empty slabs

-1|--1ref Single reference

Valid debug options (FZPUT may be combined)

a / A Switch on all debug options (=FZUP)

- Switch off all debug options

f / F Sanity Checks (SLAB_DEBUG_FREE)

z / Z Redzoning

p / P Poisoning

u / U Tracking

t / T Tracing

参考资料:

https://www.kernel.org/doc/Documentation/vm/slub.txt
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-kernel-slab
https://lwn.net/Articles/340267/
https://gitlab.eurecom.fr/oai/odroid-linux-3.10.y-rt/commit/4c13dd3b48fcb6fbe44f241eb11a057ecd1cba75
一个实例分析

展开阅读全文

页面更新:2024-05-22

标签:内存   字符   特征   分配   对象   机制   区域   代码   工具   系统

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top