On Sat, Jun 7, 2025 at 12:55 PM Martin D Kealey <mar...@kurahaupo.gen.nz> wrote:
> Hi Joel > > > On Sun, 8 Jun 2025 at 00:08, Joel Ebel via Bug reports for the GNU Bourne > Again SHell <bug-bash@gnu.org> wrote: > >> This is mostly an FYI, as I don't think our ridiculous environment needs >> to >> be supported, but the E2BIG test in exec3.sub never finishes in our >> testing >> environment due to ARG_MAX being set to a huge number. I'm adding a patch >> to limit the test to 2 MB ARG_MAX, though I don't know what the best value >> limit might be generally. I wanted to share it in case it was useful. > > > I'm guessing this is blocking your CI/CD pipeline? > Technically this test will finish, but you'd need to be *much* more > patient. > > The problem with using a small fake value for argmax is that the rest of > the test won't elicit E2BIG, which basically constitutes a test failure. > > I would rather fix the test so that it still runs correctly, but in a > reasonable time. > > As a baseline, running the current test with a 2 MiB limit over-fills the > environment by about 15%, and takes about 19 seconds to run on my machine. > If I run it with a 16 MiB limit, the overfill is negligible, and it takes > about 85 seconds to run on my machine. > If I were to run it with a 2 GiB limit, by linear extrapolation I would > expect it to take *at least 4 hours*, but possibly much longer, as there > is a quadratic element to the timing that is only measurable above about > 500 MiB. (See below) > > For a start, *just* lifting the range expansion out of the loop reduces > the time from 4 hours to 5 minutes. > However that's still a long wait, and we can do *much* better: > (a) avoid all range expansions and > (b) avoid a linear loop > > The simplest (and fastest) would be more like this: > > $ git diff tests > diff --git a/tests/exec3.sub b/tests/exec3.sub > index c8875bef4..01ced690f 100644 > --- a/tests/exec3.sub > +++ b/tests/exec3.sub > @@ -62,10 +62,7 @@ argmax=$(getconf ARG_MAX 2>/dev/null) > if (( argmax <= 0 )); then > argmax=1048576 > fi > -v=$(echo {1..250000}) > -while (( ${#v} < $argmax )); do > - v+=$(echo {250001..350000}) > -done > +printf -v v %.*u "$argmax" 0 > export v > exec ${THIS_SH} </dev/null > EOF > $ #endpatch > > (Running this with a 2 GiB limit takes 11.9 seconds on my machine, or at > least 1200 times faster than the current version.) > > However there might be some objections to relying on the printf built-in, > since in theory Bash could be built without it, in which case I suggest: > > $ git diff tests > diff --git a/tests/exec3.sub b/tests/exec3.sub > index c8875bef4..af43e09bf 100644 > --- a/tests/exec3.sub > +++ b/tests/exec3.sub > @@ -62,9 +62,11 @@ argmax=$(getconf ARG_MAX 2>/dev/null) > if (( argmax <= 0 )); then > argmax=1048576 > fi > -v=$(echo {1..250000}) > -while (( ${#v} < $argmax )); do > - v+=$(echo {250001..350000}) > +for (( m = n = argmax / ${#argmax} + 1 ; o = m & m-1 ; m = o )) do :; done > +v= > +for ((; m ; m >>= 1 )) do > + v+=$v > + (( n & m )) && v+=$argmax > done > export v > exec ${THIS_SH} </dev/null > $ #endpatch > > (Running this with a 2 GiB limit takes 13.6 seconds on my machine, or > about 14% slower than my printf version, but still more than 1000 times > faster than the current version. Running this with a 1 GiB limit takes 5.3 > seconds on my machine, so the quadratic timing is evident. Running it with > a 2 MiB limit takes 36 milliseconds on my machine.) > > -Martin > I appreciate the effort to make the test run more efficiently and faster, and that's probably a good idea, but I think there still needs to be a way out. I didn't express just how huge our ARG_MAX is. It's 2^62 or 4.6 exabytes. I don't think there's any way to reasonably expect that this test will complete with that environment, so I still need a way of skipping the test. I don't know if that's something we'd want to bake directly into exec3.sub (your ARG_MAX is ridiculous. skipping test) or if we should just keep patching it ourselves internally. Our test runs `make check` but only checks the return code. I have to manually read the output if I want to verify the correctness, so a diff in the error text, which I would expect to see, isn't going to block a build. Joel