核心鍊錶使用 刪除鍊錶節點

2021-06-05 10:18:05 字數 2752 閱讀 4119

當我們使用遍歷的方法來刪除鍊錶時:

list_for_each(pos, &student_list)

list_for_each(pos, head)這個巨集定義是用來遍歷鍊錶的,通過其第乙個引數pos來刪除鍊錶節點,但是,執行後就會出現以下錯誤:

unable to handle kernel paging request at virtual address 00100100

pgd = c3aa8000

[00100100] *pgd=33a82031, *pte=00000000, *ppte=00000000

internal error: oops: 17 [#1]

last sysfs file: /sys/devices/virtual/vc/vcsa4/dev

modules linked in: mylist(-) [last unloaded: mylist]

cpu: 0 not tainted (2.6.32.2 #1)

pc is at cleanup_module+0x48/0x64 [mylist]

lr is at sys_delete_module+0x1e8/0x25c

pc : lr : psr: 00000013

sp : c3a99f40 ip : bf0122e0 fp : 00000000

r10: be825e88 r9 : c3a98000 r8 : c002e024

r7 : c3a99f44 r6 : 00000880 r5 : bf01219c r4 : 00000000

r3 : bf0122e4 r2 : bf0122e4 r1 : 00100100 r0 : c3a480d8

flags: nzcv irqs on fiqs on mode svc_32 isa arm segment user

control: c000717f table: 33aa8000 dac: 00000015

process rmmod (pid: 849, stack limit = 0xc3a98270)

stack: (0xc3a99f40 to 0xc3a9a000)

9f40: c3ab8c80 696c796d 00007473 00000000 00000000 c35d8828 00000062 c0091bf8

9f60: 00000000 00000000 00000000 c3ab8c80 00000000 c3a9a6c0 c3ab8c80 00000000

9f80: bf01219c 00000880 c3a99f8c 00000000 c3ab8c80 be825f63 00000001 00000000

9fa0: 00000081 c002dea0 be825f63 00000001 be825f63 00000880 4022a024 00000001

9fc0: be825f63 00000001 00000000 00000081 00000001 00000000 be825e88 00000000

9fe0: 00000000 be825b10 00018250 401c886c 60000010 be825f63 00000000 00000000

(cleanup_module+0x48/0x64 [mylist]) from (sys_delete_module+0x1e8/0x25c)

(sys_delete_module+0x1e8/0x25c) from (ret_fast_syscall+0x0/0x28)

code: e59fc018 e1a0300c e4931004 e1510003 (e5910000)

---[ end trace 2e1cdf07b6db8d2d ]---

segmentation fault

原因在於使用list_for_each(pos, head)來遍歷整個鍊錶時,依賴於pos->next,從他的**實現就可以看出來:

/*include/linux/list.h*/

#define list_for_each(pos, head) /

for (pos = (head)->next; prefetch(pos->next), pos != (head); /

pos = pos->next)

而刪除節點函式

list_del(pos);

會把pos的後向鍊錶post->next指向另外乙個位址,見函式原型:

/*include/linux/list.h*/

static inline void list_del(struct list_head *entry)

/*include/linux/poison.h*/

#define list_poison1 ((void *) 0x00100100)

而這個位址正好是出錯資訊提示的位址0x00100100。

正確的做法其實應該使用另外乙個遍歷巨集定義:

/*include/linux/list.h*/

#define list_for_each_safe(pos, n, head) /

for (pos = (head)->next, n = pos->next; pos != (head); /

pos = n, n = pos->next)

這裡用n做了pos的備份,當處理完for迴圈裡的事情後,又把n的值重新賦回給pos,確保pos結構裡的值不被改變。

jjdeng@scut

[email protected]

2011.01.19

該貼**於

核心鍊錶使用 刪除鍊錶節點

核心鍊錶使用 刪除鍊錶節點 當我們使用遍歷的方法來刪除鍊錶時 list for each pos,student list list for each pos,head 這個巨集定義是用來遍歷鍊錶的,通過其第乙個引數pos來刪除鍊錶節點,但是,執行後就會出現以下錯誤 unable to handle...

核心鍊錶使用 刪除鍊錶節點

核心鍊錶使用 刪除鍊錶節點 當我們使用遍歷的方法來刪除鍊錶時 list for each pos,student list list for each pos,head 這個巨集定義是用來遍歷鍊錶的,通過其第乙個引數pos來刪除鍊錶節點,但是,執行後就會出現以下錯誤 unable to handle...

鍊錶 刪除鍊錶的節點

劍指offer的乙個題,題目是要求在最少的時間內刪除鍊錶的節點。問題分析 對於鍊錶的刪除,按照劍指offer的一貫思路就是展開討論 1 空鍊錶咋辦 待刪除的節點是空節點咋辦 2 要刪除的節點在鍊錶中的位置有三種情況 1 鍊錶只有乙個節點,待刪除節點是表頭又是尾節點 2 鍊錶有多個節點,待刪除的節點是...