应用 Valgrind 发现 Linux 程序的内存问题
Valgrind的使用方法
valgrind的callgrind工具进行多线程性能分析
使用valgrind进行后台服务器的性能优化
Valgrind 3.6.0 for ARM-Linux
应用 Valgrind 发现 Linux 程序的内存问题及交叉编译for arm
valgrind: failed to start tool 'memcheck' for platform 'amd64-linux
https://sourceforge.net/p/valgrind/mailman/search/?q=Assertion+%27done_this_time+%3E%3D+0%27
嵌入式 嵌入式工程师必备软件Valgrind
valgrind --tool=memcheck --leak-check=yes ./my_svr
./valgrind --leak-check=full --show-reachable=yes --trace-children=yes /mnt/nfs/a.out
[root@dvrdvs bin] # ./valgrind --leak-check=full --show-reachable=yes --trace-c
hildren=yes /mnt/nfs/a.out
==25829== Memcheck, a memory error detector
==25829== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25829== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==25829== Command: /mnt/nfs/a.out
==25829==
==25829==
==25829== Process terminating with default action of signal 4 (SIGILL)
==25829== Illegal opcode at address 0x38080404
==25829== at 0x4000E50: _start (in /lib/ld-uClibc-0.9.32.1.so)
valgrind: m_scheduler/scheduler.c:957 (run_thread_for_a_while): Assertion 'done_this_time >= 0' failed.
==25829== at 0x3803496C: ??? (in /tmp/valgrind/lib/valgrind/memcheck-arm-linux)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable
==25829== at 0x4000E50: _start (in /lib/ld-uClibc-0.9.32.1.so)
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.
cat /proc/cpuinfo
Processor : ARMv7 Processor rev 1 (v7l)
processor : 0
BogoMIPS : 1987.37
processor : 1
BogoMIPS : 1993.93
Features : swp half thumb fastmult edsp tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x4
CPU part : 0xc09
CPU revision : 1
Hardware : hi3535
Revision : 0000
Serial : 0000000000000000
valgrind -v -d /bin/true
[root@dvrdvs bin] # ./valgrind --leak-check=full --show-reachable=yes --trace-ch
ildren=yes /mnt/nfs/a.out
==1900== Memcheck, a memory error detector
==1900== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==1900== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==1900== Command: /mnt/nfs/a.out
==1900==
==1900==
==1900== Process terminating with default action of signal 4 (SIGILL)
==1900== Illegal opcode at address 0x3808653C
==1900== at 0x4000E50: _start (in /lib/ld-uClibc-0.9.32.1.so)
==1900==
==1900== HEAP SUMMARY:
==1900== in use at exit: 0 bytes in 0 blocks
==1900== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==1900==
==1900== All heap blocks were freed -- no leaks are possible
==1900==
==1900== For counts of detected and suppressed errors, rerun with: -v
==1900== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Illegal instruction
> $ addr2line -e memcheck-arm-linux -a 0x380869FC
> 0x380869fc
> ~/valgrind-3.11.0/coregrind/m_dispatch/dispatch-arm-linux.S:71
>
> 2. Then, I check the source code at line 71 is:
> fmxr fpscr, r4
>
> 3. Then, I search ARM assembly document:
> 6.7.14. FMRX, FMXR, and FMSTAT
> Transfer contents between an ARM register and a VFP system register.
>
> 4. However, this CPU hi3535 seems don't support VFP, because the Makefile in my SDK use
> armv7a_soft instead of armv7a_vfp glibc runtime library
The minimum hardware which valgrind assumes and requires is armv7 with VFP
(vector floating point.)
The ability to function without floating point would be a new feature for valgrind.
Valgrind would have to notice that the chip lacks VFP, then avoid using it,
and give an error if the target software used FP instructions.
You could enter a Request For Enhancement using the bug reporting tool
http://valgrind.org/support/bug_reports.html
Give the explicit example of your chip, and any others that you know that lack FP
but otherwise are armv7.
Meanwhile, use some other hardware to run your software under valgrind.
Most embedded devices have a subroutine library which maps logical functionality
to the actual hardware. So make a substitute library which maps that
functionality to a hardware device which valgrind does support, such as
a RaspberyyPi model B+ version 2 (1GB RAM, 4CPU, VFP, NEON, ...).
[root@dvrdvs bin] # ./valgrind --leak-check=full --show-reachable=yes --trace-c
hildren=yes /mnt/nfs/a.out
==26433== Memcheck, a memory error detector
==26433== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26433== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==26433== Command: /mnt/nfs/a.out
==26433==
==26433==
==26433== Process terminating with default action of signal 4 (SIGILL)
==26433== Illegal opcode at address 0x38086524
==26433== at 0x4000E50: _start (in /lib/ld-uClibc-0.9.32.1.so)
valgrind: m_scheduler/scheduler.c:957 (run_thread_for_a_while): Assertion 'done_this_time >= 0' failed.
==26433== at 0x38036B84: report_and_quit (m_libcassert.c:260)
==26433== by 0xEB000945: ???
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable
==26433== at 0x4000E50: _start (in /lib/ld-uClibc-0.9.32.1.so)
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.
[root@dvrdvs bin] # ./valgrind -v -d
--957:1:debuglog DebugLog systemarm_notify_die,Oops - undefined instruction
started by Stagarm_notify_die,Oops - undefined instruction
e 1, level 1 logging requested
--957:1:launcher no tool requested, defaulting to 'memcheck'
--957:1:launcher no client specified, defaulting platform to 'arm-linux'
--957:1:launcher launching /mnt/nfs/valgrind/lib/valgrind/memcheck-arm-linux
--957:1:debuglog DebugLog system started by Stage 2 (main), level 1 logging requested
--957:1:main Welcome to Valgrind version 3.9.0 debug logging
--957:1:main Checking current stack is plausible
--957:1:main Checking initial stack was noted
--957:1:main Starting the address space manager
--957:1:main Address space manager is running
--957:1:main Starting the dynamic memory manager
--957:1:mallocfr newSuperblock at 0x61402000 (pszB 4194288) owner VALGRIND/core
--957:1:mallocfr deferred_reclaimSuperblock at 0x61402000 (pszB 4194288) (prev 0x0) owner VALGRIND/core
--957:1:main Dynamic memory manager is running
--957:1:main Initialise m_debuginfo
--957:1:main VG_(libdir) = /mnt/nfs/valgrind/lib/valgrind
--957:1:main Getting launcher's name ...
--957:1:main ... /mnt/nfs/valgrind/bin/valgrind
--957:1:main Get hardware capabilities ...
--957:1:machine ARMv7 VFP 0 VFP2 0 VFP3 0 NEON 0
--957:1:cache Could not autodetect cache info
--957:1:main ... arch = ARM, hwcaps = ARMv7
--957:1:main Getting the working directory at startup
--957:1:main ... /mnt/nfs/valgrind/bin
--957:1:main Split up command line
--957:1:main (early_) Process Valgrind's command line options
--957:1:main Create initial image
--957:1:initimg Loading client
valgrind: no program specified
valgrind: Use --help for more information.
[root@dvrdvs bin] #
[Valgrind-users] valgrind run error , help me, thx
> 1. First, I use addr2line to find out the source code:
> $ addr2line -e memcheck-arm-linux -a 0x380869FC
> 0x380869fc
> ~/valgrind-3.11.0/coregrind/m_dispatch/dispatch-arm-linux.S:71
>
> 2. Then, I check the source code at line 71 is:
> fmxr fpscr, r4
>
> 3. Then, I search ARM assembly document:
> 6.7.14. FMRX, FMXR, and FMSTAT
> Transfer contents between an ARM register and a VFP system register.
>
> 4. However, this CPU hi3535 seems don't support VFP, because the Makefile in my SDK use
> armv7a_soft instead of armv7a_vfp glibc runtime library
The minimum hardware which valgrind assumes and requires is armv7 with VFP
(vector floating point.)
The ability to function without floating point would be a new feature for valgrind.
Valgrind would have to notice that the chip lacks VFP, then avoid using it,
and give an error if the target software used FP instructions.
You could enter a Request For Enhancement using the bug reporting tool
http://valgrind.org/support/bug_reports.html
Give the explicit example of your chip, and any others that you know that lack FP
but otherwise are armv7.
Meanwhile, use some other hardware to run your software under valgrind.
Most embedded devices have a subroutine library which maps logical functionality
to the actual hardware. So make a substitute library which maps that
functionality to a hardware device which valgrind does support, such as
a RaspberyyPi model B+ version 2 (1GB RAM, 4CPU, VFP, NEON, ...).
注:网上搜索到的一个解释,貌似是hisi3531 20a不支持VFP导致
下面是我的程序运行时的说明:
[root@dvrdvs bin] # ./valgrind /mnt/nfs/a.out
==969== Memcheck, a memory error detector
==969== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==969== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==969== Command: /mnt/nfs/a.out
==969==
arm_notify_die,Oops - undefined instruction
==969==
==969== Process terminating with default action of signal 4 (SIGILL)
==969== Illegal opcode at address 0x380D858C
==969== at 0x80F0: ??? (in /mnt/nfs/a.out)
valgrind: m_scheduler/scheduler.c:957 (run_thread_for_a_while): Assertion 'done_this_time >= 0' failed.
==969== at 0x38063FD0: report_and_quit (m_libcassert.c:260)
==969== by 0x380642B3: vgPlain_assert_fail (m_libcassert.c:340)
==969== by 0x380EB90B: run_thread_for_a_while (scheduler.c:957)
==969== by 0x380EC753: vgPlain_scheduler (scheduler.c:1267)
==969== by 0x3810A31B: thread_wrapper (syswrap-linux.c:103)
==969== by 0x3810A513: run_a_thread_NORETURN (syswrap-linux.c:156)
==969== by 0xFFFFFFFF: ???
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable
==969== at 0x80F0: ??? (in /mnt/nfs/a.out)
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.
查看0x380D858C位置:
yinguicai@Cpl-IBP-Product:~/data/work/svn/vis_tools/valgrind/output/lib/valgrind$ arm-hisiv100nptl-linux-addr2line -f -e memcheck-arm-linux 0x380D858C
vgPlain_disp_run_translations
/workteam/yinguicai/data/work/svn/vis_tools/valgrind/valgrind-3.9.0/coregrind/m_dispatch/dispatch-arm-linux.S:71
出错指令:
70 mov r4, #0
71 fmxr fpscr, r4
与搜索到的解释一致,目前在该平台下暂时放弃对valgrind的使用
在调试valgrind过程中memcheck-arm-linux是由exec执行的,gdb需要多进程调试,下面是一些记录:
[root@dvrdvs bin] # /mnt/nfs/gdb ./valgrind
GNU gdb (GDB) 7.3
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /mnt/nfs/valgrind/bin/valgrind...done.
(gdb) b main
Breakpoint 1 at 0x9310: file launcher-linux.c, line 258.
(gdb) catch exec
Catchpoint 2 (exec)
(gdb) c
The program is not being run.
(gdb) r
Starting program: /mnt/nfs/valgrind/bin/valgrind
Breakpoint 1, main (argc=1, argv=0xbef2ed94, envp=0xbef2ed9c)
at launcher-linux.c:258
258 launcher-linux.c: No such file or directory.
in launcher-linux.c
(gdb) c
Continuing.
process 929 is executing new program: /mnt/nfs/valgrind/lib/valgrind/memcheck-arm-linux
Error in re-setting breakpoint 1: Function "main" not defined.
Catchpoint 2 (exec'd /mnt/nfs/valgrind/lib/valgrind/memcheck-arm-linux), 0x38076520 in _start () at m_main.c:2704
warning: Source file is more recent than executable.
2704 vg_assert(0);
(gdb) b m_machine.c:1380
Breakpoint 3 at 0x3806c1b0: file m_machine.c, line 1380.
(gdb) c
Continuing.
Breakpoint 3, vgPlain_machine_get_hwcaps () at m_machine.c:1380
warning: Source file is more recent than executable.
1380 have_VFP = True;
(gdb) n
参考资料:
Gdb调试多进程程序
注意:采用gdbserver+gdb方式调试时,这几种方法都试过,均不适合进行多进程调试
valgrind相关示例程序:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <ctype.h> #include <assert.h> #include <time.h> #include <sys/time.h> int add(int x, int y) { return 0; } int fun() { int *p = (int*)malloc(10*sizeof(int)); p[10] = 0; return 0; } int main() { fun(); printf("....over... "); return 0; }
yinguicai@Cpl-IBP-Product:~/tmp/valgrind$ gcc -g -O0 test.c
yinguicai@Cpl-IBP-Product:~/tmp/valgrind$ ls
a.out test.c
yinguicai@Cpl-IBP-Product:~/tmp/valgrind$ valgrind ./a.out
==28396== Memcheck, a memory error detector
==28396== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==28396== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==28396== Command: ./a.out
==28396==
==28396== Invalid write of size 4
==28396== at 0x400573: fun (test.c:38)
==28396== by 0x40058D: main (test.c:46)
==28396== Address 0x51f0068 is 0 bytes after a block of size 40 alloc'd
==28396== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28396== by 0x400566: fun (test.c:36)
==28396== by 0x40058D: main (test.c:46)
==28396==
....over...
==28396==
==28396== HEAP SUMMARY:
==28396== in use at exit: 40 bytes in 1 blocks
==28396== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==28396==
==28396== LEAK SUMMARY:
==28396== definitely lost: 40 bytes in 1 blocks
==28396== indirectly lost: 0 bytes in 0 blocks
==28396== possibly lost: 0 bytes in 0 blocks
==28396== still reachable: 0 bytes in 0 blocks
==28396== suppressed: 0 bytes in 0 blocks
==28396== Rerun with --leak-check=full to see details of leaked memory
==28396==
==28396== For counts of detected and suppressed errors, rerun with: -v
==28396== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
yinguicai@Cpl-IBP-Product:~/tmp/valgrind$ valgrind --leak-check=full ./a.out
==28544== Memcheck, a memory error detector
==28544== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==28544== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==28544== Command: ./a.out
==28544==
==28544== Invalid write of size 4
==28544== at 0x400573: fun (test.c:38)
==28544== by 0x40058D: main (test.c:46)
==28544== Address 0x51f0068 is 0 bytes after a block of size 40 alloc'd
==28544== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28544== by 0x400566: fun (test.c:36)
==28544== by 0x40058D: main (test.c:46)
==28544==
....over...
==28544==
==28544== HEAP SUMMARY:
==28544== in use at exit: 40 bytes in 1 blocks
==28544== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==28544==
==28544== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==28544== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28544== by 0x400566: fun (test.c:36)
==28544== by 0x40058D: main (test.c:46)
==28544==
==28544== LEAK SUMMARY:
==28544== definitely lost: 40 bytes in 1 blocks
==28544== indirectly lost: 0 bytes in 0 blocks
==28544== possibly lost: 0 bytes in 0 blocks
==28544== still reachable: 0 bytes in 0 blocks
==28544== suppressed: 0 bytes in 0 blocks
==28544==
==28544== For counts of detected and suppressed errors, rerun with: -v
==28544== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
yinguicai@Cpl-IBP-Product:~/tmp/valgrind$ strip a.out
yinguicai@Cpl-IBP-Product:~/tmp/valgrind$ valgrind --leak-check=full ./a.out
==28882== Memcheck, a memory error detector
==28882== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==28882== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==28882== Command: ./a.out
==28882==
==28882== Invalid write of size 4
==28882== at 0x400573: ??? (in /workteam/yinguicai/tmp/valgrind/a.out)
==28882== by 0x40058D: ??? (in /workteam/yinguicai/tmp/valgrind/a.out)
==28882== by 0x4E5376C: (below main) (libc-start.c:226)
==28882== Address 0x51f0068 is 0 bytes after a block of size 40 alloc'd
==28882== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28882== by 0x400566: ??? (in /workteam/yinguicai/tmp/valgrind/a.out)
==28882== by 0x40058D: ??? (in /workteam/yinguicai/tmp/valgrind/a.out)
==28882== by 0x4E5376C: (below main) (libc-start.c:226)
==28882==
....over...
==28882==
==28882== HEAP SUMMARY:
==28882== in use at exit: 40 bytes in 1 blocks
==28882== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==28882==
==28882== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==28882== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28882== by 0x400566: ??? (in /workteam/yinguicai/tmp/valgrind/a.out)
==28882== by 0x40058D: ??? (in /workteam/yinguicai/tmp/valgrind/a.out)
==28882== by 0x4E5376C: (below main) (libc-start.c:226)
==28882==
==28882== LEAK SUMMARY:
==28882== definitely lost: 40 bytes in 1 blocks
==28882== indirectly lost: 0 bytes in 0 blocks
==28882== possibly lost: 0 bytes in 0 blocks
==28882== still reachable: 0 bytes in 0 blocks
==28882== suppressed: 0 bytes in 0 blocks
==28882==
==28882== For counts of detected and suppressed errors, rerun with: -v
==28882== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
aa