From: Andrejs B. <sin...@gm...> - 2014-05-21 11:15:02
|
Hi there! I'm quite new to Linux and was trying to use Valgrind for finding leaks on 32-bit Linux ARMv7 (3.6.0, armv7l). I crosscompiled Valgrind using non-stripped version of uClibc library. I tried Valgrind version 3.9.0 and then newest from SVN (13985). ldd's output for valgrind: /# ldd /usr/bin/valgrind ldd: can't open cache '/etc/ld.so.cache' libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb6f27000) libc.so.0 => /lib/libc.so.0 (0xb6ed2000) ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0xb6f3a000) I tried detecting obvious leak in an example: /* leak.c */ #include <stdlib.h> int main() { int *x = malloc(10 * sizeof(int)); return 0; } On Linux/x86-64 leak was detected. On Linux/ARM using --trace-redir=yes option I've found that vgpreload_core-arm-linux.so and vgpreload_memcheck-arm-linux.so files are not being read. Using strace on Valgrind I found that vgpreload_memcheck-arm-linux.so is accessed, but not used (access("/usr/lib/valgrind/vgpreload_memcheck-arm-linux.so", R_OK) = 0). I've checked ld-uClibc-0.9.33.2.so, libuClibc-0.9.33.2.so and Valgrind's *.so files using 'file' and 'readelf'. They are not stripped. Also, have checked libuClibc-0.9.33.2.so for 'malloc' with 'readelf -a libuClibc-0.9.33.2.so | grep malloc'. It's there. Have checked sonames. They are same as shown in Valgrind's log. Full Valgrind log on Linux/ARM: /# valgrind --trace-redir=yes ./leak ==3526== Memcheck, a memory error detector ==3526== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==3526== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==3526== Command: ./leak ==3526== --3526-- << --3526-- ------ REDIR STATE after VG_(redir_initialise) ------ --3526-- TOPSPECS of soname (hardwired) --3526-- ld-linux-armhf.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux-armhf.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ld-linux.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ------ ACTIVE ------ --3526-- >> --3526-- Reading syms from /transit/misc/leak --3526-- svma 0x0000008338, avma 0x0000008338 --3526-- << --3526-- ------ REDIR STATE after VG_(redir_notify_new_DebugInfo) ------ --3526-- TOPSPECS of soname NONE filename /transit/misc/leak --3526-- TOPSPECS of soname (hardwired) --3526-- ld-linux-armhf.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux-armhf.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ld-linux.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ------ ACTIVE ------ --3526-- >> --3526-- Reading syms from /lib/ld-uClibc-0.9.33.2.so --3526-- svma 0x0000000dc0, avma 0x0004000dc0 --3526-- << --3526-- ------ REDIR STATE after VG_(redir_notify_new_DebugInfo) ------ --3526-- TOPSPECS of soname ld-uClibc.so.0 filename /lib/ld-uClibc-0.9.33.2.so --3526-- TOPSPECS of soname NONE filename /transit/misc/leak --3526-- TOPSPECS of soname (hardwired) --3526-- ld-linux-armhf.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux-armhf.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ld-linux.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ------ ACTIVE ------ --3526-- >> --3526-- Reading syms from /usr/lib/valgrind/memcheck-arm-linux --3526-- svma 0x00380000c0, avma 0x00380000c0 --3526-- << --3526-- ------ REDIR STATE after VG_(redir_notify_new_DebugInfo) ------ --3526-- TOPSPECS of soname NONE filename /usr/lib/valgrind/memcheck-arm-linux --3526-- TOPSPECS of soname ld-uClibc.so.0 filename /lib/ld-uClibc-0.9.33.2.so --3526-- TOPSPECS of soname NONE filename /transit/misc/leak --3526-- TOPSPECS of soname (hardwired) --3526-- ld-linux-armhf.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux-armhf.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ld-linux.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ------ ACTIVE ------ --3526-- >> --3526-- Reading syms from /lib/libgcc_s.so.1 --3526-- svma 0x0000003c58, avma 0x0004812c58 --3526-- << --3526-- ------ REDIR STATE after VG_(redir_notify_new_DebugInfo) ------ --3526-- TOPSPECS of soname libgcc_s.so.1 filename /lib/libgcc_s.so.1 --3526-- TOPSPECS of soname NONE filename /usr/lib/valgrind/memcheck-arm-linux --3526-- TOPSPECS of soname ld-uClibc.so.0 filename /lib/ld-uClibc-0.9.33.2.so --3526-- TOPSPECS of soname NONE filename /transit/misc/leak --3526-- TOPSPECS of soname (hardwired) --3526-- ld-linux-armhf.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux-armhf.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ld-linux.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ------ ACTIVE ------ --3526-- >> --3526-- Reading syms from /lib/libuClibc-0.9.33.2.so --3526-- svma 0x000000a7b0, avma 0x000482c7b0 --3526-- << --3526-- ------ REDIR STATE after VG_(redir_notify_new_DebugInfo) ------ --3526-- TOPSPECS of soname libc.so.0 filename /lib/libuClibc-0.9.33.2.so --3526-- TOPSPECS of soname libgcc_s.so.1 filename /lib/libgcc_s.so.1 --3526-- TOPSPECS of soname NONE filename /usr/lib/valgrind/memcheck-arm-linux --3526-- TOPSPECS of soname ld-uClibc.so.0 filename /lib/ld-uClibc-0.9.33.2.so --3526-- TOPSPECS of soname NONE filename /transit/misc/leak --3526-- TOPSPECS of soname (hardwired) --3526-- ld-linux-armhf.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux.so.3 memcpy R-> (0000.0) 0x38075c50 --3526-- ld-linux-armhf.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ld-linux.so.3 strlen R-> (0000.0) 0x38075c24 --3526-- ------ ACTIVE ------ --3526-- >> ==3526== Invalid read of size 4 ==3526== at 0x4005550: _dl_get_ready_to_run (in /lib/ld-uClibc-0.9.33.2.so) ==3526== Address 0xbde78a9c is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes ==3526== ==3526== Invalid read of size 4 ==3526== at 0x4864C34: __uClibc_main (in /lib/libuClibc-0.9.33.2.so) ==3526== Address 0xbde78c6c is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes ==3526== ==3526== Invalid read of size 4 ==3526== at 0x4864A30: __uClibc_fini (in /lib/libuClibc-0.9.33.2.so) ==3526== Address 0xbde78c4c is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes ==3526== ==3526== Invalid read of size 4 ==3526== at 0x4000E1C: ??? (in /lib/ld-uClibc-0.9.33.2.so) ==3526== Address 0xbde78c34 is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes ==3526== ==3526== ==3526== HEAP SUMMARY: ==3526== in use at exit: 0 bytes in 0 blocks ==3526== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3526== ==3526== All heap blocks were freed -- no leaks are possible ==3526== ==3526== For counts of detected and suppressed errors, rerun with: -v ==3526== ERROR SUMMARY: 32 errors from 4 contexts (suppressed: 0 from 0) On Linux/x86-64 using --trace-redir=yes I've found, that functions from libc.so.0 are being redirected after vgpreload_memcheck-amd64-linux.so is being read. Excerpt from log: >> --6671-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so --6671-- svma 0x0000002f10, avma 0x0004c28f10 --6671-- << --6671-- ------ REDIR STATE after VG_(redir_notify_new_DebugInfo) ------ --6671-- TOPSPECS of soname NONE filename /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so --6671-- libc.so* setenv W-> (0000.0) 0x04c2f8a0 --6671-- libc.so* unsetenv W-> (0000.0) 0x04c2f800 --6671-- libc.so* putenv W-> (0000.0) 0x04c2f760 --6671-- libc.so* wcslen R-> (2037.0) 0x04c2f740 --6671-- libc.so* strcasestr R-> (2035.0) 0x04c2f680 --6671-- libc.so* strspn R-> (2034.0) 0x04c2f600 Also hardwired sonames are redirected on x86-64, but not on ARM. But that's maybe cause soname 'ld-uClibc.so.0' differs from 'ld-linux.so.3' and 'ld-linux-armhf.so.3'. Thank you very much in advance! Best regards, Andrejs |
From: Julian S. <js...@ac...> - 2014-05-21 13:44:22
|
This is most likely to be a soname problem, in that ucLibc's soname is different from the one used for the malloc/free intercepts. J |
From: Andrejs B. <sin...@gm...> - 2014-05-21 15:24:09
|
Hi Julian! Soname for malloc intercepts should be one defined in VG_Z_LIBC_SONAME? include/pub_tool_redir.h:244:# define VG_Z_LIBC_SONAME libcZdsoZa // libc.so* And soname for libuClibc-0.9.33.2.so is libc.so.0: [andrejs@arch ~]$ readelf -a ./dev_libs/lib/libuClibc-0.9.33.2.so | grep soname 0x0000000e (SONAME) Library soname: [libc.so.0] Best regards, Andrejs On 5/21/14, Julian Seward wrote: > > This is most likely to be a soname problem, in that ucLibc's soname > is different from the one used for the malloc/free intercepts. > > J > > |
From: Philippe W. <phi...@sk...> - 2014-05-21 18:45:14
|
On Wed, 2014-05-21 at 14:14 +0300, Andrejs Bogdanovs wrote: > On Linux/x86-64 leak was detected. > On Linux/ARM using --trace-redir=yes option I've found that > vgpreload_core-arm-linux.so and vgpreload_memcheck-arm-linux.so files > are not being read. > Using strace on Valgrind I found that vgpreload_memcheck-arm-linux.so > is accessed, but not used > (access("/usr/lib/valgrind/vgpreload_memcheck-arm-linux.so", R_OK) = 0). If Valgrind does not preload the above, then the redirections will not happen. Running valgrind -v -v -v -d -d -d env might give some lights on what does not work In particular, what is the value of the LD_PRELOAD env variable ? Philippe |
From: Andrejs B. <sin...@gm...> - 2014-05-22 06:45:27
|
On 5/21/14, Philippe Waroquiers wrote: > > If Valgrind does not preload the above, then the redirections will not > happen. > > Running > valgrind -v -v -v -d -d -d env > might give some lights on what does not work > In particular, what is the value of the LD_PRELOAD env variable ? > > Philippe > Hi Philippe! I tried command 'valgrind -v -v -v -d -d -d env' And got: LD_PRELOAD=/usr/lib/valgrind/vgpreload_core-arm-linux.so:/usr/lib/valgrind/vgpreload_memcheck-arm-linux.so Full log: http://pastebin.com/JmzjaRKp |
From: Julian S. <js...@ac...> - 2014-05-22 09:02:02
|
On 05/21/2014 05:24 PM, Andrejs Bogdanovs wrote: > Hi Julian! > > Soname for malloc intercepts should be one defined in VG_Z_LIBC_SONAME? > include/pub_tool_redir.h:244:# define VG_Z_LIBC_SONAME libcZdsoZa > // libc.so* > And soname for libuClibc-0.9.33.2.so is libc.so.0: > [andrejs@arch ~]$ readelf -a ./dev_libs/lib/libuClibc-0.9.33.2.so | grep soname > 0x0000000e (SONAME) Library soname: [libc.so.0] That soname looks ok, then. But from the log you posted later, it is clear that there is no malloc intercepting happening. For malloc intercepting to work, the files vgpreload_core-arm-linux.so and vgpreload_memcheck-amd64-linux.so need to be loaded into the process. Comparing your log with a run with a glibc based system, I see this Reading syms from [..]/vgpreload_core-amd64-linux.so Reading syms from [..]/vgpreload_memcheck-amd64-linux.so which is missing in your log. Does uCLibc implement LD_PRELOAD? I think that is how Valgrind causes those two objects to be loaded into the process. J |
From: Andrejs B. <sin...@gm...> - 2014-05-22 12:18:22
|
On 5/22/14, Julian Seward wrote: > > That soname looks ok, then. But from the log you posted > later, it is clear that there is no malloc intercepting happening. > > For malloc intercepting to work, the files vgpreload_core-arm-linux.so > and vgpreload_memcheck-amd64-linux.so need to be loaded into the process. > > Comparing your log with a run with a glibc based system, I see this > > Reading syms from [..]/vgpreload_core-amd64-linux.so > Reading syms from [..]/vgpreload_memcheck-amd64-linux.so > > which is missing in your log. > > Does uCLibc implement LD_PRELOAD? I think that is how Valgrind causes > those two objects to be loaded into the process. > > J > That may be a clue! Actually Valgrind sets LD_PRELOAD env variable to correct string, pointing to existing /usr/lib/valgrind/vgpreload_core-arm-linux.so and /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so, but uClibc may have been configured without LD_PRELOAD. I've found this in blog entry from NeoSkye: http://drivingtux.blogspot.com/2013/10/getting-valgrind-memcheck-to-work-with.html He wrote: "It turns out that valgrind actually sets the LD_PRELOAD environment variable early in execution, before loading the executable that is to be analyzed. This should instruct the runtime link loader to load the libraries in LD_PRELOAD, which are the vgpreload ones. Unfortunately, if your uclibc is configured without LD_PRELOAD (like ours was), the loader will ignore LD_PRELOAD and valgrind won't know that the vgpreload libraries were never loaded and malloc was not replaced. tl;dr uclibc must be configured with LD_PRELOAD in order for valgrind's memcheck to work. " Will try to do that. |
From: Andrejs B. <sin...@gm...> - 2014-05-22 14:06:51
|
On 5/22/14, Andrejs Bogdanovs wrote: > On 5/22/14, Julian Seward wrote: >> >> >> Does uCLibc implement LD_PRELOAD? I think that is how Valgrind causes >> those two objects to be loaded into the process. >> >> > > tl;dr uclibc must be configured with LD_PRELOAD in order for > valgrind's memcheck to work. " > > Will try to do that. > Recompiled uClibc configured with LD_PRELOAD, recompiled example program and Valgrind and it works now! Thank you guys! |