Christopher Layne wrote: > On Sat, Aug 04, 2007 at 07:21:46PM -0700, Scott Lamb wrote: >> Christopher Layne wrote: >>> On Thu, Jul 19, 2007 at 01:14:58PM -0700, Scott Lamb wrote: >>>> When I use "valgrind --tool=memcheck" on a libevent-based program, it >>>> gives the following complaint: >>>> >>>> ==15442== Conditional jump or move depends on uninitialised value(s) >>>> ==15442== at 0x4C0F2D3: event_add (event.c:632) >>>> ==15442== by 0x405EE4: main_loop (net.c:356) >>>> ==15442== by 0x411853: main (tincd.c:329) >>>> >>>> Here's the relevant portion of event.c: >>>> >>>> 632 if ((ev->ev_flags & EVLIST_ACTIVE) && >>>> 633 (ev->ev_res & EV_TIMEOUT)) { >>>> >>>> I've looked through the libevent code and verified that ev_res is always >>>> initialized when (ev_flags & EVLIST_ACTIVE) is true, so there's no real >>>> bug here. >>> You wouldn't happen to have a copy of the code or atleast code segment >>> which was tickling this would you? >> Yes, I also think it was really an uninitialized area being read from, >> but not one to worry about. >> >> As I'm sure you know, && indicates lazy evaluation - the second half >> doesn't get evaluated if the first half is false. But this was an > > Right. However my point (in regards to splitting the conditional) was due > to the ambiguity of multiple options when valgrind complains about a single > line which has more than one possibility: > > 1. ev_flags is uninitialised (but when masked, result just happens to be > true). > + ev_res is uninitialised, valgrind complains about line 632. > 2. ev_flags is uninitialised, mask results false, ev_res never touched, > valgrind > complains about line 632. > 3. ev_flags is initialised, mask results true, ev_res is uninitialised, > valgrind > complains about line 632. > 4. ev_flags is initialised, mask results false, ev_res never touched. > > See where I was going with that now? The code may indicate all day that > ev_flags should always be initialised before even hitting event_add, but that > doesn't stop other things from happening, like half your DRAM being 0x0, > your CPU melting, straight up bugs, etc. I'm sure you get the drift.
Well, splitting the conditional won't help - line numbers in optimized builds don't really make sense anyway; it jumps all over the place. This only happens on optimized 64-bit builds (in which the optimization makes sense because ev_flags and ev_res are in the same word). If you have such a machine, you can reproduce it with this trivial program: [EMAIL PROTECTED] ~]$ cat test.c #include <stdlib.h> #include <event.h> int main(int argc, char **argv) { struct event *ev; ev = malloc(sizeof(struct event)); if (ev == NULL) abort(); ev->ev_flags = 0; if ((ev->ev_flags & EVLIST_ACTIVE) && (ev->ev_res & EV_TIMEOUT)) { abort(); } return 0; } [EMAIL PROTECTED] ~]$ uname -a Linux rosalyn.zorg.slamb.org 2.6.18-8.el5xen #1 SMP Thu Mar 15 19:56:43 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux [EMAIL PROTECTED] ~]$ gcc --version gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [EMAIL PROTECTED] ~]$ valgrind --version valgrind-3.2.1 [EMAIL PROTECTED] ~]$ gcc -Wall -O2 test.c -o test [EMAIL PROTECTED] ~]$ valgrind --tool=memcheck ./test ...boilerplate... ==24325== Conditional jump or move depends on uninitialised value(s) ==24325== at 0x400504: main (in /home/slamb/test) ... [EMAIL PROTECTED] ~]$ gcc -Wall test.c -o test [EMAIL PROTECTED] ~]$ valgrind --tool=memcheck ./test ...boilerplate only... You'll notice the same thing does not happen on a 32-bit machine. [EMAIL PROTECTED] ~]$ uname -a Linux spiff-centos5 2.6.23-rc1 #8 SMP Fri Jul 27 21:02:53 PDT 2007 i686 i686 i386 GNU/Linux [EMAIL PROTECTED] ~]$ gcc --version gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [EMAIL PROTECTED] ~]$ valgrind --version valgrind-3.2.1 [EMAIL PROTECTED] ~]$ gcc -Wall -O2 test.c -o test [EMAIL PROTECTED] ~]$ valgrind --tool=memcheck ./test ...boilerplate only... [EMAIL PROTECTED] ~]$ gcc -Wall test.c -o test [EMAIL PROTECTED] ~]$ valgrind --tool=memcheck ./test ...boilerplate only... > I still do not believe this to be valgrind's fault. Valgrind surely knows > exactly > what is going on with registers as it is emulating them. > (http://valgrind.org/docs/manual/mc-tech-docs.html#mc-tech-docs.storage) It's not quite sophisticated enough to realize that despite boolean operations before performed on junk, they can never actually influence the result. > I basically was just curious how you got it to come about, because I also > tried various optimization combinations of both libevent (ev_res not init'd) > and test code to try and see this and was unsuccessful in doing so. Valgrind > never indicated an error. Now if I explicitly did not pass the event struct > to event_set() before hand, then yes errors were visible. But for the most > part, depending on how much trash was in memory at the time, they wouldn't > make it past the first assert(). The issue though is that in your case, it > might not have even been on the stack, or an entirely different scenario - > which is what got me asking in the first place. I just think it's unsafe > to write things off as "valgrind noise" when said noise could actually > indicate a "should not happen." _______________________________________________ Libevent-users mailing list Libevent-users@monkey.org http://monkey.org/mailman/listinfo/libevent-users