linux双向链表分析之list_del中的技巧
来源:互联网 发布:大数据分析道与术 编辑:程序博客网 时间:2024/06/07 09:09
原文出处z2007b http://blog.csdn.net/z2007b/article/details/6370383。
linux内核的双向链表是比较经典的东西,网上分析链表的同志基本分析了99%,就差了1%。那就是list_del函数。
先给出函数原型:#ifdef CONFIG_ILLEGAL_POINTER_VALUE
# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL)
#else
# define POISON_POINTER_DELTA 0
#endif
#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)
#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
集中体现在
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
这两行代码。
为什么不写成:
entry->next = NULL;
entry->prev = NULL;
我们先看一下相关的注释:/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
翻译一下:
在正常环境下,这个非空指针将会引起页错误(通常所说的缺页中断)。可被用来验证没有初始化的链表节点。
首先,我们可以内核中找到一下函数:
这个函数是需要在打开了CONFIG_DEBUG_LIST这个宏后才起作用。很明显这个宏是用于链表调试的。
/** * list_del - deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty on entry does not return true after this, the entry is * in an undefined state. */void list_del(struct list_head *entry){WARN(entry->next == LIST_POISON1,"list_del corruption, next is LIST_POISON1 (%p)\n",LIST_POISON1);WARN(entry->next != LIST_POISON1 && entry->prev == LIST_POISON2,"list_del corruption, prev is LIST_POISON2 (%p)\n",LIST_POISON2);WARN(entry->prev->next != entry,"list_del corruption. prev->next should be %p, ""but was %p\n", entry, entry->prev->next);WARN(entry->next->prev != entry,"list_del corruption. next->prev should be %p, ""but was %p\n", entry, entry->next->prev);__list_del(entry->prev, entry->next);entry->next = LIST_POISON1;entry->prev = LIST_POISON2;}这个地方有对这两个宏的引用。这个函数的警告信息告诉我们这个节点已经被用过了,很显然,我们将其与平常意义的节点作比较可以得到如下信息:我们得到的这个链表是被删掉的,不是刚初始化没用的。另外我大胆猜测了一下其另一个用途:就算我们不打开CONFIG_DEBUG_LIST这个宏,我们在调试出错代码的时候经常会返回指针的值,我们很多时候出错都是指针为NULL造成的,这时候我们如果发现是值是LIST_POISON1或LIST_POISON2的话,那我们马上可以将注意力转移到链表上来了,并且是因为误用了一个已经从链表中删除掉的节点。
- linux双向链表分析之list_del中的技巧
- linux双向链表分析之list_del中的技巧
- linux双向链表分析之list_del中的技巧
- list_del 分析
- linux 内核分析之list_head 双向链表结构
- list_del 分析2
- Linux内核双向循环链表分析
- linux双向链表List结构分析
- list_del()
- list_del()
- 看linux中的双向链表
- Linux中的双向循环链表
- Linux中的双向循环链表
- 双向链表分析
- Linux内核-双向循环链表代码分析
- 双向循环链表设计分析之二
- 双向循环链表分析设计之三
- 双向循环链表设计分析之四
- 九选三不及格,心情沉痛ing
- Linux设备驱动开发学习步骤
- * java版HashMap,大数据量时效率很低,建议1000条数据以下使用
- git使用总结
- 网管工具之cacti
- linux双向链表分析之list_del中的技巧
- Flex命名空间解说
- C#设计模式之17——迭代器模式
- MySQL 修改AUTO_INCREMENT的值
- 用 MDX 创建时间命名集总结 SSAS
- NIO应用
- 有关使用 GPS Intermediate Driver 无法获取到GPS数据的一个问题
- cassandra学习笔记一
- db2命令行远程连接数据库