From e97299fc658df9ce0e14385ad698f63d7387d93b Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 1 Jun 2023 13:01:59 -0500 Subject: [PATCH] Fix #1174 - bad debug info causing stack traversal to segfault. Coming from commit 77189b6e66193cc03b824413cfcf65a1c20bb53d, relating to changes in source mapping debug info, this caused a segfault when traversing a stack frame where the birth_pc was incredibly large due to wrap around. This fix prevents the wrap around and does saturating subtraction to 0. --- src/core/compile.c | 9 ++++++++- test/suite0015.janet | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/compile.c b/src/core/compile.c index 05c19ba2..8ab0e3a2 100644 --- a/src/core/compile.c +++ b/src/core/compile.c @@ -978,7 +978,14 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) { jsm.death_pc = pair.death_pc - scope->bytecode_start; } /* Handle birth_pc == 0 correctly */ - jsm.birth_pc = pair.birth_pc ? pair.birth_pc - scope->bytecode_start : 0; + if ((uint32_t) scope->bytecode_start > pair.birth_pc) { + jsm.birth_pc = 0; + } else { + jsm.birth_pc = pair.birth_pc - scope->bytecode_start; + } + janet_assert(jsm.birth_pc <= jsm.death_pc, "birth pc after death pc"); + janet_assert(jsm.birth_pc < (uint32_t) def->bytecode_length, "bad birth pc"); + janet_assert(jsm.death_pc <= (uint32_t) def->bytecode_length, "bad death pc"); jsm.slot_index = pair.slot.index; jsm.symbol = pair.sym2; janet_v_push(locals, jsm); diff --git a/test/suite0015.janet b/test/suite0015.janet index bb00a9b6..aba27bd9 100644 --- a/test/suite0015.janet +++ b/test/suite0015.janet @@ -47,4 +47,15 @@ (assert (= 10 (do (var x 10) (def y x) (++ x) y)) "no invalid aliasing") +# Crash issue #1174 - bad debug info +(defn crash [] + (debug/stack (fiber/current))) +(do + (math/random) + (defn foo [_] + (crash) + 1) + (foo 0) + 10) + (end-suite)