Valgrind给错了,但一切似乎都很好 [英] Valgrind giving error but everything seems fine

查看:400
本文介绍了Valgrind给错了,但一切似乎都很好的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎是我以前的帖子的副本,但不是.....

This one seems like a duplicate of my previous post but it is not.....

Valgrind出现以下错误:

Here Valgrind giving the following error:

 udit@udit-Dabba ~/mec $  valgrind --leak-check=full
 sendip -v -p ipv6 -f file.txt -6s ::1 -p esp -es 0x20 -eq 0x40
 -ei z30 -eI z100  -p tcp -ts 21 -td 21 ::2  

 ==4331== Memcheck, a memory error detector
 ==4331== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
 ==4331== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
 ==4331== Command: sendip -v -p ipv6 -f file.txt -6s ::1 -p esp -es 0x20
 -eq 0x40 -ei z30 -eI z100 -p tcp -ts 21 -td 21 ::2
==4331== 
esp
Added 43 options
Initializing module ipv6
Initializing module esp
Initializing module tcp
==4331== Invalid write of size 4
==4331==    at 0x4027EB8: memcpy (mc_replace_strmem.c:635)
==4331==    by 0x4032269: do_opt (esp.c:113)
==4331==    by 0x804A51D: main (sendip.c:575)
==4331==  Address 0x41ceab0 is 144 bytes inside a block of size 146 alloc'd
==4331==    at 0x402699A: realloc (vg_replace_malloc.c:525)
==4331==    by 0x4032231: do_opt (esp.c:111)
==4331==    by 0x804A51D: main (sendip.c:575)
==4331== 

valgrind: m_mallocfree.c:225 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.

==4331==    at 0x380282BD: report_and_quit (m_libcassert.c:193)
==4331==    by 0x38028415: vgPlain_assert_fail (m_libcassert.c:267)
==4331==    by 0x380351E7: vgPlain_arena_malloc (m_mallocfree.c:225)
==4331==    by 0x380662C7: vgPlain_cli_malloc (replacemalloc_core.c:83)
==4331==    by 0x38001FA8: vgMemCheck_new_block (mc_malloc_wrappers.c:201)
==4331==    by 0x38002196: vgMemCheck_malloc (mc_malloc_wrappers.c:238)
==4331==    by 0x38068BF8: vgPlain_scheduler (scheduler.c:1394)
==4331==    by 0x3807A354: run_a_thread_NORETURN (syswrap-linux.c:94)

sched status:
running_tid=1

Thread 1: status = VgTs_Runnable
==4331==    at 0x40268A4: malloc (vg_replace_malloc.c:236)
==4331==    by 0x4152415: gethostbyname2 (getXXbyYY.c:103)
==4331==    by 0x402CC68: set_addr (ipv6.c:33)
==4331==    by 0x804A642: main (sendip.c:594)


Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

esp.c (第113行)

  case 'eI':       /* ICV data (variable length) */
                   /* For right now, we will do either random generation
                   * or a user-provided string. We put it in the header,
                   * then move it into the trailer in finalize.
                   */
            length = stringargument(arg, &temp);
            priv->icvlen = length;
            pack->alloc_len += length;
            pack->data = realloc(esp, pack->alloc_len);
            esp = (esp_header *)pack->data;                                                                              
      113:      
            memcpy(&esp->tail.ivicv[priv->ivlen],temp, priv->icvlen);
            pack->modified |= ESP_MOD_ICV;

这些是我想可能有助于调试的相应头文件...

These are the respective header files which I suppose may help in debugging ......

ip6.h

/*
 * authentication header
*/
struct ip_auth_hdr {
    u_int8_t  nexthdr;
    u_int8_t  hdrlen;       /* This one is measured in 32 bit units! */
    u_int16_t reserved;
    u_int32_t spi;
    u_int32_t seq_no;       /* Sequence number */
    u_int8_t  auth_data[0]; /* Variable len but >=4. Mind the
                               64 bit alignment! */
 #define icv     auth_data       /* rfc 4302 name */
    /* TBD - high-order sequence number */

 };

/*
 * encapsulated security payload header
 */
 struct ip_esp_hdr {
    u_int32_t spi;
    u_int32_t seq_no;       /* Sequence number */
    u_int8_t  enc_data[0];  /* Variable len but >=8. Mind the
                             64 bit alignment! */
  };

esp.h

 struct ip_esp_tail {
    u_int8_t padlen;        /* padding is pushed before tail */
    u_int8_t nexthdr;
    u_int32_t ivicv[0];     /* both IV and ICV, if any */
 };

 struct ip_esp_headtail {
    struct ip_esp_hdr hdr;
    struct ip_esp_tail tail;
  };

  typedef struct ip_esp_headtail esp_header;

  #define ESP_MIN_PADDING 4 

  typedef struct ip_esp_private { /* keep track of things privately */
    u_int32_t type;         /* type = IPPROTO_ESP */
    u_int32_t ivlen;        /* length of IV portion */
    u_int32_t icvlen;       /* length of ICV portion */
    u_int32_t keylen;       /* length of "key" (not transmitted data) */
    u_int32_t key[0];       /* key itself */
  } esp_private;

  struct ip_auth_hdr {
    u_int8_t  nexthdr;
    u_int8_t  hdrlen;       /* This one is measured in 32 bit units! */
    u_int16_t reserved;
    u_int32_t spi;
    u_int32_t seq_no;       /* Sequence number */
    u_int8_t  auth_data[0]; /* Variable len but >=4. Mind the
                               64 bit alignment! */
  #define icv     auth_data       /* rfc 4302 name */
    /* TBD - high-order sequence number */

  };

 /*
  * encapsulated security payload header
  */
  struct ip_esp_hdr {
    u_int32_t spi;
    u_int32_t seq_no;       /* Sequence number */
    u_int8_t  enc_data[0];  /* Variable len but >=8. Mind the
                            64 bit alignment! */  
  };

如果有人知道泄漏在哪里发生?以及如何打补丁?

If anyone getting any clue where is the leakage going on ??? and how to patch it ??

推荐答案

正如克里斯所说,valgrind告诉您程序正在尝试写入分配的区域之外的内存:

As Chris said valgrind tells you that you program is trying to write to memory that is outside of the allocated region:

Invalid write of size 4
   at 0x4027EB8: memcpy (mc_replace_strmem.c:635)
   by 0x4032269: do_opt (esp.c:113)
   by 0x804A51D: main (sendip.c:575)
 Address 0x41ceab0 is 144 bytes inside a block of size 146 alloc'd
   at 0x402699A: realloc (vg_replace_malloc.c:525)
   by 0x4032231: do_opt (esp.c:111)
   by 0x804A51D: main (sendip.c:575)

它告诉您在do_opt(在esp.c文件的第111行)中,您调用realloc分配了146个字节的内存,现在函数memcpy正在尝试从4个字节开始从144个字节开始写入该存储块的开始,这将导致在分配的区域之外写入(144 + 4> 146).它还告诉您,memcpy是从do_opt函数调用的.

It tells you that in do_opt (in the file esp.c at line 111) you have called realloc to allocate 146 bytes of memory and now the function memcpy is trying to do a 4-byte write starting at 144 bytes from the start of that memory block, which will cause a write outside of the allocated region (144 + 4 > 146). It also tells you that memcpy was called from the do_opt function.

因此,要么分配给很少的内存,要么在复制到内存时使用了错误的偏移量.因此,下一步就是检查valgrind报告的位置中的代码.

So either you are allocating to little memory or you are using wrong offset when copying to the memory. So next step would be to inspect the code in the locations reported by valgrind.

但是如果在查看代码时问题不明显该怎么办?

But what to do if the problem isn't obvious when looking at the code?

一种选择是使用valgrind的--db-attach option,它允许您输入gdb.这样一来,您就可以环顾四周,并检查一下weather pack-> alloc_len是您期望的值,如果&esp->tail.ivicv[priv->ivlen]指向宫殿,则可以将其与pack-> data进行比较. (这也可以通过添加printf来打印这些值的经典方法来完成).

One option is to use valgrind's --db-attach option, which allows you to enter gdb. That will allow you to look around and check things like weather pack->alloc_len is the value you expect, and if &esp->tail.ivicv[priv->ivlen] points to the palace you expect it to compared to pack->data. (this could also be done the classic way by adding printf printing those values).

以下是我的猜测是什么问题,但如果您想先自己弄清楚问题,就隐藏起来了:

Below is my guess what the problem is, but hidden if you want to try to figure it out yourself first:

也许您忘记了ivicv是一个uint32,而您以字节为单位测量了priv-> ivlen.在这种情况下,将其更改为&esp->tail.ivicv[priv->ivlen / sizeof(u_int32_t)]会有所帮助

这篇关于Valgrind给错了,但一切似乎都很好的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆