From 9bf8bcd357ad311dd60eaa1732638f32ac57748b Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Sat, 1 Aug 2026 16:35:26 -0400 Subject: [PATCH] Fix two comments that misstate exit sites and NULL validity Both found while auditing the pool for the cross-thread transfer guarantee. AGENTS.md said the two exit() calls that bypass akerr_exit() are "both in src/error.c". ENSURE_ERROR_READY's pool-exhaustion abort is in include/akerror.tmpl.h. The count of abort sites is load-bearing -- it is the argument against any API that could fail on pool exhaustion -- so pointing at the wrong file makes it hard to check. akerr_valid_error_address() returns 1 for NULL, which is right for VALID() (NULL is how a function reports success) and a trap for anything reading it as "is this a pool slot". Say so where the function is defined. Comments only; no behavior change. Co-Authored-By: Claude Opus 5 (1M context) --- AGENTS.md | 6 +++--- src/error.c | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5cd0189..d69dbaf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -92,9 +92,9 @@ releases it on the single return path. Do not call consumer code owns the one mapping from an akerr status to an exit code: an exit status is a byte, and every consumer status starts at 256, so passing a status through `exit()` silently truncates it — status 256 exits 0 and reports success. The -only exits that bypass it are the two that have no status to map, both in -`src/error.c`: `ENSURE_ERROR_READY`'s pool-exhaustion abort and the NULL-context -case in `akerr_default_handler_unhandled_error()`. This rule applies to test +only exits that bypass it are the two that have no status to map: +`ENSURE_ERROR_READY`'s pool-exhaustion abort in `include/akerror.tmpl.h`, and the +NULL-context case in `akerr_default_handler_unhandled_error()` in `src/error.c`. This rule applies to test programs too, except where the test's whole point is to observe the raw truncation. diff --git a/src/error.c b/src/error.c index a3ae18e..4182d50 100644 --- a/src/error.c +++ b/src/error.c @@ -129,6 +129,11 @@ akerr_ErrorContext *__akerr_copy_string(char *destination, int capacity, * * Takes no lock: the addresses of the pool slots are fixed for the life of the * process, and nothing here reads a slot's contents. + * + * NULL reads back as valid, because the caller is VALID() asking whether a + * function returned something it has no business returning, and NULL is how a + * function says it succeeded. Anything reading this as "is this a pool slot" + * must check for NULL itself. */ int akerr_valid_error_address(akerr_ErrorContext *ptr) {