|
From: Peter S. <sne...@no...> - 2003-11-12 16:17:12
|
I'm getting a warning about an "uninitialized value" when I run valgrind on a program which uses "gethostbyname_r", on a RH8.0 system. I was using valgrind-20031012, but I've just upgraded to 2.0.0 and see the same thing. The output is: ==11556== Startup, with flags: ==11556== --suppressions=/usr/local/lib/valgrind/default.supp ==11556== -v ==11556== --num-callers=12 ... ==11556== Conditional jump or move depends on uninitialised value(s) ==11556== at 0x40008A4A: elf_dynamic_do_rela.8 (in /lib/ld-2.2.93.so) ==11556== by 0x40008CBA: _dl_relocate_object_internal (in /lib/ld-2.2.93.so) ==11556== by 0x42109863: dl_open_worker (in /lib/i686/libc-2.2.93.so) ==11556== by 0x4000A425: _dl_catch_error_internal (in /lib/ld-2.2.93.so) ==11556== by 0x421092BE: __GI__dl_open (in /lib/i686/libc-2.2.93.so) ==11556== by 0x4210A6B9: do_dlopen (in /lib/i686/libc-2.2.93.so) ==11556== by 0x4000A425: _dl_catch_error_internal (in /lib/ld-2.2.93.so) ==11556== by 0x4210A587: __libc_dlopen (in /lib/i686/libc-2.2.93.so) ==11556== by 0x420EA677: __nss_lookup_function (in /lib/i686/libc-2.2.93.so) ==11556== by 0x420EB1DA: __nss_lookup (in /lib/i686/libc-2.2.93.so) ==11556== by 0x420EC3B8: __GI___nss_hosts_lookup (in /lib/i686/libc-2.2.93.so) ==11556== by 0x420EE174: gethostbyname_r@@GLIBC_2.1.2 (in /lib/i686/libc-2.2. My code calls gethostbyname_r, but even when I initialized *all* the parameters, valgrind still reported this error. Should this be supressed, or is it really telling me something? -- Peter Snelling |
|
From: John R.
|
> ==11556== Conditional jump or move depends on uninitialised value(s)
> ==11556== at 0x40008A4A: elf_dynamic_do_rela.8 (in /lib/ld-2.2.93.so)
> ==11556== by 0x40008CBA: _dl_relocate_object_internal (in
> /lib/ld-2.2.93.so)
Glibc/elf uses some uninitialized values that happen to work because
the same uninit value is used twice and "cancels." This reveals
an opportunity for enhancement in memcheck, and sleazy code in glibc.
Look at this code for elf_dynamic_do_rela() in elf/dynamic-link.h:
-----
struct { ElfW(Addr) start, size; int lazy; } ranges[2]; \
ranges[0].lazy = 0; \
ranges[0].size = ranges[1].size = 0; \
ranges[0].start = 0; \
-----
and notice that ranges[1].lazy and .start are not initialized. Later:
-----
for (ranges_index = 0; ranges_index < 2; ++ranges_index) \
elf_dynamic_do_##reloc ((map), \
ranges[ranges_index].start, \
ranges[ranges_index].size, \
ranges[ranges_index].lazy); \
-----
and for elf_dynamic_do_rela in elf/do-rel.h:
-----
const ElfW(Rel) *r = (const void *) reladdr; ## .start
const ElfW(Rel) *end = (const void *) (reladdr + relsize); ## .start + .size
-----
and later in elf_dynamic_do_rela:
-----
for (; r < end; ++r)
-----
Valgrind notices that "r < end" depends on reladdr, and reladdr is
uninitialized. The C standard says that therefore _any_ behavior
is allowed: infinite loop, wrong answer, random answer, "correct"
answer. It just happens that gcc-compiled code works.
Several years ago, the maintainer of glibc boasted of pride in this code.
All executables that are supervised by ld-linux.so.2 suffer this, but
vagrind [memcheck] usually does not notice because it happens before
any LD_PRELOAD module gets control. Memcheck does see the problem
on some subsequent dynamic loads, as here.
--
|