处理内存时出错 - mremap_chunk:断言

时间:2011-10-24 13:22:53

标签: c memory-management memcpy memmove

这似乎是我以前的帖子,但这里的问题是不同的..

这是问题的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,在第二个位置将其更改为priv->keylen+priv->akeylen

但还有一些事情需要改进

为什么要覆盖???

2 个答案:

答案 0 :(得分:1)

由于key [0] struct hack似乎包含两个键的空间,因此您还需要为两者分配内存。在这两种情况下('k'和'K')

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

连接这两个键时,最简单的方法是将u_int32_t键转换为字符指针并对其进行算术运算:

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

[和memmove()相似] 你的程序中的其余演员阵容都可以删除。

答案 1 :(得分:0)

如果 malloc内的导致断言失败,则问题出在外面。断言不是关于传递给malloc的参数,而是关于内存的状态,它已被破坏。这意味着您之前写过了一个您不应该写的内存区域。因此,即使您提供了正确的回溯(例如使用gdb),这也不会指向问题的根源。有许多工具可用于调试内存问题。 valgrind是最广泛使用的工具之一。这将使您的程序非常缓慢,并通过查看每个单独的内存访问显示大量可能的问题。另一个更轻量级的工具是mudflap,它将与之相关联。缩小问题的一个非常基本的方法是在代码中添加assert(condition)语句,并希望您提前失败。有时你可以通过查看代码中的每一个内存访问来解决这个问题,并确保它不会超出范围(或者你不确定,添加一个断言语句)。