-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Open
Labels
bugA bug.A bug.
Description
Here is how you can reproduce:
$ rg --version | head -n 1
ripgrep 15.1.0 (rev 0a88cccd51)
$ grep --version | head -n 1
grep (GNU grep) 3.12.14-071a
$ mkdir -p `yes a/ | head -n $((32 * 1024)) | tr -d '\n'`
$ while cd $(yes a/ | head -n 1024 | tr -d '\n'); do :; done 2>/dev/null
$ pwd | tr '/' '\n' | wc -l
32771
$ echo hello | tee $(seq 100) > /dev/null
$ (cd $HOME && grep -r '^hello$' a | wc -l)
100
$ (cd $HOME && rg '^hello$' a)
rg: [trimmed long file name]: File name too long (os error 36)
It also seems that rg unnecessarily computes the current working
directory for each file processed. That becomes inefficient when
ENAMETOOLONG is returned and the openat (dirfd, "..", ...) to root
fallback has to be used. This can be seen below from the same directory:
$ pwd | tr '/' '\n' | wc -l
32771
$ time grep -r '^hello$' | wc -l
100
real 0m0.004s
user 0m0.001s
sys 0m0.005s
$ time rg --no-heading --line-number '^hello$' | wc -l
thread '<unknown>' (1405793) has overflowed its stack
fatal runtime error: stack overflow, aborting
100
real 2m59.479s
user 0m22.209s
sys 19m10.741s
I am not sure where the stack overflow is from. Probably a large item on
the stack, instead of deep recursion?
Also, during that test you can see that lots of memory is allocated
seemingly only for the file names:
$ (ulimit -v $(($(numfmt --from=iec 9G) / 1024)) && rg --no-heading --line-number '^hello$')
memory allocation of 63663 bytes failed
Aborted (core dumped) ( ulimit -v $(($(numfmt --from=iec 9G) / 1024)) && rg --no-heading --line-number '^hello$' )
Note that creating a directory this deep might depend on your file
system, and shells other than bash or zsh will almost certainly fail
to cd this deep.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugA bug.A bug.