diff options
author | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-07-31 23:15:56 +0900 |
---|---|---|
committer | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-08-01 16:00:59 +0900 |
commit | 19d3c80e8136402a26b52c8da46eee071ec413d6 (patch) | |
tree | 7649a44bf5ff014070e525e922d09fe12d3567f2 /vm_backtrace.c | |
parent | 5d33f787169bcc3594d2264726695d58c4a06899 (diff) | |
download | ruby-19d3c80e8136402a26b52c8da46eee071ec413d6.tar.gz |
calc_lineno(): add assertions
This function has a lot of assumptions. Should make them sure.
Diffstat (limited to 'vm_backtrace.c')
-rw-r--r-- | vm_backtrace.c | 39 |
1 files changed, 28 insertions, 11 deletions
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; i<limit && cfp != end_cfp;) { - if (cfp->iseq && cfp->pc) { + if (VM_FRAME_RUBYFRAME_P(cfp)) { if (start > 0) { start--; continue; |