diff --git a/configure.ac b/configure.ac index efc1dbd2ab..40e8a95f57 100644 --- a/configure.ac +++ b/configure.ac @@ -1993,6 +1993,7 @@ AS_IF([test x$rb_cv_builtin___builtin_choose_expr = xyes], [ ]) ]) RUBY_CHECK_BUILTIN_FUNC(__builtin_types_compatible_p, [__builtin_types_compatible_p(int, int)]) +RUBY_CHECK_BUILTIN_FUNC(__builtin_trap, [__builtin_trap()]) AS_IF([test "$ac_cv_func_qsort_r" != no], [ AC_CACHE_CHECK(whether qsort_r is GNU version, rb_cv_gnu_qsort_r, diff --git a/vm_backtrace.c b/vm_backtrace.c index 0493ed8c89..776f6d188a 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -33,8 +33,18 @@ inline static int calc_lineno(const rb_iseq_t *iseq, const VALUE *pc) { size_t pos = (size_t)(pc - iseq->body->iseq_encoded); - /* use pos-1 because PC points next instruction at the beginning of instruction */ - return rb_iseq_line_no(iseq, pos - 1); + if (LIKELY(pos)) { + /* use pos-1 because PC points next instruction at the beginning of instruction */ + pos--; + } +#if VMDEBUG && defined(HAVE_BUILTIN___BUILTIN_TRAP) + else { + /* SDR() is not possible; that causes infinite loop. */ + rb_print_backtrace(); + __builtin_trap(); + } +#endif + return rb_iseq_line_no(iseq, pos); } int