|
From: Tom H. <to...@co...> - 2007-07-03 18:02:55
|
In message <118...@sk...>
"Alan M. Evans" <val...@al...> wrote:
> Please consider the following function:
>
> ssize_t nSendTo (int fd, const void *buf, size_t size, const char *host, port_t port) {
> struct hostent *hp;
> struct sockaddr_in to;
> #ifdef VERROR
> memset(&to,0,sizeof(to));
> #endif
> if (!(hp = gethostbyname(host)) &&
> !(hp = gethostbyaddr(host,strlen(host),AF_INET))) return -1;
> memcpy((char *)&to.sin_addr, hp->h_addr_list[0], hp->h_length);
> to.sin_port = htons((short)port);
> to.sin_family = AF_INET;
> #ifdef VERROR
> if (size==31) {
> char buf31[100]= {0};
> ssize_t sent;
> for (sent = 0; sent<100; ++sent) buf31[sent] = 0;
> printf("31 bytes\n");
> memcpy(&buf31[0],buf,31);
> sent = sendto(fd,&buf31[0],size,0,(struct sockaddr*)&to,sizeof(to));
> printf("sent=%i\n",sent);
> return sent;
> } else {
> printf("%i bytes\n",size);
> #endif
> return sendto(fd,buf,size,0,(struct sockaddr*)&to,sizeof(to));
> #ifdef VERROR
> }
> #endif
> }
>
> Without the VERROR sections, this function has served me well for years
> as a wrapper around sendto(). Now, valgrind is complaining about
> uninitialized bytes, but only the first time size==31:
>
> 22 bytes
> 12 bytes
> 15 bytes
> 54 bytes
> 12 bytes
> 22 bytes
> 12 bytes
> 15 bytes
> 33 bytes
> 31 bytes
> ==545== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
> ==545== at 0x34082CE283: __sendto_nocancel (in /lib64/libc-2.5.so)
> ==545== by 0x40899C: nSendTo (in /home/alan/bin/Neti)
> ==545== by 0x409745: nWriteTo (in /home/alan/bin/Neti)
> ==545== by 0x40BFA6: NetiSession::HandleWrite() (in /home/alan/bin/Neti)
> ==545== by 0x4113C7: Session::Check(SelectSet*) (in /home/alan/bin/Neti)
> ==545== by 0x40258E: CheckSession(Monad*, void*) (in /home/alan/bin/Neti)
> ==545== by 0x407D04: MonadList::ForEach(bool (*)(Monad*, void*), void*) (in /home/alan/bin/Neti)
> ==545== by 0x402CE0: Run(int, char**, char**, char*) (in /home/alan/bin/Neti)
> ==545== by 0x402DFC: main (in /home/alan/bin/Neti)
> ==545== Address 0x7FF00015C is on thread 1's stack
> sent=31
> 22 bytes
>
> I added the VERROR sections to be supremely sure that I could not
> possibly be passing any uninitialized bytes to sendto(). Did I miss
> something? Is valgrind misreporting? Or is glibc doing the wrong thing?
> How would I find out?
I don't understand what you think the VERROR sections are proving?
You carefuly zero fill 100 bytes, but then you copy in the 31 bytes
that you are actually going to send, and which presumably contain
the uninitialised data, hence undoing all the time you spent carefully
zero filling the local array.
The real problem presumably lies somewhere further up the call stack
where some uninitialised data was placed in the buffer that it is
being asked to send.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|