Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Jun 1998 15:27:17 +0800
From:      Peter Wemm <peter@netplex.com.au>
To:        Terry Lambert <tlambert@primenet.com>
Cc:        joelh@gnu.org, fenner@parc.xerox.com, current@FreeBSD.ORG
Subject:   Re: Bogus errno twiddling by lstat... 
Message-ID:  <199806210727.PAA27276@spinner.netplex.com.au>
In-Reply-To: Your message of "Sat, 20 Jun 1998 20:02:49 GMT." <199806202002.NAA17957@usr02.primenet.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
Terry Lambert wrote:
> > If, however, you don't like our malloc's current implementation, and
> > think that errno should be saved and restored across a successful
> > call, and that the lost cycles would be worthwhile, then diffs would
> > be perfectly welcome, I'm sure.
> 
> Since the malloc.conf file is unnecessarily being looked for in the
> printf case (since ld.so already caused it to be looked for, and didn't
> find it), I think the redundant call to llok for it is certainly worth
> removing.

What redundant call??!?

pwroot@spinner[2:59pm]/tmp-115# cat xx.c
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>

main()
{
        struct stat sb;
        int saveerrno, saveerrno2;
        int ret;
        char *e;

        write(1, "1\n", 2);
        errno = 0;
        ret = lstat("foo", &sb);
        saveerrno = errno;

        write(1, "2\n", 2);
        e = strerror(saveerrno);
        saveerrno2 = errno;

        write(1, "3\n", 2);
        printf("lstat returned %d, errno = %d = %s\n", ret, saveerrno, e);

        write(1, "4\n", 2);
        printf("errno is now: %d, saveerrno2 = %d\n", errno, saveerrno2);
        write(1, "5\n", 2);
}
pwroot@spinner[2:59pm]/tmp-116# cc -o xx xx.c
pwroot@spinner[2:59pm]/tmp-117# ktrace ./xx
1
2
3
lstat returned 0, errno = 0 = Undefined error: 0
4
errno is now: 2, saveerrno2 = 0
5
pwroot@spinner[2:59pm]/tmp-118# l foo
0 -rw-r--r--  1 peter  wheel  0 Jun 18 16:52 foo

pwroot@spinner[2:59pm]/tmp-119# kdump | grep conf
 27160 xx       NAMI  "/etc/malloc.conf"

Quite clearly there is only one lookup..

pwroot@spinner[DING!]/tmp-120# kdump | more
 27160 ktrace   RET   ktrace 0
 27160 ktrace   CALL  execve(0xefbfd8e3,0xefbfd870,0xefbfd878)
 27160 ktrace   NAMI  "./xx"
 27160 xx       RET   execve 0
 27160 xx       CALL  open(0x10a0,0,0)
 27160 xx       NAMI  "/usr/libexec/ld.so"
 27160 xx       RET   open 3
[... trimmed ...]
 27160 xx       CALL  write(0x1,0x156a,0x2)
 27160 xx       GIO   fd 1 wrote 2 bytes
       "3
       "
 27160 xx       RET   write 2
 27160 xx       CALL  fstat(0x1,0xefbfd458)
 27160 xx       RET   fstat 0
 27160 xx       CALL  readlink(0x2006e8e2,0xefbfd454,0x3f)
 27160 xx       NAMI  "/etc/malloc.conf"
 27160 xx       RET   readlink -1 errno 2 No such file or directory
 27160 xx       CALL  mmap(0,0x1000,0x3,0x1002,0xffffffff,0,0,0)
 27160 xx       RET   mmap 536952832/0x20014000
 27160 xx       CALL  break(0x7000)
 27160 xx       RET   break 0
 27160 xx       CALL  break(0x17000)
 27160 xx       RET   break 0
 27160 xx       CALL  ioctl(0x1,TIOCGETA,0xefbfd494)
 27160 xx       RET   ioctl 0
 27160 xx       CALL  write(0x1,0x7000,0x31)
 27160 xx       GIO   fd 1 wrote 49 bytes
       "lstat returned 0, errno = 0 = Undefined error: 0
       "
 27160 xx       RET   write 49/0x31
 27160 xx       CALL  write(0x1,0x1591,0x2)
 27160 xx       GIO   fd 1 wrote 2 bytes
       "4
       "
 27160 xx       RET   write 2
[..]

Now, I don't see any redundant calls to readlink("/etc/malloc.conf"),
and no calls to malloc() by ld.so (ld.so has it's own malloc that it uses 
during startup and switches to the libc malloc after it's got hold of 
libc.so.*).

Also, since this is freebsd-current, so I assume you're talking about 
-current.

> I would also not save and restore state, except in anticipation of
> an error.  If the cached value were being used (as it should be),
> then the malloc.conf reference shouldn't have been tried (and not being
> tried, the errno would not be in danger of being blown).

malloc_init() and the readlink are only called once.  I think you're
imagining this.

So, first you blame lstat() with a badly flawed test program as "evidence".
When challenged on it, you say "I knew that" and then claim that ld.so is
calling malloc. At the same time you claim that this is therefore violating
some ansi requirement for functions to not change errno, which somebody
else has pointed out that the specs say the opposite.  When confronted with
that, you then come up with malloc not caching it's readlink() of
malloc.conf, which is clearly false and verifiable.

What next?

malloc() has been adjusted to preserve errno across the readlink(), so I 
suggest you leave it at that rather than digging youself an even deeper 
hole. :-)

Cheers,
-Peter



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806210727.PAA27276>