Skip to content

Error CONTEXT lines, and a fix for a crash in nested error propagation#23

Merged
jdatcmd merged 2 commits into
masterfrom
error-context
Jul 6, 2026
Merged

Error CONTEXT lines, and a fix for a crash in nested error propagation#23
jdatcmd merged 2 commits into
masterfrom
error-context

Conversation

@jdatcmd

@jdatcmd jdatcmd commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Two things, found together — full suite green on PG 11–18 + jsonb_plphp in the container sweep.

CONTEXT lines (the feature)

Every message raised while PL/php code runs now carries context, like the other PLs:

ERROR:  division by zero at line 7
CONTEXT:  PL/php function "div_by_zero"

with variants for anonymous blocks (PL/php anonymous code block) and validation (compilation of PL/php function "f"), via standard error_context_stack callbacks in the three entry points. Every expected file gains its CONTEXT lines, including the base_1/trigger_1 alternates and jsonb_plphp.

The crash (the discovery)

Writing the nested-call test surfaced a latent backend crasher, present since the zend_try blocks were introduced and reproducible on 2.3.0: a PostgreSQL error longjmp'ing out of a handler's zend_try skips zend_end_try(), leaving EG(bailout) pointing into a dead stack frame. When one PL/php function calls another via SPI and the inner one fails, the outer function keeps running with the stale bailout environment — its eventual uncaught error longjmps into garbage (glibc fortify aborts with "longjmp causes uninitialized stack frame"; without fortify it's stack corruption).

Fix: save EG(bailout) before each handler's zend_try and restore it in the PG_CATCH that re-throws — all three entry points. New pgerror cases pin the formerly-crashing flow: uncaught nested error, session health afterwards, and catching the nested failure as PgError in the outer function.

Also fixes the at line N suffix double-appending the nested flow exposed.

🤖 Generated with Claude Code

ChronicallyJD and others added 2 commits July 5, 2026 20:28
Errors, warnings, and notices raised while PL/php code runs now carry
a CONTEXT line, like every other PL:

    ERROR:  division by zero at line 7
    CONTEXT:  PL/php function "div_by_zero"

via error_context_stack callbacks in the call handler ("PL/php
function \"name\""), the inline handler ("PL/php anonymous code
block"), and the validator ("compilation of PL/php function").

Exercising nested calls surfaced a longstanding crasher, fixed here:
a PostgreSQL error longjmp'ing out of a handler's zend_try block
skips zend_end_try(), leaving EG(bailout) pointing into the dying
stack frame.  When one PL/php function called another via SPI and the
inner one failed, execution continued in the outer function with the
stale bailout environment; its eventual bailout (an uncaught error)
longjmp'ed into garbage -- glibc's fortify checks abort with "longjmp
causes uninitialized stack frame", and without them it is arbitrary
stack corruption.  Save EG(bailout) before each handler's zend_try
and restore it in the PG_CATCH that re-throws, in all three entry
points.  Present since the zend_try blocks were introduced; the test
suite never exercised an error crossing nested calls.

Also guard the "at line N" suffix against double-appending, which the
nested flow made visible.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every existing error and notice in the expected files gains its
CONTEXT line -- including the base_1/trigger_1 alternates that absorb
older servers' message wording.  New pgerror cases cover an uncaught
error crossing nested calls (the former crasher), session health
afterwards, and catching the nested failure as PgError in the outer
function.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jdatcmd
jdatcmd merged commit 8cedf36 into master Jul 6, 2026
11 checks passed
@jdatcmd
jdatcmd deleted the error-context branch July 6, 2026 02:34
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.

2 participants