2013-01-14 53 views
0

我寫Linux內核模塊,並有一些問題: 我模塊落在點在點檢查這些指針值空指針引用錯誤,而指針不是空最近

static struct area_control { 
    struct list_head head; 
    unsigned long addr; 
    unsigned long jiffies; 
    struct area_part *part; 
} *const_areas = NULL, *var_areas = NULL; 

static struct area_control *Find_Area(unsigned long addr, struct area_control *first_area) 
{ 
    if (first_area) 
    { 
     struct area_control *cur_area = first_area; 
     while (1) 
     { 
      if (!cur_area) return NULL; 
      if (cur_area->addr == addr) 
      { 
       cur_area->jiffies = jiffies; 
       return cur_area; 
      } 
      cur_area = list_entry(cur_area->head.next, struct area_control, head); 
      if (cur_area == first_area) return NULL; 
     } 
    } 
    return NULL; 
} 

cur_area->head.next 模塊下降,因爲cur_area是NULL! - 我從呼叫跟蹤和反彙編中得到這個事實。模塊爲Linux 2.6.34 x86_64的多處理器架構

+0

你在說什麼? –

+0

你作爲list_entry的第二個參數傳遞了什麼? – Dariusz

+1

你的第三個參數也沒有意義,因爲它沒有在我看到的任何地方聲明... – Jason

回答

0
 cur_area = list_entry(cur_area->head.next, struct area_control, head); 

您需要檢查是否cur_area->head.nextNULL爲好。

使用宏定義:

#define list_entry(ptr, type, member) \ 
((type *)((char *)(ptr) – (unsigned long)(&((type *)0)->member))) 

代碼將被擴展爲:

 cur_area = ((struct area_control *)((char *)(cur_area->head.next) - (unsigned long(&((struct area_control *)0)->head))) 

正如你所看到的,這個代碼將如果cur_area->head.next爲空失敗。

+0

如果元素是在linux雙鏈表中,那麼不能存在空值字段'prev'和'next'以正確的方式初始化。你也可以看到反彙編代碼'mov rax,[rbp + cur_area];這些宏定義的'list_entry'的mov rax,[rax]' - 這些代碼運行良好ethen雖然walue cur_area-> head.next'爲NULL –

+0

在我看來(根據您的問題中的信息) cur_area-> head.next'是'NULL'。它如何變成'NULL'我不能說。可能是其餘代碼中某處的錯誤。我將在調試器中更改時設置一個斷點。 –

+0

'cur_area-> head.next'可以在這些行上有任何值,而不會造成致命後果。 Bug'空指針解除引用'說''cur_area'(不是你所說的cur_area-> head.hext)是NULL。呼叫跟蹤也是這樣說的:%rax = 0x0000在錯誤點 –