You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
resolve_test_location forks a subshell per test for a line number the per-file scan already read (1.08ms per test) #1346
Every test forks a subshell to read a line number, and the per-file scan already read it.
Measured
$(shopt -s extdebug; declare -F fn) costs 1.08 ms per call on macOS arm64, bash 3.2.57, best of 3 over 2000 calls. It runs once per test, unconditionally. Over this suite's ~2491 tests that is roughly 2.7 seconds of a sequential run.
A bare $( ) costs 1.1 to 1.4 ms on the same box. Worth noting: perf-fork-budget.md records 0.46 ms, which predates arm64. The old figure should not be reused for estimates.
It is called from export_test_identity (src/runner/context.sh:65) for every test, to build <file>:<line> for a failure message most tests never emit.
Meanwhile bashunit::runner::functions_for_script (src/runner/discovery.sh:340-380) already runs $( shopt -s extdebug; declare -F $all_fn_names )once per file, reads <name> <line> <file> for every function in it, sorts by definition line, and then throws the line numbers away.
Expected behavior
Cache name to line in that existing per-file pass and make the per-test lookup a scan of it. Bash 3 parallel arrays, following _BASHUNIT_TAGS_MAP_FNS / _BASHUNIT_TAGS_MAP_TAGS in src/helper/tags.sh. Keep the current $( ) as the fallback for a name that is not in the map, so nothing regresses for a function defined some other way.
extdebug must stay inside the subshell (#808). Verify against a data-provider test, where one function runs for many rows, and against an interpolated title.
Hazard for any rewrite here: extdebug clears set -E and set -T on Bash 5.2+
Worth knowing before touching this path. shopt -s extdebug turns on errtrace and functrace everywhere, but turning it off is not symmetric:
Build
after shopt -u extdebug
3.00.22, 3.2.57, 4.0.44
errtrace/functrace stay on
5.2.37, 5.3.15
both off, even if they were on beforehand
So on 5.2 and above, disabling extdebug silently turns off set -E and set -T. That is the concrete shape of the #808 hazard, and it differs across the supported range, which the comment at src/runner/context.sh:84-88 does not say.
Consequence for this issue: keeping extdebug inside a subshell is not only about not clobbering caller state, it is also what stops --strict error tracing being switched off underneath the run on newer shells. A rewrite that drops the subshell has to save and restore errtrace/functrace explicitly. Tracked in #1354.
Measured saving, for scale
Removing this subshell measured 0.27 to 0.39 ms/test on Linux and 0.62 ms on macOS. Doing it the Bash 3.0-safe way beat rewriting it with Bash 5.3's ${ cmd; }: the gate-free pair of this plus #1348 saved 0.64 ms/test on 5.3, where the fully gated version of the same sites saved 0.60 ms. So no version gate is wanted here.
Activity
Chemaclass commentedon Sep 9, 2026
Hazard for any rewrite here:
extdebugclearsset -Eandset -Ton Bash 5.2+Worth knowing before touching this path.
shopt -s extdebugturns onerrtraceandfunctraceeverywhere, but turning it off is not symmetric:shopt -u extdebugerrtrace/functracestay onSo on 5.2 and above, disabling
extdebugsilently turns offset -Eandset -T. That is the concrete shape of the #808 hazard, and it differs across the supported range, which the comment atsrc/runner/context.sh:84-88does not say.Consequence for this issue: keeping
extdebuginside a subshell is not only about not clobbering caller state, it is also what stops--stricterror tracing being switched off underneath the run on newer shells. A rewrite that drops the subshell has to save and restoreerrtrace/functraceexplicitly. Tracked in #1354.Measured saving, for scale
Removing this subshell measured 0.27 to 0.39 ms/test on Linux and 0.62 ms on macOS. Doing it the Bash 3.0-safe way beat rewriting it with Bash 5.3's
${ cmd; }: the gate-free pair of this plus #1348 saved 0.64 ms/test on 5.3, where the fully gated version of the same sites saved 0.60 ms. So no version gate is wanted here.Chemaclass commentedon Sep 9, 2026
Done in #1356 (merged).