Skip to content

A signal is retried; a failed check is not - #116

Merged
bravemaster3 merged 1 commit into
mainfrom
ci/a-signal-is-retried-a-verdict-is-not
Sep 12, 2026
Merged

bravemaster3 merged 1 commit into
mainfrom
ci/a-signal-is-retried-a-verdict-is-not

Conversation

@bravemaster3

Copy link
Copy Markdown
Owner

The QGIS 4.2 (real PyQGIS) job exited 139 on the merge of #115 — a documentation-only PR,
one markdown file. The same commit's own PR run had passed that job minutes earlier, and
a rerun of the merge commit passed
with nothing changed. The repository's code is not the variable.

It is the second occurrence. Both on the 4.2 image only, never ltr; both at a different
place
(once corrupted size vs. prev_size, once a clean Segmentation fault (core dumped)
immediately after the Rule-based section header, before its first check printed); both passing on
a rerun.

Not diagnosed, and not pretended otherwise

The obvious suspect is the borrowed-pointer trap already recorded in notes_for_future.md: a
symbol taken out of a rule tree and read after its temporary is gone segfaults exactly like this.
So the harness's own rule builder was run 300 times on 4.2 with gc.collect() between every
round — plain, ELSE, scale-limited and nested rule trees, built, read, applied back and read again.
No crash. An earlier occurrence survived 9 full runs under GC stress.

There is no fix to make yet. Two things that help anyway:

1. The next crash will say where it was

faulthandler.enable() in test_real_qgis.py, test_roundtrip_matrix.py and
coverage_report.py. The standing complaint about this class of failure — written down twice in
the repo — is that it arrives as nothing but Segmentation fault (core dumped) and leaves you
guessing which of 349 checks was running. Now the signal handler prints the Python stack.

2. CI distinguishes a crash from a verdict

exit code what happens
0 pass
1 (a failed check) fails immediately — no retry
≥ 128 (killed by a signal) ::warning:: in the run summary, then one more attempt

A genuinely broken round trip still stops the build on the first try. Only a native crash gets the
second run, and it stays visible rather than being silently swallowed. Verified against exit codes
0, 1, 139 and 134.

Nothing here touches the plugin

No file under geodeploy_qgis/ changed, so 0.7.2 does not need re-uploading anywhere. This is
the harness and the workflow.

349 + 569 checks and the coverage report pass on qgis:ltr and qgis:4.2 with faulthandler enabled.

The QGIS 4.2 job exited 139 on the merge of a documentation-only PR — one
markdown file. The same commit's own PR run had passed that job minutes
earlier, and a rerun of the merge commit passed with nothing changed. So the
repository's code is not the variable.

It is the second time. Both were on the 4.2 image only, both at a different
place (once `corrupted size vs. prev_size`, once a clean SIGSEGV right after
the Rule-based section header), and both passed on a rerun.

NOT DIAGNOSED, AND NOT PRETENDED OTHERWISE. The obvious suspect is the
borrowed-pointer trap already recorded in notes_for_future: a symbol taken out
of a rule tree and read after its temporary is gone segfaults exactly like
this. So the harness's own rule builder was run 300 times on 4.2 with a
collection between every round — plain, ELSE, scale-limited and nested trees,
built, read, applied back and read again — and did not crash once. An earlier
occurrence survived 9 full runs under GC stress. There is no fix to make yet.

Two things that help anyway:

faulthandler is enabled in all three QGIS scripts, so a signal prints the
Python stack from inside the handler. The standing complaint about this class
of crash is that it arrives as nothing but "Segmentation fault (core dumped)"
and leaves you guessing which of 349 checks was running. Next time it will say.

And CI now distinguishes a crash from a verdict. Below exit 128 the step fails
immediately, so a broken round trip still stops the build on the first try;
128 or above it prints a ::warning:: and runs the script once more. The flake
stays visible in the run summary instead of being silently swallowed.

349 + 569 checks and the coverage report pass on qgis:ltr and qgis:4.2 with
faulthandler enabled.

Signed-off-by: Koffi Dodji Noumonvi <noumonvikoffidodji@hotmail.fr>
@bravemaster3
bravemaster3 merged commit 0201dd1 into main Sep 12, 2026
8 checks passed
@bravemaster3
bravemaster3 deleted the ci/a-signal-is-retried-a-verdict-is-not branch September 12, 2026 04:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant