aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--vm_backtrace.c14
2 files changed, 13 insertions, 2 deletions
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