数据结构
kmemleak_object
struct kmemleak_object描述一段通过memblock_alloc、kmalloc、vmalloc、kmem_cache_alloc等函数分配的内存块。此内存块会加入到红黑树object_tree_root和双向链表object_list中。
//Kmemleak.c
/* search tree for object boundaries */
static struct rb_root object_tree_root = RB_ROOT;
//Kmemleak.c
struct kmemleak_object {
spinlock_t lock;
unsigned long flags; /* object status flags */
struct list_head object_list;
struct list_head gray_list;
struct rb_node rb_node;
struct rcu_head rcu; /* object_list lockless traversal */
/* object usage count; object freed when use_count == 0 */
atomic_t use_count;
unsigned long pointer;
size_t size;
/* minimum number of a pointers found before it is considered leak */
int min_count;
/* the total number of pointers found pointing to this object */
int count;
/* checksum for detecting modified objects */
u32 checksum;
/* memory ranges to be scanned inside an object (empty for all) */
struct hlist_head area_list;
unsigned long trace[MAX_TRACE];
unsigned int trace_len;
unsigned long jiffies; /* creation timestamp */
pid_t pid; /* pid of the current task */
char comm[TASK_COMM_LEN]; /* executable name */
};
lock:spinlock锁用于保护当前的object对象。
flags:object的状态标志位。有以下状态标志位:
- OBJECT_ALLOCATED:表示已经分配的内存块的状态标志。在创建object的时候,会置上此标记,在释放object的时候,清除此标记。
- OBJECT_REPORTED:表示经过一轮内存扫描之后,把有内存泄漏风险的object的flags置上OBJECT_REPORTED,然后用户可以通过cat /sys/kernel/debug/kmemleak获取有内存泄漏风险的object。
- OBJECT_NO_SCAN:表示不去扫描此内存块。kmemleak为了减少误报和漏报,通过封装好的接口设置内存块是否需要扫描,如果不需要扫描则flags置上OBJECT_NO_SCAN标志。
- OBJECT_FULL_SCAN:表示当内存不足分配scan_area失败的时候,把当前的object标记为OBJECT_FULL_SCAN,表示此objcet全部扫描,不再是局部扫描
object_list:通过该字段把objec添加到object_list链表中。
gray_list:通过该字段把object添加到gray_list链表中。
rb_node:通过该字段把object添加到object_tree_root的红黑树中。
扫描二维码关注公众号,回复: 15716818 查看本文章use_count:object使用计数。通过get_object增加计数,put_object减少计数,当use_count = 0时释放该object。
pointer:object的起始地址。
size:object的大小。
excess_ref:具体见kmemleak_vmalloc函数实现。
min_count:指向内存块的最少指针个数。如果小于该值,说明有内存泄漏的嫌疑。
count:扫描到的指向内存块的指针总数,和min_count配合使用。
checksum:内存块的CRC校验和。
area_list:如果area_list链表为NULL,则以object的pointer为起始地址和size为大小的地址范围扫描。如果不为NULL,以area_list链表中的kmemleak_scan_area节点的start和size为地址范围扫描。一个object描述的内存块可能被分割为多个kmemleak_scan_area区域,所有的kmemleak_scan_area通过node节点添加到area_list为头的链表中。
trace:保存创建object的stack trace的地址。
trace_len:表示stack trace的实际深度,最大深度为MAX_TRACE(16)。
jiffies:创建object时的jiffies。
pid:表示创建objcet的pid号。
comm:创建object的进程名。