|
From: Mike M. <mi...@su...> - 2006-06-05 22:09:38
|
Yes, Nick, you've accurately summarized the problem. Too bad memcheck can't catch it, but you're right, the compiler did warn us, we just missed it. Thanks for the help. On 6/5/06, Nicholas Nethercote <nj...@cs...> wrote: > On Mon, 5 Jun 2006, Bob Rossi wrote: > > > OK, if we include > > #define _GNU_SOURCE /* ptsname_r() under Linux */ > > #include <sys/types.h> > > we get the prototype > > extern char *ptsname (int __fd) __attribute__ ((__nothrow__)); > > in the translation unit. > > > > If we include > > #include <sys/types.h> > > #define _GNU_SOURCE /* ptsname_r() under Linux */ > > we do not get the prototype in the translation unit. > > > > Then, we do this, > > char *name; > > if (!(name = ptsname(*masterfd))) > > > > In the case where the prototype is defined, it works fine and there > > is no crash. In the case where there is no prototype, we get this > > error. > > ../../../../cgdb/various/util/src/pseudo.c:304: warning: assignment > > makes pointer from integer without a cast > > > > That's because it thinks ptsname returns an int, and assigns it to a > > char*. This works when the sizeof(char*) == sizeof(int). However on this > > 64 amd machine, sizeof (char*)=8 sizeof (int)=4. This gives us the > > crash. > > > > Now, I'm wondering why valgrind reports no error on this circumstance. > > Would this be an improvement to memcheck? It took us quite some time to > > figure out the problem. > > Here's my guess as to what happened. The lower 4 bytes of the return > register (%rax, I think) got set to the return value. The upper 4 bytes got > left as whatever they were before; but importantly, those 4 bytes were > defined (ie. initialised). So the whole register is seen by Memcheck as > defined, because it is. You then used that value as a pointer, which was > bogus, but under Memcheck you got lucky/unlucky and the access through that > pointer hit addressable memory. Or possibly(?) Valgrind changes the way the > values go through the registers somewhat, and you luckily/unluckily ended up > with the correct value. > > The problem is that Memcheck does all its analysis at the byte-level. But > your problem here (assuming I've diagnosed it correctly) is that you > erroneously combined two 4-byte values into an 8-byte value which you then > used. As for whether Memcheck or another tool could detect this... it seems > like it would be hard, because multi-byte values get constructed from > single-byte or fewer-byte values all the time, and I can't think how to > distinguish the erroneous ones from the legitimate ones. > > So it's something that Memcheck can't detect. But the compiler can :) > > Nick > > > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users > |