#include "akerror.h" #include "err_capture.h" #include /* * Releasing an error context back to the pool must wipe it, so the next caller * that checks it out never sees stale status/message/stacktrace from a previous * error. Mutation testing showed the clearing memset in akerr_release_error * could be deleted without any test noticing. */ akerr_ErrorContext *boom(void) { PREPARE_ERROR(e); FAIL_RETURN(e, AKERR_VALUE, "stale dirty message that must not survive"); } int main(void) { akerr_capture_install(); akerr_init(); /* Raise and fully handle an error; FINISH_NORETURN releases it to the pool. */ PREPARE_ERROR(e); ATTEMPT { CATCH(e, boom()); } CLEANUP { } PROCESS(e) { } HANDLE(e, AKERR_VALUE) { AKERR_CHECK_STATUS(e, AKERR_VALUE); } FINISH_NORETURN(e); AKERR_CHECK(e == NULL); /* The next context handed out is the slot we just released: it must be clean. */ akerr_ErrorContext *slot = akerr_next_error(); AKERR_CHECK(slot != NULL); AKERR_CHECK(slot->status == 0); AKERR_CHECK(slot->message[0] == '\0'); AKERR_CHECK(slot->stacktracebuf[0] == '\0'); AKERR_CHECK(strstr(slot->message, "stale dirty message") == NULL); fprintf(stderr, "err_release_clears ok\n"); return 0; }