fix(test): deterministic ceiling for the GLR merge-cap regression guard
perl_glr_deep_parse_recursion_capped wandered between 2s and 218s for the IDENTICAL input: past the merge cap the ambiguity-exploded GLR parse grinds at an environment-dependent rate (allocator/scheduler state in the forked child), and the test paid for however long that grind ran. It was the critical path of every parallel run and the dominant chunk of the sequential one. The guard's actual signal is the CRASH, not the grind: when CBM_TS_STACK_MERGE_MAX_DEPTH regresses, the recursive stack-merge overflows within the first second at this depth (same profile as the sibling pre-guard probe, rc=139 in under a second). The forked child now arms a 10s alarm whose handler exits cleanly — a real SIGSEGV/SIGBUS still terminates the child by signal first and stays visible to WIFSIGNALED, so the RED path is untouched; only the pointless remainder of the grind is skipped. Windows (in-process branch) is unchanged. Suite b: 13s across three consecutive runs (was 2-218s). Full parallel run: 97s wall, 6,374 passed / 0 failed / 1 skipped, union guard clean — vs 351s sequential on the same machine (3.6x). Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
@@ -441,6 +441,15 @@ static bool so_extract_crashes(const char *content, CBMLanguage lang, const char
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
/* Child-side alarm handler: a clean exit on the deadline — never reached on
|
||||
* a crash (SIGSEGV/SIGBUS terminate the child first and stay visible). */
|
||||
static void so_parse_alarm_exit(int sig) {
|
||||
(void)sig;
|
||||
_exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Parse `content` with tree-sitter DIRECTLY in a forked child — bypassing
|
||||
* cbm_extract_file's Perl pre-parse nesting guard — returning true if the child
|
||||
* died by signal. This is the crash-isolating regression for the vendored GLR
|
||||
@@ -471,6 +480,15 @@ static bool so_parse_crashes(const char *content, CBMLanguage lang) {
|
||||
return false;
|
||||
}
|
||||
if (pid == 0) {
|
||||
/* Deterministic ceiling: past the merge cap the ambiguity-exploded
|
||||
* GLR parse GRINDS (minutes, environment-dependent — measured 2s to
|
||||
* 218s for the identical input). The guard's signal is the CRASH,
|
||||
* which fires within the first seconds when the recursion cap
|
||||
* regresses — so a clean exit after 10s proves the cap held without
|
||||
* paying for the rest of the grind. SIGSEGV/SIGBUS still report as
|
||||
* WIFSIGNALED; the alarm handler exits cleanly, never masking them. */
|
||||
signal(SIGALRM, so_parse_alarm_exit);
|
||||
alarm(10);
|
||||
TSParser *parser = ts_parser_new();
|
||||
if (parser) {
|
||||
ts_parser_set_language(parser, ts_lang);
|
||||
|
||||
Reference in New Issue
Block a user