From 19d3c80e8136402a26b52c8da46eee071ec413d6 Mon Sep 17 00:00:00 2001 From: 卜部昌平 Date: Wed, 31 Jul 2019 23:15:56 +0900 Subject: calc_lineno(): add assertions This function has a lot of assumptions. Should make them sure. --- vm.c | 2 +- vm_backtrace.c | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/vm.c b/vm.c index 0759ef2a01..593540a32e 100644 --- a/vm.c +++ b/vm.c @@ -1343,7 +1343,7 @@ rb_source_location(int *pline) const rb_execution_context_t *ec = GET_EC(); const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp); - if (cfp && cfp->iseq) { + if (cfp && VM_FRAME_RUBYFRAME_P(cfp)) { if (pline) *pline = rb_vm_get_sourceline(cfp); return rb_iseq_path(cfp->iseq); } diff --git a/vm_backtrace.c b/vm_backtrace.c index 4f92439478..8d1e4b99d5 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -32,19 +32,36 @@ id2str(ID id) inline static int calc_lineno(const rb_iseq_t *iseq, const VALUE *pc) { - size_t pos = (size_t)(pc - iseq->body->iseq_encoded); - if (LIKELY(pos)) { - /* use pos-1 because PC points next instruction at the beginning of instruction */ - pos--; + VM_ASSERT(iseq); + VM_ASSERT(iseq->body); + VM_ASSERT(iseq->body->iseq_encoded); + VM_ASSERT(iseq->body->iseq_size); + if (! pc) { + /* This can happen during VM bootup. */ + VM_ASSERT(iseq->body->type == ISEQ_TYPE_TOP); + VM_ASSERT(! iseq->body->local_table); + VM_ASSERT(! iseq->body->local_table_size); + return 0; } -#if VMDEBUG && defined(HAVE_BUILTIN___BUILTIN_TRAP) else { - /* SDR() is not possible; that causes infinite loop. */ - rb_print_backtrace(); - __builtin_trap(); - } + ptrdiff_t n = pc - iseq->body->iseq_encoded; + VM_ASSERT(n <= iseq->body->iseq_size); + VM_ASSERT(n >= 0); + ASSUME(n >= 0); + size_t pos = n; /* no overflow */ + 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); + return rb_iseq_line_no(iseq, pos); + } } int @@ -1296,7 +1313,7 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines) const rb_callable_method_entry_t *cme; for (i=0; iiseq && cfp->pc) { + if (VM_FRAME_RUBYFRAME_P(cfp)) { if (start > 0) { start--; continue; -- cgit v1.2.3