[前][次][番号順一覧][スレッド一覧]

ruby-changes:43475

From: naruse <ko1@a...>
Date: Fri, 1 Jul 2016 04:36:47 +0900 (JST)
Subject: [ruby-changes:43475] naruse:r55548 (trunk): * .gdbinit (rb_ps_thread): show ruby level backtrace.

naruse	2016-07-01 04:36:38 +0900 (Fri, 01 Jul 2016)

  New Revision: 55548

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55548

  Log:
    * .gdbinit (rb_ps_thread): show ruby level backtrace.
      Usually you can call `rb_ps` to show ruby leve backtraces
      for all living threads.
      Note that it can call with core file like `gcore <pid>`
      and `gdb ruby core.<pid>`.

  Modified files:
    trunk/.gdbinit
    trunk/ChangeLog
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55547)
+++ ChangeLog	(revision 55548)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jul  1 04:32:52 2016  NARUSE, Yui  <naruse@r...>
+
+	* .gdbinit (rb_ps_thread): show ruby level backtrace.
+	  Usually you can call `rb_ps` to show ruby leve backtraces
+	  for all living threads.
+	  Note that it can call with core file like `gcore <pid>`
+	  and `gdb ruby core.<pid>`.
+
 Thu Jun 30 19:15:13 2016  Naohisa Goto  <ngotogenome@g...>
 
 	* string.c: Fix memory corruptions when using UTF-16/32 strings.
Index: .gdbinit
===================================================================
--- .gdbinit	(revision 55547)
+++ .gdbinit	(revision 55548)
@@ -413,6 +413,13 @@ document rp_id https://github.com/ruby/ruby/blob/trunk/.gdbinit#L413
   Print an ID.
 end
 
+define print_string
+  set $flags = ((struct RBasic*)($arg0))->flags
+  printf "%s", (char *)(($flags & RUBY_FL_USER1) ? \
+	    ((struct RString*)($arg0))->as.heap.ptr : \
+	    ((struct RString*)($arg0))->as.ary)
+end
+
 define rp_string
   set $flags = ((struct RBasic*)($arg0))->flags
   set print address off
@@ -936,11 +943,66 @@ document rb_ps_vm https://github.com/ruby/ruby/blob/trunk/.gdbinit#L943
 Dump all threads in a (rb_vm_t*) and their callstacks
 end
 
+define print_lineno
+  set $cfp = $arg0
+  set $iseq = $cfp->iseq
+  set $pos = $cfp->pc - $iseq->body->iseq_encoded
+  if $pos != 0
+    set $pos = $pos - 1
+  end
+
+  set $i = 0
+  set $size = $iseq->body->line_info_size
+  set $table = $iseq->body->line_info_table
+  #printf "size: %d\n", $size
+  if $size == 0
+  else
+    set $i = 1
+    while $i < $size
+      #printf "table[%d]: position: %d, line: %d, pos: %d\n", $i, $table[$i].position, $table[$i].line_no, $pos
+      if $table[$i].position > $pos
+        loop_break
+      end
+      set $i = $i + 1
+      if $table[$i].position == $pos
+        loop_break
+      end
+    end
+    printf "%d", $table[$i-1].line_no
+  end
+end
+
 define rb_ps_thread
   set $ps_thread = (struct RTypedData*)$arg0
   set $ps_thread_th = (rb_thread_t*)$ps_thread->data
   printf "* #<Thread:%p rb_thread_t:%p native_thread:%p>\n", \
     $ps_thread, $ps_thread_th, $ps_thread_th->thread_id
+  set $cfp = $ps_thread_th->cfp
+  set $cfpend = (rb_control_frame_t *)($ps_thread_th->stack + $ps_thread_th->stack_size)-1
+  while $cfp < $cfpend
+    if $cfp->iseq
+      if $cfp->pc
+        set $location = $cfp->iseq->body->location
+        print_string $location.path
+        printf ":"
+        print_lineno $cfp
+        printf ":in `"
+        print_string $location.label
+        printf "'\n"
+      else
+        printf "???.rb:???:in `???'\n"
+      end
+    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"
+      else
+        printf "unknown_frame:???:in `???'\n"
+      end
+    end
+    set $cfp = $cfp + 1
+  end
 end
 
 # Details: https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/MachineInstructionsTraceWithGDB

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]