Files
scriptc/tests/library-mode/init-trap/probe.c
Chris Tate e1f93475cb Deliver runtime-detected library traps structured, with codes, entry symbols, and profile overlays
- The library trap funnel (scr_library.c) now assembles every detected trap into the ratified 0x01 text 0x1F code 0x1F symbol [0x1F remediation] form: the baseline human line rides unchanged as field 0, and 0x01-led messages (facade-authored throws, the compile-time SC4012 contract trap) still pass verbatim.
- Trap kinds classify over the runtime's own message conventions into a new SC4013-SC4019 runtime code family (escaped exception, range, type, syntax, OOM, internal invariant, residual), documented beside SC4012 in the diagnostics registry; no arithmetic kind exists because no runtime site can fire one.
- Every generated entry prologue (init, reset, collect, each export, both emissions) records its external symbol in a SCR_LIB-only static slot the funnel reads, so the structured message names the trapping entry as the host linked it; profile teachings/remediations for the family land as a program-TU overlay table both backends emit identically.
- K5/K7/init-trap fixtures now pin the structured layout with the spec's parse rule (default text, code, entry symbol, fields=3 on a no-teachings profile), and new K12 tests pin the SC4014 teaching/remediation overlay plus the undeclared-code default; the verbatim and text-leads-printable pins stay.
- The default executable lane is byte-identical (signature-stripped cmp over a stash/rebuild pair); all library suites and the diagnostics suite are green on both emissions.
2026-07-23 19:57:38 -05:00

53 lines
1.6 KiB
C

/* A trap during init routes to the sink exactly once; the host survives
* through its own longjmp frame below the entry. Init counts as an entry:
* the structured message's symbol field names the init symbol itself. */
#include <setjmp.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
extern void ki_init(void);
extern void ki_set_panic_sink(void (*fn)(void *, const uint8_t *, size_t, uint64_t), void *ctx);
static jmp_buf trap_jmp;
static int sink_calls = 0;
/* The spec's parse rule (see traps/probe.c). */
static void show(const uint8_t *msg, size_t len) {
if (len == 0 || msg[0] != 0x01) {
printf("baseline printable=%d text=%.*s", len > 0 && msg[0] >= 0x20, (int)len, (const char *)msg);
return;
}
static const char *names[4] = {"text", "code", "symbol", "remediation"};
const uint8_t *p = msg + 1, *end = msg + len;
int fields = 0;
for (;;) {
const uint8_t *sep = memchr(p, 0x1f, (size_t)(end - p));
const uint8_t *stop = sep != NULL ? sep : end;
if (fields < 4) printf("%s=[%.*s]\n", names[fields], (int)(stop - p), (const char *)p);
fields++;
if (sep == NULL) break;
p = sep + 1;
}
printf("fields=%d text_printable=%d\n", fields, len > 1 && msg[1] >= 0x20);
}
static void sink(void *ctx, const uint8_t *msg, size_t len, uint64_t addr) {
(void)ctx; (void)addr;
sink_calls++;
printf("sink[%d]:\n", sink_calls);
show(msg, len);
longjmp(trap_jmp, 1);
}
int main(void) {
ki_set_panic_sink(sink, NULL);
if (setjmp(trap_jmp) == 0) {
ki_init();
printf("UNREACHABLE\n");
} else {
printf("survived init trap, sink_calls=%d\n", sink_calls);
}
return 0;
}