summaryrefslogtreecommitdiff
path: root/vm_backtrace.c
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2019-07-31 23:15:56 +0900
committer卜部昌平 <shyouhei@ruby-lang.org>2019-08-01 16:00:59 +0900
commit19d3c80e8136402a26b52c8da46eee071ec413d6 (patch)
tree7649a44bf5ff014070e525e922d09fe12d3567f2 /vm_backtrace.c
parent5d33f787169bcc3594d2264726695d58c4a06899 (diff)
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.c39
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;