linux雙向鍊錶分析之list del中的技巧

2021-06-04 12:08:46 字數 1585 閱讀 4798

原文出處z2007b

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)

集中體現在 

entry->next = list_poison1;

entry->prev = list_poison2;

這兩行**。

為什麼不寫成:

entry->next = 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)

這個地方有對這兩個巨集的引用。這個函式的警告資訊告訴我們這個節點已經被用過了,很顯然,我們將其與平常意義的節點作比較可以得到如下資訊:我們得到的這個鍊錶是被刪掉的,不是剛初始化沒用的。另外我大膽猜測了一下其另乙個用途:就算我們不開啟config_debug_list這個巨集,我們在除錯出錯**的時候經常會返回指標的值,我們很多時候出錯都是指標為null造成的,這時候我們如果發現是值是list_poison1或list_poison2的話,那我們馬上可以將注意力轉移到鍊錶上來了,並且是因為誤用了乙個已經從鍊錶中刪除掉的節點。

linux雙向鍊錶分析之list del中的技巧

linux核心的雙向鍊錶是比較經典的東西,網上分析鍊錶的同志基本分析了99 就差了1 那就是list del函式。先給出函式原型 ifdef config illegal pointer value define poison pointer delta ac config illegal poin...

鍊錶之雙向鍊錶

首先在說下單鏈表,才能和雙鏈表作比較 單鏈表 單向鍊錶 由兩部分組成 資料域 data 和結點域 node 單鏈表就像是一條打了很多結的繩子,每乙個繩結相當於乙個結點,每個節結點間都有繩子連線,這樣原理的實現是通過node結點區的頭指標head實現的,每個結點都有乙個指標,每個節點指標的指向都是指向...

RT Thread 雙向鍊錶分析

從鍊錶刪除節點函式 rt list remove 鍊錶節點元素訪問 雙向鍊錶也叫雙鏈表,是鍊錶的一種,是在作業系統中常用的資料結構,它的每個資料結點中都有兩個指標,分別指向直接後繼和直接前驅,其頭指標 head 是唯一確定的。所以,從雙向鍊錶中的任意乙個結點開始,都可以很方便地訪問它的前驅結點和後繼...