[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: RA-DAV tests acting *very* strangely.

From: Kirby C. Bohling <kbohling_at_birddog.com>
Date: 2003-03-10 18:59:04 CET

On Mon, 2003-03-10 at 00:21, cmpilato@collab.net wrote:

> Then, I reverted that temporary change and debugged my client again to
> see what happened when my weird bug showed up:
>
> ### "."
> (gdb) p *dir->dirstruct
> $1 = {fd = 4, data = 0x80896a0 "çh\b", allocation = 4096, size = 64,
> offset = 16, filepos = 1, lock = {__m_reserved = 0, __m_count = 0,
> __m_owner = 0x0, __m_kind = 0, __m_lock = {__status = 0,
> __spinlock = 0}}}
> ### ".."
> (gdb) p *dir->dirstruct
> $3 = {fd = 4, data = 0x80896a0 "çh\b", allocation = 4096, size = 64,
> offset = 32, filepos = 2, lock = {__m_reserved = 0, __m_count = 0,
> __m_owner = 0x0, __m_kind = 0, __m_lock = {__status = 0,
> __spinlock = 0}}}
> ### "iota"
> (gdb) p *dir->dirstruct
> $5 = {fd = 4, data = 0x80896a0 "çh\b", allocation = 4096, size = 64,
> offset = 48, filepos = 3, lock = {__m_reserved = 0, __m_count = 0,
> __m_owner = 0x0, __m_kind = 0, __m_lock = {__status = 0,
> __spinlock = 0}}}
> ### "A"
> (gdb) p *dir->dirstruct
> $7 = {fd = 4, data = 0x80896a0 "çh\b", allocation = 4096, size = 64,
> offset = 64, filepos = 4, lock = {__m_reserved = 0, __m_count = 0,
> __m_owner = 0x0, __m_kind = 0, __m_lock = {__status = 0,
> __spinlock = 0}}}
> ### "A" (again)
> (gdb) p *dir->dirstruct
> $10 = {fd = 4, data = 0x80896a0 "èh\b", allocation = 4096, size = 16,
> offset = 16, filepos = 5, lock = {__m_reserved = 0, __m_count = 0,
> __m_owner = 0x0, __m_kind = 0, __m_lock = {__status = 0,
> __spinlock = 0}}}
>
> Whoa! I noticed almost immediately that on that second "A" that is
> returned, the *dir->dirstruct->data member had suddenly changed (and
> the offset member was no longer incrementing by 16 like it had been).

I'm kinda curious about they 0x80896a0 changes it's interpretation from
run to run, and from the previous print outs, and the last one. That's
weird.

The size=64 and offset incrementing by 16 looks right. readdir_r calls
getdent(), which caches up to allocation size directory entries. So
when you first get there it appears there are only 4 files. If you read
the glibc code for readdir_r, when (offset <= size) you just grab the
next entry from the cache. So when size=64 and offset=64 then you are
refreshing the cache (there now appear to be 5 files). The new cache is
16 bytes long, and has only one entry in it. Sure seems like your doing
this:

opendir()
readdir()
creat() /* screws up the offsets and cache */
readdir()
readdir()
readdir()
readdir()
closedir()

I've read the manual.texi for glibc covering readdir_r/readdir_r64, and
didn't see anything that would lead me to believe that creating and
deleting a file would be safe. Not sure what doc's your reading.
readdir_r has no man page on my RH 7.2 machine.

I couldn't follow the code once you got into the getdent() case in
glibc/kernel (not smart enough, and didn't have time to investigate).
I'm not sure how it works. I'd be reasonable curious what you get if
you set a breakpoint just before the second "A" file gets read, and run
a program that has just the:

opendir()
while( !readdir_r() )
{
        printf( filename );
}
closedir();

To see how many entries it believes are in there now, and print out the
structure that has size/offset to see how many it attempts to read at
once.

That would miss files that only have an open file count, and don't exist
to anyone but the one process. When you unlink the temporary, did it
get closed? Otherwise you'd have a file that only the subversion
process can see (what's this have to do with python though, that doesn't
fit the facts yet).

the readdir_r has some logic for skipping deleted files, I wonder if
creating and deleting the files is screwing up the offsets.

<snip>

> But apparently this isn't working out too well on my machine.
>
> Does anyone have any reason to believe that this would not be safe,
> and have any ideas why running Subversion via a Python popen3() call
> would cause some problem to occur which does not run Subversion is run
> directly from the shell? Inquiring (and admittedly boggled) minds
> wanna know.
>

Hmmm, the only thing about popen3 I can see, is your environment might
be tweaked a bit. Not sure how python's works, but the standard popen
says you get passed to the "/bin/sh -c" command line, so things like
LD_PRELOAD, the enviroment variable that puts glibc into compatibility
mode so your not calling the same readdir_r()/getdents() pair might be
mildly different. Not sure how you could have problems with it, but
possible LFS vs. non-LFS in python versus not in python?

Possibly getting an strace in extremely verbose mode would be more
informative both under python, and not under python to see if there are
significant differences in libraries loading, and the series of syscalls
around this area.

Weird part is why isn't anyone else seeing it? That doesn't make sense
either.

                Kirby

> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org
>
>

-- 
Real Programmers view electronic multimedia files with a hex editor.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Mar 10 19:00:47 2003

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.