summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-01 09:24:59 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-01 09:24:59 +0000
commit14d9ceed15a81a249608f9d1273af4e25da615c6 (patch)
treee6727595d1314f6ede4aeff7bd659a8af81b8b6d
parent10e28726a149d7d01e0c3dedb9694ec312cd8a9d (diff)
* .gdbinit (rb_ps_thread): show the detail of cfunc in ruby level
backtrace. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55553 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--.gdbinit84
-rw-r--r--ChangeLog5
2 files changed, 84 insertions, 5 deletions
diff --git a/.gdbinit b/.gdbinit
index 005a4756b4..5735c65c1a 100644
--- a/.gdbinit
+++ b/.gdbinit
@@ -413,7 +413,7 @@ document rp_id
Print an ID.
end
-define print_string
+define output_string
set $flags = ((struct RBasic*)($arg0))->flags
printf "%s", (char *)(($flags & RUBY_FL_USER1) ? \
((struct RString*)($arg0))->as.heap.ptr : \
@@ -972,6 +972,61 @@ define print_lineno
end
end
+define check_method_entry
+ # get $immeo and $can_be_svar and return $me
+ set $imemo = (struct RBasic *)$arg0
+ set $can_be_svar = $arg1
+ if $imemo != Qfalse
+ set $type = ($imemo->flags >> 12) & 0x07
+ if $type == imemo_ment
+ set $me = (rb_callable_method_entry_t *)$imemo
+ else
+ if $type == imemo_svar
+ set $imemo == ((struct vm_svar *)$imemo)->cref_or_me
+ check_method_entry $imemo 0
+ end
+ end
+ end
+end
+
+define output_id
+ set $id = $arg0
+ # rb_id_to_serial
+ if $id > tLAST_OP_ID
+ set $serial = (rb_id_serial_t)($id >> ID_SCOPE_SHIFT)
+ else
+ set $serial = (rb_id_serial_t)$id
+ end
+ if $serial && $serial <= global_symbols.last_id
+ set $idx = $serial / ID_ENTRY_UNIT
+ set $ids = (struct RArray *)global_symbols.ids
+ set $flags = $ids->basic.flags
+ if ($flags & RUBY_FL_USER1)
+ set $idsptr = $ids->as.ary
+ set $idslen = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
+ else
+ set $idsptr = $ids->as.heap.ptr
+ set $idslen = $ids->as.heap.len
+ end
+ if $idx < $idslen
+ set $t = 0
+ set $ary = (struct RArray *)$idsptr[$idx]
+ if $ary != Qnil
+ set $flags = $ary->basic.flags
+ if ($flags & RUBY_FL_USER1)
+ set $aryptr = $ary->as.ary
+ set $arylen = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
+ else
+ set $aryptr = $ary->as.heap.ptr
+ set $arylen = $ary->as.heap.len
+ end
+ set $result = $aryptr[($serial % ID_ENTRY_UNIT) * ID_ENTRY_SIZE + $t]
+ output_string $result
+ end
+ end
+ end
+end
+
define rb_ps_thread
set $ps_thread = (struct RTypedData*)$arg0
set $ps_thread_th = (rb_thread_t*)$ps_thread->data
@@ -983,11 +1038,11 @@ define rb_ps_thread
if $cfp->iseq
if $cfp->pc
set $location = $cfp->iseq->body->location
- print_string $location.path
+ output_string $location.path
printf ":"
print_lineno $cfp
printf ":in `"
- print_string $location.label
+ output_string $location.label
printf "'\n"
else
printf "???.rb:???:in `???'\n"
@@ -995,8 +1050,27 @@ define rb_ps_thread
else
# if ($cfp->flag & VM_FRAME_MAGIC_MASK) == VM_FRAME_MAGIC_CFUNC
if ($cfp->flag & 255) == 0x61
- # you can check cfunc by simple `backtrace` command...
- printf "cfunc:???:in `???'\n"
+ #define VM_ENVVAL_BLOCK_PTR_FLAG 0x02
+ #define VM_EP_PREV_EP(ep) ((VALUE *)GC_GUARDED_PTR_REF((ep)[0]))
+ set $ep = $cfp->ep
+ set $me = NULL
+ while ($ep[0] & 0x02) != 0
+ check_method_entry $ep[-1] 0
+ if $me != NULL
+ loop_break
+ end
+ set $ep = $ep[0]
+ end
+ if $me == NULL
+ check_method_entry $ep[-1] 1
+ end
+ set print symbol-filename on
+ output/a $me->def->body.cfunc.func
+ set print symbol-filename off
+ set $mid = $me->def->original_id
+ printf ":in `"
+ output_id $mid
+ printf "'\n"
else
printf "unknown_frame:???:in `???'\n"
end
diff --git a/ChangeLog b/ChangeLog
index c695bd9805..2810d9e855 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jul 1 18:20:00 2016 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * .gdbinit (rb_ps_thread): show the detail of cfunc in ruby level
+ backtrace.
+
Fri Jul 1 13:26:39 2016 Naohisa Goto <ngotogenome@gmail.com>
* string.c (rb_str_subseq, str_substr): When RSTRING_EMBED_LEN_MAX