fix package bug, improve stack trace

This commit is contained in:
2026-02-17 00:28:10 -06:00
parent 8a19cffe9f
commit 0ac575db85
6 changed files with 50 additions and 103 deletions

View File

@@ -2113,7 +2113,9 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
/* Search frame chain for a disruption handler.
Use frame_pc to track each frame's execution point:
- For the faulting frame, it's the current pc.
- For unwound caller frames, read from frame->address. */
- For unwound caller frames, read from frame->address.
Keep frame_ref.val at the faulting frame and preserve caller
links so the trace walk can show the full call chain. */
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); /* re-chase after GC */
{
uint32_t frame_pc = pc;
@@ -2125,28 +2127,34 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
env = fn->u.reg.env_record;
pc = code->disruption_pc;
ctx->disruption_reported = FALSE;
frame_ref.val = JS_MKPTR(frame); /* root handler frame for GC */
break;
}
if (JS_IsNull(frame->caller)) {
if (!ctx->disruption_reported) {
const char *fn_name = code->name_cstr ? code->name_cstr : "<anonymous>";
const char *file = code->filename_cstr ? code->filename_cstr : "<unknown>";
/* Use faulting frame (frame_ref.val) for the header */
JSFrameRegister *fault = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
JSFunction *fault_fn = JS_VALUE_GET_FUNCTION(fault->function);
JSCodeRegister *fault_code = fault_fn->u.reg.code;
const char *fn_name = fault_code->name_cstr ? fault_code->name_cstr : "<anonymous>";
const char *file = fault_code->filename_cstr ? fault_code->filename_cstr : "<unknown>";
uint16_t line = 0, col = 0;
if (code->line_table && frame_pc > 0 && frame_pc - 1 < code->instr_count) {
line = code->line_table[frame_pc - 1].line;
col = code->line_table[frame_pc - 1].col;
uint32_t fpc = pc > 0 ? pc - 1 : 0;
if (fault_code->line_table && fpc < fault_code->instr_count) {
line = fault_code->line_table[fpc].line;
col = fault_code->line_table[fpc].col;
}
fprintf(stderr, "unhandled disruption in %s (%s:%u:%u)\n", fn_name, file, line, col);
/* Walk and print the frame chain as a stack trace */
/* Walk intact caller chain for stack trace */
{
JSFrameRegister *trace_frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
JSFrameRegister *trace_frame = fault;
int first = 1;
while (trace_frame) {
if (!mist_is_function(trace_frame->function)) break;
JSFunction *trace_fn = JS_VALUE_GET_FUNCTION(trace_frame->function);
if (trace_fn->kind == JS_FUNC_KIND_REGISTER && trace_fn->u.reg.code) {
JSCodeRegister *tc = trace_fn->u.reg.code;
uint32_t tpc = first ? (frame_pc > 0 ? frame_pc - 1 : 0)
uint32_t tpc = first ? fpc
: (uint32_t)(JS_VALUE_GET_INT(trace_frame->address) >> 16);
uint16_t tl = 0, tcol = 0;
if (tc->line_table && tpc < tc->instr_count) {
@@ -2164,15 +2172,13 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
}
ctx->disruption_reported = TRUE;
}
frame_ref.val = JS_MKPTR(frame); /* update root for GC / done */
result = JS_Throw(ctx, JS_NULL);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
goto done;
}
/* Unwind one frame — read caller's saved pc from its address field */
JSFrameRegister *caller = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller);
frame->caller = JS_NULL;
frame = caller;
frame_ref.val = JS_MKPTR(frame);
/* Advance to caller — keep chain intact (no nulling caller links) */
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller);
frame_pc = (uint32_t)(JS_VALUE_GET_INT(frame->address) >> 16);
}
}