3

valgrind一天前我才开始使用SO 本身的某人所建议的。它是一个了不起的工具,但今天我遇到了问题。它给出了以下错误:definitely lost bytes但无法判断错误的位置。

这是输出valgrind

 udit@udit-Dabba ~ $  valgrind --leak-check=full  sendip -v -p ipv6 
 -f file.txt -6s ::1 -p ah -as 0x20 -aq 0x40 -ak "yugal" -am xorauth.so
 -p udp -us 21 -  ud 21 ::2 

 ==12885== Memcheck, a memory error detector
 ==12885== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
 ==12885== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
 ==12885== Command: sendip -v -p ipv6 -f file.txt -6s ::1 -p ah 
 -as 0x20 -aq 0x40 -ak "yugal" -am xorauth.so -p udp -us 21 -ud 21 ::2
 ==12885== 
 Added 19 options
 Initializing module ipv6
 Initializing module ah
 Initializing module udp
 Finalizing module udp
 Finalizing module ah
 Finalizing module ipv6
 Final packet data:
 60 00 00 00   `...
 00 38 33 20   .83 
 /*rest packet data*/
 73 62 68 64   sbhd
 66 67 68 79   fghy
 68 61 62 63   habc
Freeing module ipv6
Freeing module ah
Freeing module udp
==12885== 
==12885== HEAP SUMMARY:
==12885==     in use at exit: 875 bytes in 7 blocks
==12885==   total heap usage: 115 allocs, 108 frees, 9,587 bytes allocated
==12885== 
==12885== 52 (16 direct, 36 indirect) bytes in 1 blocks are definitely 
lost in loss record 5 of 7
==12885==    at 0x40268A4: malloc (vg_replace_malloc.c:236)
==12885==    by 0x4032ADA: ???
==12885==    by 0x40320EF: ???
==12885==    by 0x804A51D: main (sendip.c:575)
==12885== 
==12885== LEAK SUMMARY:
==12885==    definitely lost: 16 bytes in 1 blocks
==12885==    indirectly lost: 36 bytes in 1 blocks
==12885==      possibly lost: 0 bytes in 0 blocks
==12885==    still reachable: 823 bytes in 5 blocks
==12885==         suppressed: 0 bytes in 0 blocks
==12885== Reachable blocks (those to which a pointer was found) are not shown.
==12885== To see them, rerun with: --leak-check=full --show-reachable=yes
==12885== 
==12885== For counts of detected and suppressed errors, rerun with: -v
==12885== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 35 from 11)

错误到底在哪里???

实际上我xorauth.so在这里的命令中链接了文件,它在可选字段中填充了一些
身份验证数据,但它无法这样做。

运行命令后没有可选的身份验证数据出现在其位置,并且
valgrind还说definitely lost bytes但它没有说明问题出在哪里?
我也尝试了这种变化valgrind

  udit@udit-Dabba ~ $  valgrind --leak-check=full --show-reachable=yes 
  sendip -v -p ipv6 -f file.txt -6s ::1 -p ah -as 0x20 -aq 0x40 
  -ak "yugal" -am xorauth.so -p udp -us 21 -ud 21 ::2 

  ==12893== Memcheck, a memory error detector
  ==12893== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
  ==12893== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
  ==12893== Command: sendip -v -p ipv6 -f file.txt -6s ::1 -p ah -as 0x20
 -aq 0x40 -ak yugal -am xorauth.so -p udp -us 21 -ud 21 ::2
 ==12893== 
 Added 19 options
 Initializing module ipv6
 Initializing module ah
 Initializing module udp
 Finalizing module udp
 Finalizing module ah
 Finalizing module ipv6
 Final packet data:
 60 00 00 00   `...
 00 38 33 20   .83 
 /*rest packet data*/
 66 67 68 79   fghy
 68 61 62 63   habc

 Freeing module ipv6
 Freeing module ah
 Freeing module udp
 ==12893== 
 ==12893== HEAP SUMMARY:
 ==12893==     in use at exit: 875 bytes in 7 blocks
 ==12893==   total heap usage: 115 allocs, 108 frees, 9,587 bytes allocated
 ==12893== 
 ==12893== 28 bytes in 1 blocks are still reachable in loss record 1 of 7
 ==12893==    at 0x40268A4: malloc (vg_replace_malloc.c:236)
 ==12893==    by 0x400CDE8: _dl_map_object_deps (dl-deps.c:510)
 ==12893==    by 0x40125BA: dl_open_worker (dl-open.c:263)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x4012145: _dl_open (dl-open.c:555)
 ==12893==    by 0x40408BA: dlopen_doit (dlopenold.c:55)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x40402CB: _dlerror_run (dlerror.c:164)
 ==12893==    by 0x4040936: dlopen@GLIBC_2.0 (dlopenold.c:77)
 ==12893==    by 0x4032BB3: ???
 ==12893==    by 0x40320EF: ???
 ==12893==    by 0x804A51D: main (sendip.c:575)
 ==12893== 
 ==12893== 33 bytes in 1 blocks are still reachable in loss record 2 of 7
 ==12893==    at 0x40268A4: malloc (vg_replace_malloc.c:236)
 ==12893==    by 0x4004E3E: local_strdup (dl-load.c:162)
 ==12893==    by 0x4007DD8: _dl_map_object (dl-load.c:2183)
 ==12893==    by 0x401255A: dl_open_worker (dl-open.c:226)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x4012145: _dl_open (dl-open.c:555)
 ==12893==    by 0x40408BA: dlopen_doit (dlopenold.c:55)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x40402CB: _dlerror_run (dlerror.c:164)
 ==12893==    by 0x4040936: dlopen@GLIBC_2.0 (dlopenold.c:77)
 ==12893==    by 0x4032BB3: ???
 ==12893==    by 0x40320EF: ???

 ==12893== 
 ==12893== 33 bytes in 1 blocks are still reachable in loss record 3 of 7
 ==12893==    at 0x40268A4: malloc (vg_replace_malloc.c:236)
 ==12893==    by 0x400AA70: _dl_new_object (dl-object.c:161)
 ==12893==    by 0x4005F8F: _dl_map_object_from_fd (dl-load.c:957)
 ==12893==    by 0x4007E92: _dl_map_object (dl-load.c:2250)
 ==12893==    by 0x401255A: dl_open_worker (dl-open.c:226)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x4012145: _dl_open (dl-open.c:555)
 ==12893==    by 0x40408BA: dlopen_doit (dlopenold.c:55)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x40402CB: _dlerror_run (dlerror.c:164)
 ==12893==    by 0x4040936: dlopen@GLIBC_2.0 (dlopenold.c:77)
 ==12893==    by 0x4032BB3: ???
 ==12893== 
 ==12893== 36 bytes in 1 blocks are indirectly lost in loss record 4 of 7
 ==12893==    at 0x40268A4: malloc (vg_replace_malloc.c:236)
 ==12893==    by 0x4032AF3: ???
 ==12893==    by 0x40320EF: ???
 ==12893==    by 0x804A51D: main (sendip.c:575)
 ==12893== 
 ==12893== 52 (16 direct, 36 indirect) bytes in 1 blocks are definitely
 lost in loss record 5 of 7
 ==12893==    at 0x40268A4: malloc (vg_replace_malloc.c:236)
 ==12893==    by 0x4032ADA: ???
 ==12893==    by 0x40320EF: ???
 ==12893==    by 0x804A51D: main (sendip.c:575)
 ==12893== 
 ==12893== 80 bytes in 1 blocks are still reachable in loss record 6 of 7
 ==12893==    at 0x4025355: calloc (vg_replace_malloc.c:467)   
 ==12893==    by 0x400FC84: _dl_check_map_versions (dl-version.c:300)
 ==12893==    by 0x4012810: dl_open_worker (dl-open.c:269)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x4012145: _dl_open (dl-open.c:555)
 ==12893==    by 0x40408BA: dlopen_doit (dlopenold.c:55)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x40402CB: _dlerror_run (dlerror.c:164)

 ==12893==    by 0x4040936: dlopen@GLIBC_2.0 (dlopenold.c:77)
 ==12893==    by 0x4032BB3: ???
 ==12893==    by 0x40320EF: ???
 ==12893==    by 0x804A51D: main (sendip.c:575)
 ==12893== 
 ==12893== 649 bytes in 1 blocks are still reachable in loss record 7 of 7
 ==12893==    at 0x4025355: calloc (vg_replace_malloc.c:467)
 ==12893==    by 0x400A842: _dl_new_object (dl-object.c:77)
 ==12893==    by 0x4005F8F: _dl_map_object_from_fd (dl-load.c:957)
 ==12893==    by 0x4007E92: _dl_map_object (dl-load.c:2250)
 ==12893==    by 0x401255A: dl_open_worker (dl-open.c:226)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x4012145: _dl_open (dl-open.c:555)
 ==12893==    by 0x40408BA: dlopen_doit (dlopenold.c:55)
 ==12893==    by 0x400E4D5: _dl_catch_error (dl-error.c:178)
 ==12893==    by 0x40402CB: _dlerror_run (dlerror.c:164)
 ==12893==    by 0x4040936: dlopen@GLIBC_2.0 (dlopenold.c:77)
 ==12893==    by 0x4032BB3: ???
 ==12893== 
 ==12893== LEAK SUMMARY:
 ==12893==    definitely lost: 16 bytes in 1 blocks
 ==12893==    indirectly lost: 36 bytes in 1 blocks
 ==12893==      possibly lost: 0 bytes in 0 blocks
 ==12893==    still reachable: 823 bytes in 5 blocks
 ==12893==         suppressed: 0 bytes in 0 blocks
 ==12893== 
 ==12893== For counts of detected and suppressed errors, rerun with: -v
 ==12893== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 35 from 11)

我不明白这个输出我在文件夹中看不到任何名为 dl-error 等的文件。请告诉我解决问题的正确方法。

编辑: 正如建议的那样,我应该使用gcc选项-g来包含调试信息......但问题是我正在使用 make 命令,实际上这个实现不是由我完成的。它是一个标准的数据包生成器工具,并且有一些错误。我等不及要修复错误,所以尝试自己动手修复它,因为我的项目因此而陷入困境。所以请告诉我应该怎么做。是否有类似的开关make或者我有改变某处。因为我第一次面对这种情况,所以不知道make和makefile是如何工作的?如果需要,我可以在此处添加一些文件的内容。

sendip.c(第 575 行)

  575:       if(!mod->do_opt(opts[longindex].name,gnuoptarg,mod->pack)) {
  576:       printf("go to hell");// added by me but not printed.
  577:       usage=TRUE; 
  578:       }

make 命令的输出

  udit@udit-Dabba ~/Downloads/sendip-2.5-mec-2 $ make
  for subdir in mec ; do \
    cd $subdir ;\
    make  ;\
    cd ..  ;\
    done
  make[1]: Entering directory `/home/udit/Downloads/sendip-2.5-mec-2/mec'
  make[1]: Nothing to be done for `all'.
  make[1]: Leaving directory `/home/udit/Downloads/sendip-2.5-mec-2/mec'
  gcc -fPIC -fsigned-char -pipe -Wall -Wpointer-arith -Wwrite-strings -Wstrict-   
  prototypes -Wnested-externs -Winline -Werror -g -Wcast-align - 
  DSENDIP_LIBS=\"/usr/local/lib/sendip\"   -c -o sendip.o sendip.c
  sh -c "if [ `uname` = Linux ] ; then \
  gcc -o sendip -g  -rdynamic -ldl -lm -fPIC -fsigned-char -pipe -Wall 
  -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wnested-externs
  -Winline -Werror -g -Wcast-align -DSENDIP_LIBS=\"/usr/local/lib/sendip\" 
  sendip.o gnugetopt.o gnugetopt1.o compact.o ; \
  elif [ `uname` = SunOS ] ; then \
  gcc -o sendip -g -lsocket -lnsl -lm -ldl -fPIC -fsigned-char -pipe -Wall
  -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wnested-externs
  -Winline -Werror -g -Wcast-align -DSENDIP_LIBS=\"/usr/local/lib/sendip\"
  sendip.o gnugetopt.o gnugetopt1.o compact.o ;\
  else \
  gcc -o sendip -g -rdynamic -lm -fPIC -fsigned-char -pipe -Wall 
  -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wnested-externs
  -Winline -Werror -g -Wcast-align -DSENDIP_LIBS=\"/usr/local/lib/sendip\"
  sendip.o gnugetopt.o gnugetopt1.o compact.o ; \
  fi"
  ./help2man -n "Send arbitrary IP packets" -N >sendip.1

* Makefile 的内容:*

   #configureable stuff
   PREFIX ?= /usr/local
   BINDIR ?= $(PREFIX)/bin
   MANDIR ?= $(PREFIX)/share/man/man1
   LIBDIR ?= $(PREFIX)/lib/sendip
   #For most systems, this works
   INSTALL ?= install
   #For Solaris, you may need
   #INSTALL=/usr/ucb/install

   CFLAGS= -fPIC -fsigned-char -pipe -Wall -Wpointer-arith
   -Wwrite-strings \
   -Wstrict-prototypes -Wnested-externs -Winline -Werror -g -Wcast-align \
                    -DSENDIP_LIBS=\"$(LIBDIR)\"
   #-Wcast-align causes problems on solaris, but not serious ones
   LDFLAGS=        -g -rdynamic -lm
   #LDFLAGS_SOLARIS= -g -lsocket -lnsl -lm
   LDFLAGS_SOLARIS= -g -lsocket -lnsl -lm -ldl
   LDFLAGS_LINUX= -g  -rdynamic -ldl -lm
   LIBCFLAGS= -shared
   CC=     gcc

   PROGS= sendip
   BASEPROTOS= ipv4.so ipv6.so
   IPPROTOS= icmp.so tcp.so udp.so
   UDPPROTOS= rip.so ripng.so ntp.so
   TCPPROTOS= bgp.so
   PROTOS= $(BASEPROTOS) $(IPPROTOS) $(UDPPROTOS) $(TCPPROTOS)
   LIBS= libsendipaux.a
   LIBOBJS= csum.o compact.o protoname.o headers.o parseargs.o cryptomod.o crc32.o
   SUBDIRS= mec

   all:    $(LIBS) subdirs sendip $(PROTOS) sendip.1 sendip.spec

   #there has to be a nice way to do this
   sendip: sendip.o        gnugetopt.o gnugetopt1.o compact.o
    sh -c "if [ `uname` = Linux ] ; then \
   $(CC) -o $@ $(LDFLAGS_LINUX) $(CFLAGS) $+ ; \
   elif [ `uname` = SunOS ] ; then \
   $(CC) -o $@ $(LDFLAGS_SOLARIS) $(CFLAGS) $+ ;\
   else \
   $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $+ ; \    
   fi"

   libsendipaux.a: $(LIBOBJS)
    ar vr $@ $?

   subdirs:
    for subdir in $(SUBDIRS) ; do \
            cd $$subdir ;\
            make  ;\
            cd ..  ;\
            done

   protoname.o:    mec/protoname.c
    $(CC) -o $@ -c -I. $(CFLAGS) $+

   headers.o:      mec/headers.c
    $(CC) -o $@ -c -I. $(CFLAGS) $+

   parseargs.o:    mec/parseargs.c
    $(CC) -o $@ -c -I. $(CFLAGS) $+

   cryptomod.o:    mec/cryptomod.c
    $(CC) -o $@ -c -I. $(CFLAGS) $+

   crc32.o: mec/crc32table.h mec/crc32.c
    $(CC) -o $@ -c -I. $(CFLAGS) mec/crc32.c

   mec/crc32table.h: mec/gen_crc32table
    mec/gen_crc32table > mec/crc32table.h

   sendip.1:       ./help2man $(PROGS) $(PROTOS) subdirs VERSION
                    ./help2man -n "Send arbitrary IP packets" -N >sendip.1

   sendip.spec:    sendip.spec.in VERSION
                    echo -n '%define ver ' >sendip.spec
                    cat VERSION >>sendip.spec
                    cat sendip.spec.in >>sendip.spec

    %.so: %.c $(LIBS)
                    $(CC) -o $@ $(CFLAGS) $(LIBCFLAGS) $+ $(LIBS)

   .PHONY: clean install

   clean:
                    rm -f *.o *~ *.so $(PROTOS) $(PROGS) $(LIBS) core gmon.out
                    for subdir in $(SUBDIRS) ; do \
                            cd $$subdir ;\
                            make clean ;\
                            cd ..  ;\
                            done

   veryclean:
                    make clean
                    rm -f sendip.spec sendip.1

   install:                all
                    [ -d $(LIBDIR) ] || mkdir -p $(LIBDIR)
                    [ -d $(BINDIR) ] || mkdir -p $(BINDIR)
                    [ -d $(MANDIR) ] || mkdir -p $(MANDIR)
                    $(INSTALL) -m 755 $(PROGS) $(BINDIR)
                    $(INSTALL) -m 644 sendip.1 $(MANDIR)
                    $(INSTALL) -m 755 $(PROTOS) $(LIBDIR)
                    for subdir in $(SUBDIRS) ; do \
                            cd $$subdir ;\
                            make install ;\
                            cd ..  ;\
                            done


     The problem is coming only with the module xorauth.so ,
     its not performing its work.So tell me how to include some 
     more debugging info ..  
4

3 回答 3

5

这一行:

==12885==    by 0x804A51D: main (sendip.c:575)

表示泄漏的内存是在第 575 行分配的sendip.c(由在该行调用的函数,随后调用到malloc())。您看不到该函数的名称,因为它所在的任何文件都没有使用调试信息进行编译。


所以违规行是:

if(!mod->do_opt(opts[longindex].name,gnuoptarg,mod->pack)) {

这表明内存泄漏在函数内部mod->do_opt()do_opt是结构中的函数指针mod,因此您需要找到该值设置得更深的点。

于 2011-10-05T03:25:59.283 回答
3

Memcheck 工具给出的不良堆栈跟踪可能有多种原因。所有这些都列在 Valgrind FAQ - 4.2 中。Memcheck(或其他工具)提供的堆栈跟踪没有帮助。我该如何改进它们?. 在这种情况下,您正在使用dlopen共享dlclose库,因此很可能调试信息在之后被丢弃,dlclose并且 Valgrind 未能产生良好的堆栈跟踪。解决方法是避免调用dlclose.

另外,对于涉及共享对象的泄漏报告,如果共享对象在程序终止之前被卸载,Valgrind 将丢弃调试信息,错误信息将充满??? 条目。这里的解决方法是避免对这些共享对象调用 dlclose。

于 2011-10-05T18:55:19.557 回答
2

-g您应该使用调试信息( gcc的选项)构建您的程序和库。如果你不这样做,valgrind 仍然可以找到漏洞,但无法指出源代码中错误的来源。回溯中的???表明调试信息不​​可用 - 当调试信息存在时,其中许多应该显示函数名称和行号。

于 2011-10-05T02:31:28.093 回答