2011-10-24 101 views
1

好像我以前的帖子,但問題是這裏不同..錯誤 - mremap_chunk:斷言

這是問題的C結構 -

typedef struct ip_esp_private {   /* keep track of things privately */ 
u_int32_t type;   
u_int32_t ivlen;  
u_int32_t icvlen;  
u_int32_t keylen;  /* length of "Encryption key */ 
u_int32_t akeylen;  /*length of authn key */ 
u_int32_t key[0];  /* encryption key and authentication key both */ 

} esp_private; 

的值被提供給結構在運行時的內容如下 -

case 'k':  /* Key */ 
      length = stringargument(arg, &temp); 
      priv->keylen = length; 


      priv = (esp_private *)realloc(priv, 
          sizeof(esp_private)+/*length*/priv->keylen); 
      /*This one is edited */ 


     // if(priv->akeylen)  
      //  memmove(&priv->key[priv->keylen], 
       //     &priv->key[0],priv->akeylen); 
    /*These three are commented*/  

     memcpy(&priv->key[0], temp, priv->keylen); 
      pack->private = priv; 
      pack->modified |= ESP_MOD_KEY; 
      break; 



    case 'K':  /* Authentication Key */ 
      length = stringargument(arg, &temp); 
      priv->akeylen = length; // marked line(explained below) 

      priv = (esp_private *)realloc(priv, 
          sizeof(esp_private)+/*length*/priv->keylen+priv->akeylen); 
      /*this one edited too */ 


      memcpy(&priv->key[priv->keylen/sizeof(u_int32_t)], 
              temp,priv->akeylen); 
      pack->private = priv; 
      pack->modified |= ESP_MOD_KEY; 

現在有一個函數使用認證密鑰的值。

功能的相關部分是 -

if (!epriv->akeylen) { 
      key = &fakekey; 
      keylen = 1; 
    } else { 
      key = (u_int8_t *)malloc(epriv->akeylen); 
      memcpy(key,&epriv->key[epriv->keylen/sizeof(u_int32_t)] 
          ,epriv->akeylen); 

現在,當我試圖運行下面的程序,收到此錯誤,對此,我也沒辦法。

 sendip: malloc.c:3574: mremap_chunk: Assertion `((size + offset) 
            & (mp_.pagesize-1)) == 0' failed. 

我認爲可能存在功能部件一個錯誤,但它到底是什麼我不知道, 因爲當我評論標線(上述)的akeylen爲空 所以服用該fakekey值程序運行良好。

編輯1:

我在三個地方(也編輯在上面的代碼)編輯的代碼。

現在程序工作,但發生不一致的輸出。

輸入:

Encryption key - qwerty 

Authentication key - abcdef 

輸出:

Encryption key - qwerab 

    Authentication key - abcdef 

現在的情況更清晰。

這意味着問題肯定在realloc聲明。

請對此建議。

最初我在realloc聲明處增加了長度,但是現在我在第一位將其更改爲priv->keylen,在第二位將其更改爲。

但是還有一些東西需要改進

爲什麼這是覆蓋?

+0

這是純粹的推測,但是你知道'stringargument(arg,&temp)'的計算結果嗎?看起來你的'realloc'調用正被提升爲'mmap'調用(或'mremap'),當你請求分配一個很大的大小時會發生這種情況。如果碰巧你的'stringargument'函數正在返回一些太大的垃圾值,可能會發生有趣的事情。 –

+0

請看看我的編輯 –

+0

好的,我看到你的編輯。但是你需要澄清你現在看到的。你看到相同的斷言失敗?或者你沒有看到斷言,但現在你覆蓋了一些內存?或者你看到過嗎? –

回答

1

由於key [0] struct hack似乎包含兩個鍵的空間,所以您也需要爲這兩個鍵分配內存。在這兩種情況下(「K」和「K」)

priv = realloc(priv, sizeof *priv +priv->keylen+priv->akeylen); 

當串聯的兩個鍵,它是最容易投的u_int32_t鑰匙插入字符指針,做arithmatic上一個:

memcpy (priv->key, source1, sizeofsource1); 
/* and */ 
memcpy (((char*) priv->key) +priv->keylen, source2, sizeofsource2); 

[和類似的memmove()] 您的程序中的其他演員可以刪除。

+0

Thanx很多....我整天都在尋找它。 –

0

如果您從得到斷言失敗malloc,問題就在外面。斷言不是關於傳遞給malloc的參數,而是關於內存狀態,這是損壞的。這意味着你以前寫了一個你不應該寫的內存區域。因此,即使您提供了適當的回溯(例如使用gdb),這也不會指出問題的根源。有許多用於調試內存問題的工具。 valgrind是最廣泛使用的工具之一。它會讓你的程序非常慢,並通過查看每一個內存訪問來顯示你可能遇到的問題。另一個更輕量級的工具是擋泥板,它將與之相連。縮小問題的一個非常基本的方法是將assert(condition)語句添加到您的代碼中,並希望您早點失敗。有時你可以通過查看代碼中的每個內存訪問來解決這個問題,並確保它不超出界限(或者如果您不確定,請添加一個斷言語句)。

+0

請看看我的編輯 –