|
From: Kacper K. <kac...@gm...> - 2017-09-01 10:00:11
|
John Reiser
17:27 (18 godzin temu)
> ==19124== at 0x40054EC: ??? (in /lib/ld-uClibc-0.9.33.2.so <
http://ld-uClib...
Kacper Kowalski <kac...@gm...>
11:57 (1 minutę temu)
do John
Hi!
By default valgrind is not selectable in menuconfig for IMX6 platform when
cross compiling for Openwrt, but this platform is based on ARM Cortex A9
core which is implementing ARMv7 architecture. This architecture is
supported by valgrind, so I made little changes in Makefile of valgrind
package to make the package selectable from menuconfig and compilable.
I'm using GCC-5.3 and uClibc-0.9.33.2 (can't proceed to musl for now
because it is very expensive).
The problem is that valgrind is not working properly even for /bin/true:
> valgrind --leak-check=yes /bin/true
Output:
==19124== Memcheck, a memory error detector
==19124== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==19124== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==19124== Command: /bin/true
==19124==
==19124== Invalid read of size 4
==19124== at 0x40054EC: ??? (in /lib/ld-uClibc-0.9.33.2.so)
==19124== Address 0x7df01864 is on thread 1's stack
==19124== 20 bytes below stack pointer
==19124==
==19124== Invalid read of size 4
==19124== at 0x48B8CD4: ??? (in /lib/libuClibc-0.9.33.2.so)
==19124== Address 0x7df01a5c is on thread 1's stack
==19124== 20 bytes below stack pointer
==19124==
==19124== Invalid read of size 4
==19124== at 0x48B8AC0: ??? (in /lib/libuClibc-0.9.33.2.so)
==19124== Address 0x7df01a04 is on thread 1's stack
==19124== 20 bytes below stack pointer
==19124==
==19124== Invalid read of size 4
==19124== at 0x4000E54: ??? (in /lib/ld-uClibc-0.9.33.2.so)
==19124== Address 0x7df019f4 is on thread 1's stack
==19124== 20 bytes below stack pointer
==19124==
==19124==
==19124== HEAP SUMMARY:
==19124== in use at exit: 0 bytes in 0 blocks
==19124== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==19124==
==19124== All heap blocks were freed -- no leaks are possible
==19124==
==19124== For counts of detected and suppressed errors, rerun with: -v
==19124== ERROR SUMMARY: 64 errors from 4 contexts (suppressed: 0 from 0)
I found that "-D__UCLIBC__" flag should be applied when compiling valgrind,
but that didn't help, the output is the same.
Thank you for the answer.
I thought that the complaint is incorrect because it's complaining on a
simple program. Now I know that the complaint could be correct.
I couldn't run /bin/true in way you recommended, because no debug
information was provided, so I compiled simplest program with debug switch:
#include <iostream>
int main()
{
return 0;
}
Started gdbserver and connected to it using command:
(gdb) target remote | /usr/lib/valgrind/../../bin/vgdb --pid=2418
The output from gdb till first error:
Remote debugging using | /usr/lib/valgrind/../../bin/vgdb --pid=2418
relaying data between gdb and process 2418
Reading symbols from /lib/ld-uClibc.so.0...(no debugging symbols
found)...done.
Loaded symbols for /lib/ld-uClibc.so.0
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
Cannot access memory at address 0x0
0x04000e68 in ?? ()
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x040054ec in ?? ()
(gdb) info reg
r0 0x4007148 67137864
r1 0x0 0
r2 0x49ba000 77307904
r3 0x49bd90c 77322508
r4 0x4015f78 67198840
r5 0x4006054 67133524
r6 0xa 10
r7 0x4006ac0 67136192
r8 0x24 36
r9 0x401602c 67199020
r10 0x7d87aa48 2106042952 <%28210%29%20604-2952>
r11 0x7d87a674 2106041972 <%28210%29%20604-1972>
r12 0x7d87a678 2106041976 <%28210%29%20604-1976>
sp 0x7d87a678 0x7d87a678
lr 0x40054ec 67130604
pc 0x40054ec 0x40054ec
cpsr 0x20000010 536870928
Corresponding output from gdbserver:
==2418== Invalid read of size 4
==2418== at 0x40054EC: ??? (in /lib/ld-uClibc-0.9.33.2.so)
==2418== Address 0x7d87a664 is on thread 1's stack
==2418== 20 bytes below stack pointer
==2418==
==2418== (action on error) vgdb me ...
Next error:
(gdb) info reg
r0 0x7d87ad21 2106043681 <%28210%29%20604-3681>
r1 0x4a2b000 77770752
r2 0x10680 67200
r3 0x4a2f494 77788308
r4 0x7d87ad03 2106043651 <%28210%29%20604-3651>
r5 0x104d8 66776
r6 0x7d87aa60 2106042976 <%28210%29%20604-2976>
r7 0x8 8
r8 0x0 0
r9 0x0 0
r10 0x4015f78 67198840
r11 0x7d87aa4c 2106042956 <%28210%29%20604-2956>
r12 0x7d87aa50 2106042960 <%28210%29%20604-2960>
sp 0x7d87aa50 0x7d87aa50
lr 0x4a15cd4 77683924
pc 0x4a15cd4 0x4a15cd4
cpsr 0x20000010 536870928
And corresponding gdbserver output:
==2418== Invalid read of size 4
==2418== at 0x4A15CD4: ??? (in /lib/libuClibc-0.9.33.2.so)
==2418== Address 0x7d87aa3c is on thread 1's stack
==2418== 20 bytes below stack pointer
Next error:
(gdb) info reg
r0 0x207d8 133080
r1 0x1 1
r2 0x0 0
r3 0x10680 67200
r4 0x4a2b000 77770752
r5 0x0 0
r6 0x7d87aa60 2106042976 <%28210%29%20604-2976>
r7 0x4a2b400 77771776
r8 0x0 0
r9 0x0 0
r10 0x4015f78 67198840
r11 0x7d87aa2c 2106042924 <%28210%29%20604-2924>
r12 0x7d87aa30 2106042928 <%28210%29%20604-2928>
sp 0x7d87aa30 0x7d87aa30
lr 0x4a15ac0 77683392
pc 0x4a15ac0 0x4a15ac0
cpsr 0x20000010 536870928
Gdbserver:
==2418== Invalid read of size 4
==2418== at 0x4A15AC0: ??? (in /lib/libuClibc-0.9.33.2.so)
==2418== Address 0x7d87aa1c is on thread 1's stack
==2418== 20 bytes below stack pointer
And the last one:
(gdb) info reg
r0 0x482778c 75659148
r1 0x1 1
r2 0x4817000 75591680
r3 0x4817678 75593336
r4 0x4006178 67133816
r5 0x0 0
r6 0x4016034 67199028
r7 0x401602c 67199020
r8 0x0 0
r9 0x0 0
r10 0x4015f78 67198840
r11 0x7d87aa1c 2106042908 <%28210%29%20604-2908>
r12 0x7d87aa20 2106042912 <%28210%29%20604-2912>
sp 0x7d87aa20 0x7d87aa20
lr 0x4000e54 67112532
pc 0x4000e54 0x4000e54
cpsr 0x20000010 536870928
Gdbserver:
==2418== Invalid read of size 4
==2418== at 0x4000E54: ??? (in /lib/ld-uClibc-0.9.33.2.so)
==2418== Address 0x7d87aa0c is on thread 1's stack
==2418== 20 bytes below stack pointer
Summary:
==2418== HEAP SUMMARY:
==2418== in use at exit: 0 bytes in 0 blocks
==2418== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==2418==
==2418== All heap blocks were freed -- no leaks are possible
==2418==
==2418== For counts of detected and suppressed errors, rerun with: -v
==2418== ERROR SUMMARY: 128 errors from 4 contexts (suppressed: 0 from 0)
|
|
From: Kacper K. <kac...@gm...> - 2017-09-06 15:42:53
|
I booted from new image which was compiled fully with GCC-5.3 and the
problem still occurs. The advantage is that packages with debug symbols
were used and I can use the bt gdb command.
GDB:
(gdb) set verbose on
(gdb) target remote | /usr/lib/valgrind/../../bin/vgdb --pid=8269
Remote debugging using | /usr/lib/valgrind/../../bin/vgdb --pid=8269
relaying data between gdb and process 8269
Reading symbols from /lib/ld-uClibc.so.0...done.
Loaded symbols for /lib/ld-uClibc.so.0
0x04000e68 in _start () from /lib/ld-uClibc.so.0
(gdb) c
Continuing.
Reading in symbols for ldso/ldso/ldso.c...done.
Reading symbols from /usr/lib/valgrind/vgpreload_core-arm-linux.so...done.
Loaded symbols for /usr/lib/valgrind/vgpreload_core-arm-linux.so
Reading symbols from
/usr/lib/valgrind/vgpreload_memcheck-arm-linux.so...done.
Loaded symbols for /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so
Reading symbols from /usr/lib/libboost_thread.so.1.64.0...(no debugging
symbols found)...done.
Loaded symbols for /usr/lib/libboost_thread.so.1.64.0
Reading symbols from /usr/lib/libboost_system.so.1.64.0...(no debugging
symbols found)...done.
Loaded symbols for /usr/lib/libboost_system.so.1.64.0
Reading symbols from /lib/libpthread.so.0...done.
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /usr/lib/libstdc++.so.6...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/libm.so.0...done.
Loaded symbols for /lib/libm.so.0
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.0...done.
Loaded symbols for /lib/libc.so.0
Reading symbols from /usr/lib/libboost_atomic.so.1.64.0...(no debugging
symbols found)...done.
Loaded symbols for /usr/lib/libboost_atomic.so.1.64.0
Reading symbols from /lib/librt.so.0...done.
Loaded symbols for /lib/librt.so.0
Reading symbols from /lib/libdl.so.0...done.
Loaded symbols for /lib/libdl.so.0
Program received signal SIGTRAP, Trace/breakpoint trap.
_dl_get_ready_to_run (Reading in symbols for
libc/sysdeps/linux/arm/crti.S...done.
tpnt=0x4007ac0, load_addr=<optimized out>, auxvt=0x7d80ca48,
envp=<optimized out>, argv=0x0) at ldso/ldso/ldso.c:1396
1396 ldso/ldso/ldso.c: No such file or directory.
Current language: auto
The current source language is "auto; currently c".
(gdb) bt
#0 _dl_get_ready_to_run (tpnt=0x4007ac0, load_addr=<optimized out>,
auxvt=0x7d80ca48, envp=<optimized out>, argv=0x0) at ldso/ldso/ldso.c:1396
#1 0x049be918 in _init () at libc/sysdeps/linux/arm/crti.S:22
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) c
Continuing.
Reading in symbols for libc/misc/internals/__uClibc_main.c...done.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x04a170a0 in __uClibc_main (main=0x7d80cc04, argc=77770752, argv=Reading
in symbols for libc/sysdeps/linux/arm/crtn.S...done.
0x104e4 <_init+12>, app_init=Reading in symbols for
libc/sysdeps/linux/arm/crti.S...done.
0x104d8 <_init>, app_fini=0x10680 <_fini>, rtld_fini=0x4000df0 <_dl_fini>,
stack_end=0x7d80cc04) at libc/misc/internals/__uClibc_main.c:440
440 libc/misc/internals/__uClibc_main.c: No such file or directory.
(gdb) bt
#0 0x04a170a0 in __uClibc_main (main=0x7d80cc04, argc=77770752,
argv=0x104e4 <_init+12>, app_init=0x104d8 <_init>, app_fini=0x10680
<_fini>,
rtld_fini=0x4000df0 <_dl_fini>, stack_end=0x7d80cc04) at
libc/misc/internals/__uClibc_main.c:440
#1 0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
__GI___uClibc_fini () at libc/misc/internals/__uClibc_main.c:304
304 in libc/misc/internals/__uClibc_main.c
(gdb) bt
Reading in symbols for libc/stdlib/exit.c...done.
#0 __GI___uClibc_fini () at libc/misc/internals/__uClibc_main.c:304
#1 0x04a134bc in __GI_exit (rv=0) at libc/stdlib/_atexit.c:336
#2 0x04a17190 in __uClibc_main (main=0x7d80cc04, argc=77770752,
argv=0x4a17190 <__uClibc_main+764>, app_init=0x0, app_fini=0x10680 <_fini>,
rtld_fini=0x4000df0 <_dl_fini>, stack_end=0x7d80cc04) at
libc/misc/internals/__uClibc_main.c:511
#3 0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
_dl_fini () at ldso/ldso/ldso.c:311
311 ldso/ldso/ldso.c: No such file or directory.
(gdb) bt
Reading in symbols for libc/sysdeps/linux/arm/crti.S...done.
#0 _dl_fini () at ldso/ldso/ldso.c:311
#1 0x04818684 in _fini () at libc/sysdeps/linux/arm/crti.S:41
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) c
Continuing.
[Inferior 1 (Remote target) exited normally]
GDBSERVER:
==8269== Memcheck, a memory error detector
==8269== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8269== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==8269== Command: /nmi/programs/inter_empty/bin/inter_empty
==8269==
==8269== (action at startup) vgdb me ...
==8269==
==8269== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==8269== /path/to/gdb /nmi/programs/inter_empty/bin/inter_empty
==8269== and then give GDB the following command
==8269== target remote | /usr/lib/valgrind/../../bin/vgdb --pid=8269
==8269== --pid is optional if only one valgrind process is running
==8269==
==8269== Invalid read of size 4
==8269== at 0x40058F8: _dl_get_ready_to_run (ldso.c:1396)
==8269== Address 0x7d80c624 is on thread 1's stack
==8269== 20 bytes below stack pointer
==8269==
==8269== (action on error) vgdb me ...
==8269== Continuing ...
==8269== Invalid read of size 4
==8269== at 0x4A170A0: __uClibc_main (__uClibc_main.c:440)
==8269== by 0xFFFFFFFF: ???
==8269== Address 0x7d80ca34 is on thread 1's stack
==8269== 20 bytes below stack pointer
==8269==
==8269== (action on error) vgdb me ...
==8269== Continuing ...
==8269== Invalid read of size 4
==8269== at 0x4A16E70: __uClibc_fini (__uClibc_main.c:304)
==8269== by 0x4A134BB: exit (_atexit.c:336)
==8269== by 0x4A1718F: __uClibc_main (__uClibc_main.c:511)
==8269== by 0xFFFFFFFF: ???
==8269== Address 0x7d80ca0c is on thread 1's stack
==8269== 20 bytes below stack pointer
==8269==
==8269== (action on error) vgdb me ...
==8269== Continuing ...
==8269== Invalid read of size 4
==8269== at 0x4000E54: ??? (ldso.c:311)
==8269== Address 0x7d80c9fc is on thread 1's stack
==8269== 20 bytes below stack pointer
==8269==
==8269== (action on error) vgdb me ...
==8269== Continuing ...
==8269==
==8269== HEAP SUMMARY:
==8269== in use at exit: 20,224 bytes in 1 blocks
==8269== total heap usage: 6 allocs, 5 frees, 20,632 bytes allocated
==8269==
==8269== LEAK SUMMARY:
==8269== definitely lost: 0 bytes in 0 blocks
==8269== indirectly lost: 0 bytes in 0 blocks
==8269== possibly lost: 0 bytes in 0 blocks
==8269== still reachable: 20,224 bytes in 1 blocks
==8269== suppressed: 0 bytes in 0 blocks
==8269== Rerun with --leak-check=full to see details of leaked memory
==8269==
==8269== For counts of detected and suppressed errors, rerun with: -v
==8269== ERROR SUMMARY: 128 errors from 4 contexts (suppressed: 0 from 0)
|
|
From: Kacper K. <kac...@gm...> - 2017-09-07 13:31:28
|
Thank you very much, John Reiser, for such extensive help. If I understood correctly, memcheck uses hardcoded SP and it's r13? It should use the register passed with ldmdb instruction as SP (within this example it will be r11)? According to your suggestion I used "--ignore-range-below-sp=X-Y", but with other values, because valgrind documentation says that X must be > Y and they must be decimal. I used trial and error method to achieve smallest range defining ignored range and I finally found out that memcheck doesn't complain when I pass: "--ignore-range-below-sp=44-13" and valgrind works fine with "--leak-check=full" parameter used. I can't find out exactly why such numbers should be used. It is clear that 44 stand for 11 registers pushed on the stack, but why memcheck complains only when 8 registers are fetched ((44 - 13 + 1)/4 = 8)? Is it caused by updating of r13(==sp) after second fetch when ldmdb is used? |
|
From: John R. <jr...@bi...> - 2017-09-07 15:06:58
|
On 09/07/2017 Kacper Kowalski wrote:
> Thank you very much, John Reiser, for such extensive help.
You're welcome.
>
> If I understood correctly, memcheck uses hardcoded SP and it's r13? It should use the register passed with ldmdb instruction as SP (within this example it will be r11)?
No, the details are different. The hardware itself has hardcoded r13 as the
stack pointer sp. It looks to me like the compiler is trying to tail-merge
the exit-from-subroutine so that all of the branches of a final if-then-else
come together and return from exactly one point. When the subroutine
uses any of r4 through r11 then those registers must be saved at entry
and restored just before return.
The ldmdb does that, and also performs the return by writing r15(==pc).
(The compiler also cleverly uses the ldmdb to restore sp(==r13) from r12.)
Always exiting from exactly one point does have value, but in this case
where something shorter would work ("bx lr", or "mov pc,lr", or "blx lr";
or even the pair "push lr; pop pc" [==> str lr,[sp, #-4]!; ldr pc,[sp],#4!] )
even if some other paths still must use the ldmdb, then the
move-stmdb-sub wastes time and space.
>
> ... "--ignore-range-below-sp=44-13" ... I can't find out exactly why such numbers
> should be used. It is clear that 44 stand for 11 registers pushed on the stack > but why memcheck complains only when 8 registers are
> fetched ((44 - 13 + 1)/4 = 8)?
> Is it caused by updating of r13(==sp) after the second fetch when ldmdb is used?
Yes. memcheck's emulation of ldmdb is serial, using the newly-written value
of r13(==sp) to check the fetches for lower-numbered registers. All known
instances of ARM hardware effectively do everything in parallel (and cannot
be interrupted), which protects all the fetches. [I cannot find where this
is documented in the ARM manual.]
Using --ignore-range-below-sp does reduce the noise, but has the danger of
ignoring actual errors for references in that range. For ldmdb, then
memcheck should use an extra temporary variable to hold the new value of sp,
and perform the actual assignment to sp only after writing all the other
registers. (And the compiler-generated code should be improved, too.)
--
|