From b67cea4442e06467127cbb2949f40c180a5f94b5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 6 Feb 2024 22:35:24 +0900 Subject: [PATCH] backtrace.c (pack_backtrace_i): avoid infinite loop; ref #6161 When irep->refcnt reaches UINT16_MAX, mrb_irep_incref() raises exception but the function pack_backtrace_i() is called from mrb_exc_raise() thus causes the infinite loop problem. So this is a hack-ish workaround by making irep reference to NULL if refcnt reaches the maximum count. Probably we will address this issue again to make it better. --- src/backtrace.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index f4ec6999a..a98b80004 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -85,10 +85,15 @@ pack_backtrace_i(mrb_state *mrb, struct mrb_backtrace_location **pptr = (struct mrb_backtrace_location**)data; struct mrb_backtrace_location *ptr = *pptr; - if (loc->irep) { - mrb_irep_incref(mrb, (mrb_irep*)loc->irep); - } *ptr = *loc; + if (ptr->irep) { + if (ptr->irep->refcnt == UINT16_MAX) { + ptr->irep = NULL; + } + else { + mrb_irep_incref(mrb, (mrb_irep*)ptr->irep); + } + } *pptr = ptr+1; }