44 lines
1.6 KiB
C
44 lines
1.6 KiB
C
|
|
#include "akerror.h"
|
||
|
|
#include "err_capture.h"
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
/*
|
||
|
|
* akerr_release_error(NULL) is an API contract violation the library reports
|
||
|
|
* rather than crashes on: it raises AKERR_NULLPOINTER against the internal
|
||
|
|
* last-ditch context and hands that back, so the caller gets a describable
|
||
|
|
* error instead of a dereferenced NULL. Nothing exercised that path.
|
||
|
|
*
|
||
|
|
* The last-ditch context deliberately lives outside AKERR_ARRAY_ERROR so
|
||
|
|
* reporting this failure cannot consume a pool slot -- which is exactly what
|
||
|
|
* akerr_valid_error_address() reports on, and what this test checks.
|
||
|
|
*/
|
||
|
|
|
||
|
|
int main(void)
|
||
|
|
{
|
||
|
|
akerr_capture_install();
|
||
|
|
/* akerr_init() sets up the last-ditch context's stacktrace cursor. */
|
||
|
|
akerr_init();
|
||
|
|
AKERR_CHECK(akerr_slots_in_use() == 0);
|
||
|
|
|
||
|
|
akerr_ErrorContext *ret = akerr_release_error(NULL);
|
||
|
|
|
||
|
|
AKERR_CHECK(ret != NULL);
|
||
|
|
AKERR_CHECK(ret->status == AKERR_NULLPOINTER);
|
||
|
|
AKERR_CHECK(strstr(ret->message, "NULL context pointer") != NULL);
|
||
|
|
|
||
|
|
/* Reported through FAIL, so the stack trace names the error too. */
|
||
|
|
AKERR_CHECK(strstr(ret->stacktracebuf, "Null Pointer Error") != NULL);
|
||
|
|
|
||
|
|
/* Not a pool slot, and no slot was checked out to report the failure. */
|
||
|
|
AKERR_CHECK(akerr_valid_error_address(ret) == 0);
|
||
|
|
AKERR_CHECK(akerr_slots_in_use() == 0);
|
||
|
|
|
||
|
|
/* The last-ditch context is a singleton: the same one comes back. */
|
||
|
|
akerr_ErrorContext *again = akerr_release_error(NULL);
|
||
|
|
AKERR_CHECK(again == ret);
|
||
|
|
AKERR_CHECK(akerr_slots_in_use() == 0);
|
||
|
|
|
||
|
|
fprintf(stderr, "err_release_null ok\n");
|
||
|
|
return 0;
|
||
|
|
}
|