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. > optimized build of libevent, and I believe gcc decided that there were > no side effects from evaluating (ev->ev_res & EV_TIMEOUT) early and that > it would be faster to do the reads simultaneously, so it did so. gcc was > almost right about "no side effects" - I don't blame it for not knowing > that valgrind would complain about undefined values. > > valgrind is complaining about an intermediate value. Essentially, the > code did "0 && junk". The *result* is correctly defined as 0. valgrind's > just not quite smart enough to realize that though junk was loaded into > a register, it didn't actually affect the result of a comparison or any > other operation. > > Scott 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) 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." -cl _______________________________________________ Libevent-users mailing list Libevent-users@monkey.org http://monkey.org/mailman/listinfo/libevent-users