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
  • exec3.sub never f... Joel Ebel via Bug reports for the GNU Bourne Again SHell
    • Re: exec3.su... Martin D Kealey
      • Re: exec... Joel Ebel via Bug reports for the GNU Bourne Again SHell
        • Re: ... Chet Ramey
          • ... Joel Ebel via Bug reports for the GNU Bourne Again SHell
            • ... Joel Ebel via Bug reports for the GNU Bourne Again SHell
              • ... Chet Ramey
      • Re: exec... Lawrence Velázquez

Reply via email to