Sun 02 Aug 2009 03:06:21 PM UTC, comment #8:
the version is 4.5.4
I'm sorry but I can't create a reproducible example but mine
What I've noted while trying was that it /seems/ to have something to do with disk cache (as it stops failing after a couple of times but it fails again if you echo 3 > /p/s/vm/drop_caches) AND that executing a similar script on /usr/lib/, executing ldd on a subset of .so, DID NOT fail, so that it could be related to the fact that, when my script runs, it modifies the files it matches (by vacuuming sqlite databases)
just speculations, though
|
Sun 02 Aug 2009 01:02:37 PM UTC, comment #7:
federico, please indicate what version of find you are using. Also, can you proproduce the problem with a script which creates a suitable example? (I don't have your ~/.mozilla directory here!)
I'm suspicious of this part of the system call trace:
--- SIGCHLD (Child exited) @ 0 (0) ---
newfstatat(7, "cookies.sqlite-journal", 0x131ab00, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
lstat("cookies.sqlite-journal", 0x7fff7880b330) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY) = 6
... because I'm not convinced that fd 7 corresponds to the working directory, so the lstat could fail or return the wrong information.
My guess is that the lstat call is inside symlink_loop() which is called at line 462 of ftsfind.c (i.e. for the FTS_NS case).
|
Wed 29 Jul 2009 10:27:44 AM UTC, comment #6:
please check out the attachments
the bash script is the one that fails. the log is the strace log
|
Thu 16 Jul 2009 12:38:20 PM UTC, comment #5:
Both examples now avoid assertion failures on cygwin with stock findutils 4.5.4, so I'm closing the report as fixed:
$ mkdir example
$ ln -s /nowhere example/n
$ find -L example
example
example/n
$ rm example/n
$ ln -s //nowhere example/n
$ find -L example
example
example/n
$ rm example/n
$ ln -s loop example/loop
$ find -L example
example
find: `example/loop': Too many levels of symbolic links
$
|
Sat 07 Mar 2009 04:26:36 PM UTC, comment #4:
Check-in b445af98c22cd2d13673e2699a77ab728a7073b0 changed this code a bit, as did 0b1acd3358466b02f32baf9423665113dc933492.
Is the problem still reproducible from the git master branch (currently at 89da37ea3b25fd7c95d831a6f319068c99c7406b)?
|
Sat 17 Jan 2009 07:22:35 PM UTC, comment #3:
I would have expected ent->fts_info == FTS_SLNONE for the loop case. That implies that the comment on line 472 could well be misleading.
I modified fts.c to always set d_type to DT_UNKNOWN but was not able to demonstrate a problem.
|
Sun 11 Jan 2009 03:31:59 AM UTC, comment #2:
The assertion failure can also be reproduced with a loop:
$ mkdir example
$ ln -s loop example/loop
$ find -L example
example
find: `example/loop': Too many levels of symbolic links
assertion "state.type != 0" failed: file "ftsfind.c", line 475, function: consider_visiting
Aborted (core dumped)
As I see it, this only depends on having a system with d_type support, but on a file system where readdir returns DT_UNKNOWN on at least dangling symlinks. Therefore, I think that it should be possible to find a file system under Linux that can reproduce this failure, rather than relying on the cygwin-specific behavior in stat'ing a dangling symlink to "//nowhere".
|
Sun 11 Jan 2009 01:58:54 AM UTC, comment #1:
More info:
The bug first surfaced in commit acb82fe, Nov 30 2008, at the point when Jim provided a patch to gnulib fts to do fewer stat's when d_type is reliable.
The problem starts when readdir recognizes that it is too expensive to decide what the type of a broken symlink is (at least on cygwin), and returns DT_UNKNOWN (defined as 0). Next, fts calls fts_stat, which fails because the symlink is broken, but on cygwin, a symlink to "//nowhere" fails with the nonstandard errno==ENOSHARE rather than the more typical ENOENT, so no lstat is attempted to see if the file might be a dangling symlink.
So the bug might be in fts.c, line 1540, for not recognizing all cases of bad symlinks (even ignoring cygwin's nonstandard ENOSHARE, what happens for a looping symlink that returns ELOOP?). Would a readlink() be better than lstat() to determine that a symlink exists but can't be followed?
|
Sat 10 Jan 2009 11:44:14 PM UTC, original submission:
On systems where d_type is valid, find is triggering an assertion (I'm not sure if this assertion also requires that // be distinct from /, in which case the assertion may be specific to cygwin 1.7, since earlier cygwin lack d_type and other systems don't have distinct //):
$ mkdir example
$ ln -s /nowhere example/n
$ find -L example
example
example/n
but the following asserts:
$ rm example/n
$ ln -s //nowhere example/n
$ find -L example
example
assertion "state.type != 0" failed: file
"/usr/src/findutils-4.5.3-1/src/findutils-4.5.3/find/ftsfind.c", line 475,
function: consider_visiting
Aborted (core dumped)
Corinna Vinschen provided this analysis:
The assertion is basically
if (ent->fts_info == FTS_NSOK || ent->fts_info == FTS_NS)
assert (state.type != 0);
state.type is set in the calling function find() like this:
while ( (ent=fts_read(p)) != NULL )
{
state.have_type = !!ent->fts_statp->st_mode;
state.type = state.have_type ? ent->fts_statp->st_mode : 0;
}
which is a bug, AFAICS. The reason is that per the fts_read man page
the value of ent->fts_statp is undefined if ent->fts_info is FTS_NSOK
or FTS_NS. So the values of state.have_type and consequentially
state.type are undefined as well and the above assertion makes no sense.
|