1define rp
2  if ruby_dummy_gdb_enums.special_consts
3  end
4  if (VALUE)($arg0) & RUBY_FIXNUM_FLAG
5    printf "FIXNUM: %ld\n", (long)($arg0) >> 1
6  else
7  if ((VALUE)($arg0) & ~(~(VALUE)0<<RUBY_SPECIAL_SHIFT)) == RUBY_SYMBOL_FLAG
8    set $id = (($arg0) >> RUBY_SPECIAL_SHIFT)
9    if $id == '!' || $id == '+' || $id == '-' || $id == '*' || $id == '/' || $id == '%' || $id == '<' || $id == '>' || $id == '`'
10      printf "SYMBOL(:%c)\n", $id
11    else
12    if $id == idDot2
13      echo SYMBOL(:..)\n
14    else
15    if $id == idDot3
16      echo SYMBOL(:...)\n
17    else
18    if $id == idUPlus
19      echo SYMBOL(:+@)\n
20    else
21    if $id == idUMinus
22      echo SYMBOL(:-@)\n
23    else
24    if $id == idPow
25      echo SYMBOL(:**)\n
26    else
27    if $id == idCmp
28      echo SYMBOL(:<=>)\n
29    else
30    if $id == idLTLT
31      echo SYMBOL(:<<)\n
32    else
33    if $id == idLE
34      echo SYMBOL(:<=)\n
35    else
36    if $id == idGE
37      echo SYMBOL(:>=)\n
38    else
39    if $id == idEq
40      echo SYMBOL(:==)\n
41    else
42    if $id == idEqq
43      echo SYMBOL(:===)\n
44    else
45    if $id == idNeq
46      echo SYMBOL(:!=)\n
47    else
48    if $id == idEqTilde
49      echo SYMBOL(:=~)\n
50    else
51    if $id == idNeqTilde
52      echo SYMBOL(:!~)\n
53    else
54    if $id == idAREF
55      echo SYMBOL(:[])\n
56    else
57    if $id == idASET
58      echo SYMBOL(:[]=)\n
59    else
60      printf "SYMBOL(%ld)\n", $id
61    end
62    end
63    end
64    end
65    end
66    end
67    end
68    end
69    end
70    end
71    end
72    end
73    end
74    end
75    end
76    end
77    end
78  else
79  if ($arg0) == RUBY_Qfalse
80    echo false\n
81  else
82  if ($arg0) == RUBY_Qtrue
83    echo true\n
84  else
85  if ($arg0) == RUBY_Qnil
86    echo nil\n
87  else
88  if ($arg0) == RUBY_Qundef
89    echo undef\n
90  else
91  if (VALUE)($arg0) & RUBY_IMMEDIATE_MASK
92    if ((VALUE)($arg0) & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG
93      printf "FLONUM: %g\n", (double)rb_float_value($arg0)
94    else
95      echo immediate\n
96    end
97  else
98  set $flags = ((struct RBasic*)($arg0))->flags
99  if ($flags & RUBY_T_MASK) == RUBY_T_NONE
100    printf "T_NONE: "
101    print (struct RBasic *)($arg0)
102  else
103  if ($flags & RUBY_T_MASK) == RUBY_T_NIL
104    printf "T_NIL: "
105    print (struct RBasic *)($arg0)
106  else
107  if ($flags & RUBY_T_MASK) == RUBY_T_OBJECT
108    printf "T_OBJECT: "
109    print (struct RObject *)($arg0)
110  else
111  if ($flags & RUBY_T_MASK) == RUBY_T_CLASS
112    printf "T_CLASS%s: ", ($flags & RUBY_FL_SINGLETON) ? "*" : ""
113    rp_class $arg0
114  else
115  if ($flags & RUBY_T_MASK) == RUBY_T_ICLASS
116    printf "T_ICLASS: "
117    rp_class $arg0
118  else
119  if ($flags & RUBY_T_MASK) == RUBY_T_MODULE
120    printf "T_MODULE: "
121    rp_class $arg0
122  else
123  if ($flags & RUBY_T_MASK) == RUBY_T_FLOAT
124    printf "T_FLOAT: %.16g ", (((struct RFloat*)($arg0))->float_value)
125    print (struct RFloat *)($arg0)
126  else
127  if ($flags & RUBY_T_MASK) == RUBY_T_STRING
128    printf "T_STRING: "
129    set print address off
130    output (char *)(($flags & RUBY_FL_USER1) ? \
131	    ((struct RString*)($arg0))->as.heap.ptr : \
132	    ((struct RString*)($arg0))->as.ary)
133    set print address on
134    printf " bytesize:%ld ", ($flags & RUBY_FL_USER1) ? \
135            ((struct RString*)($arg0))->as.heap.len : \
136            (($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
137    if !($flags & RUBY_FL_USER1)
138      printf "(embed) "
139    else
140      if ($flags & RUBY_FL_USER2)
141        printf "(shared) "
142      end
143      if ($flags & RUBY_FL_USER3)
144        printf "(assoc) "
145      end
146    end
147    printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
148    if ($flags & RUBY_ENC_CODERANGE_MASK) == 0
149      printf "coderange:unknown "
150    else
151    if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_7BIT
152      printf "coderange:7bit "
153    else
154    if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_VALID
155      printf "coderange:valid "
156    else
157      printf "coderange:broken "
158    end
159    end
160    end
161    print (struct RString *)($arg0)
162  else
163  if ($flags & RUBY_T_MASK) == RUBY_T_REGEXP
164    set $regsrc = ((struct RRegexp*)($arg0))->src
165    set $rsflags = ((struct RBasic*)$regsrc)->flags
166    printf "T_REGEXP: "
167    set print address off
168    output (char *)(($rsflags & RUBY_FL_USER1) ? \
169	    ((struct RString*)$regsrc)->as.heap.ptr : \
170	    ((struct RString*)$regsrc)->as.ary)
171    set print address on
172    printf " len:%ld ", ($rsflags & RUBY_FL_USER1) ? \
173            ((struct RString*)$regsrc)->as.heap.len : \
174            (($rsflags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
175    if $flags & RUBY_FL_USER6
176      printf "(none) "
177    end
178    if $flags & RUBY_FL_USER5
179      printf "(literal) "
180    end
181    if $flags & RUBY_FL_USER4
182      printf "(fixed) "
183    end
184    printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
185    print (struct RRegexp *)($arg0)
186  else
187  if ($flags & RUBY_T_MASK) == RUBY_T_ARRAY
188    if ($flags & RUBY_FL_USER1)
189      set $len = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
190      printf "T_ARRAY: len=%ld ", $len
191      printf "(embed) "
192      if ($len == 0)
193	printf "{(empty)} "
194      else
195	output/x *((VALUE*)((struct RArray*)($arg0))->as.ary) @ $len
196	printf " "
197      end
198    else
199      set $len = ((struct RArray*)($arg0))->as.heap.len
200      printf "T_ARRAY: len=%ld ", $len
201      if ($flags & RUBY_FL_USER2)
202	printf "(shared) shared="
203	output/x ((struct RArray*)($arg0))->as.heap.aux.shared
204	printf " "
205      else
206	printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa
207      end
208      if ($len == 0)
209	printf "{(empty)} "
210      else
211	output/x *((VALUE*)((struct RArray*)($arg0))->as.heap.ptr) @ $len
212	printf " "
213      end
214    end
215    print (struct RArray *)($arg0)
216  else
217  if ($flags & RUBY_T_MASK) == RUBY_T_FIXNUM
218    printf "T_FIXNUM: "
219    print (struct RBasic *)($arg0)
220  else
221  if ($flags & RUBY_T_MASK) == RUBY_T_HASH
222    printf "T_HASH: ",
223    if ((struct RHash *)($arg0))->ntbl
224      printf "len=%ld ", ((struct RHash *)($arg0))->ntbl->num_entries
225    end
226    print (struct RHash *)($arg0)
227  else
228  if ($flags & RUBY_T_MASK) == RUBY_T_STRUCT
229    printf "T_STRUCT: len=%ld ", \
230      (($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) ? \
231       ($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) >> (RUBY_FL_USHIFT+1) : \
232       ((struct RStruct *)($arg0))->as.heap.len)
233    print (struct RStruct *)($arg0)
234    x/xw (($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) ? \
235          ((struct RStruct *)($arg0))->as.ary : \
236          ((struct RStruct *)($arg0))->as.heap.ptr)
237  else
238  if ($flags & RUBY_T_MASK) == RUBY_T_BIGNUM
239    printf "T_BIGNUM: sign=%d len=%ld ", \
240      (($flags & RUBY_FL_USER1) != 0), \
241      (($flags & RUBY_FL_USER2) ? \
242       ($flags & (RUBY_FL_USER5|RUBY_FL_USER4|RUBY_FL_USER3)) >> (RUBY_FL_USHIFT+3) : \
243       ((struct RBignum*)($arg0))->as.heap.len)
244    if $flags & RUBY_FL_USER2
245      printf "(embed) "
246    end
247    print (struct RBignum *)($arg0)
248    x/xw (($flags & RUBY_FL_USER2) ? \
249          ((struct RBignum*)($arg0))->as.ary : \
250          ((struct RBignum*)($arg0))->as.heap.digits)
251  else
252  if ($flags & RUBY_T_MASK) == RUBY_T_RATIONAL
253    printf "T_RATIONAL: "
254    print (struct RRational *)($arg0)
255  else
256  if ($flags & RUBY_T_MASK) == RUBY_T_COMPLEX
257    printf "T_COMPLEX: "
258    print (struct RComplex *)($arg0)
259  else
260  if ($flags & RUBY_T_MASK) == RUBY_T_FILE
261    printf "T_FILE: "
262    print (struct RFile *)($arg0)
263    output *((struct RFile *)($arg0))->fptr
264    printf "\n"
265  else
266  if ($flags & RUBY_T_MASK) == RUBY_T_TRUE
267    printf "T_TRUE: "
268    print (struct RBasic *)($arg0)
269  else
270  if ($flags & RUBY_T_MASK) == RUBY_T_FALSE
271    printf "T_FALSE: "
272    print (struct RBasic *)($arg0)
273  else
274  if ($flags & RUBY_T_MASK) == RUBY_T_DATA
275    if ((struct RTypedData *)($arg0))->typed_flag == 1
276      printf "T_DATA(%s): ", ((struct RTypedData *)($arg0))->type->wrap_struct_name
277      print (struct RTypedData *)($arg0)
278    else
279      printf "T_DATA: "
280      print (struct RData *)($arg0)
281    end
282  else
283  if ($flags & RUBY_T_MASK) == RUBY_T_MATCH
284    printf "T_MATCH: "
285    print (struct RMatch *)($arg0)
286  else
287  if ($flags & RUBY_T_MASK) == RUBY_T_SYMBOL
288    printf "T_SYMBOL: "
289    print (struct RBasic *)($arg0)
290  else
291  if ($flags & RUBY_T_MASK) == RUBY_T_UNDEF
292    printf "T_UNDEF: "
293    print (struct RBasic *)($arg0)
294  else
295  if ($flags & RUBY_T_MASK) == RUBY_T_NODE
296    printf "T_NODE("
297    output (enum node_type)(($flags&RUBY_NODE_TYPEMASK)>>RUBY_NODE_TYPESHIFT)
298    printf "): "
299    print *(NODE *)($arg0)
300  else
301  if ($flags & RUBY_T_MASK) == RUBY_T_ZOMBIE
302    printf "T_ZOMBIE: "
303    print (struct RData *)($arg0)
304  else
305    printf "unknown: "
306    print (struct RBasic *)($arg0)
307  end
308  end
309  end
310  end
311  end
312  end
313  end
314  end
315  end
316  end
317  end
318  end
319  end
320  end
321  end
322  end
323  end
324  end
325  end
326  end
327  end
328  end
329  end
330  end
331  end
332  end
333  end
334  end
335  end
336  end
337  end
338  end
339end
340document rp
341  Print a Ruby's VALUE.
342end
343
344define rp_class
345  printf "(struct RClass *) %p", (void*)$arg0
346  if ((struct RClass *)($arg0))->ptr.origin != $arg0
347    printf " -> %p", ((struct RClass *)($arg0))->ptr.origin
348  end
349  printf "\n"
350  print *(struct RClass *)($arg0)
351  print *((struct RClass *)($arg0))->ptr
352end
353document rp_class
354  Print the content of a Class/Module.
355end
356
357define nd_type
358  print (enum node_type)((((NODE*)($arg0))->flags&RUBY_NODE_TYPEMASK)>>RUBY_NODE_TYPESHIFT)
359end
360document nd_type
361  Print a Ruby' node type.
362end
363
364define nd_file
365  print ((NODE*)($arg0))->nd_file
366end
367document nd_file
368  Print the source file name of a node.
369end
370
371define nd_line
372  print ((unsigned int)((((NODE*)($arg0))->flags>>RUBY_NODE_LSHIFT)&RUBY_NODE_LMASK))
373end
374document nd_line
375  Print the source line number of a node.
376end
377
378# Print members of ruby node.
379
380define nd_head
381  printf "u1.node: "
382  rp ($arg0).u1.node
383end
384
385define nd_alen
386  printf "u2.argc: "
387  p ($arg0).u2.argc
388end
389
390define nd_next
391  printf "u3.node: "
392  rp ($arg0).u3.node
393end
394
395
396define nd_cond
397  printf "u1.node: "
398  rp ($arg0).u1.node
399end
400
401define nd_body
402  printf "u2.node: "
403  rp ($arg0).u2.node
404end
405
406define nd_else
407  printf "u3.node: "
408  rp ($arg0).u3.node
409end
410
411
412define nd_orig
413  printf "u3.value: "
414  rp ($arg0).u3.value
415end
416
417
418define nd_resq
419  printf "u2.node: "
420  rp ($arg0).u2.node
421end
422
423define nd_ensr
424  printf "u3.node: "
425  rp ($arg0).u3.node
426end
427
428
429define nd_1st
430  printf "u1.node: "
431  rp ($arg0).u1.node
432end
433
434define nd_2nd
435  printf "u2.node: "
436  rp ($arg0).u2.node
437end
438
439
440define nd_stts
441  printf "u1.node: "
442  rp ($arg0).u1.node
443end
444
445
446define nd_entry
447  printf "u3.entry: "
448  p ($arg0).u3.entry
449end
450
451define nd_vid
452  printf "u1.id: "
453  p ($arg0).u1.id
454end
455
456define nd_cflag
457  printf "u2.id: "
458  p ($arg0).u2.id
459end
460
461define nd_cval
462  printf "u3.value: "
463  rp ($arg0).u3.value
464end
465
466
467define nd_cnt
468  printf "u3.cnt: "
469  p ($arg0).u3.cnt
470end
471
472define nd_tbl
473  printf "u1.tbl: "
474  p ($arg0).u1.tbl
475end
476
477
478define nd_var
479  printf "u1.node: "
480  rp ($arg0).u1.node
481end
482
483define nd_ibdy
484  printf "u2.node: "
485  rp ($arg0).u2.node
486end
487
488define nd_iter
489  printf "u3.node: "
490  rp ($arg0).u3.node
491end
492
493
494define nd_value
495  printf "u2.node: "
496  rp ($arg0).u2.node
497end
498
499define nd_aid
500  printf "u3.id: "
501  p ($arg0).u3.id
502end
503
504
505define nd_lit
506  printf "u1.value: "
507  rp ($arg0).u1.value
508end
509
510
511define nd_frml
512  printf "u1.node: "
513  rp ($arg0).u1.node
514end
515
516define nd_rest
517  printf "u2.argc: "
518  p ($arg0).u2.argc
519end
520
521define nd_opt
522  printf "u1.node: "
523  rp ($arg0).u1.node
524end
525
526
527define nd_recv
528  printf "u1.node: "
529  rp ($arg0).u1.node
530end
531
532define nd_mid
533  printf "u2.id: "
534  p ($arg0).u2.id
535end
536
537define nd_args
538  printf "u3.node: "
539  rp ($arg0).u3.node
540end
541
542
543define nd_noex
544  printf "u1.id: "
545  p ($arg0).u1.id
546end
547
548define nd_defn
549  printf "u3.node: "
550  rp ($arg0).u3.node
551end
552
553
554define nd_old
555  printf "u1.id: "
556  p ($arg0).u1.id
557end
558
559define nd_new
560  printf "u2.id: "
561  p ($arg0).u2.id
562end
563
564
565define nd_cfnc
566  printf "u1.cfunc: "
567  p ($arg0).u1.cfunc
568end
569
570define nd_argc
571  printf "u2.argc: "
572  p ($arg0).u2.argc
573end
574
575
576define nd_cname
577  printf "u1.id: "
578  p ($arg0).u1.id
579end
580
581define nd_super
582  printf "u3.node: "
583  rp ($arg0).u3.node
584end
585
586
587define nd_modl
588  printf "u1.id: "
589  p ($arg0).u1.id
590end
591
592define nd_clss
593  printf "u1.value: "
594  rp ($arg0).u1.value
595end
596
597
598define nd_beg
599  printf "u1.node: "
600  rp ($arg0).u1.node
601end
602
603define nd_end
604  printf "u2.node: "
605  rp ($arg0).u2.node
606end
607
608define nd_state
609  printf "u3.state: "
610  p ($arg0).u3.state
611end
612
613define nd_rval
614  printf "u2.value: "
615  rp ($arg0).u2.value
616end
617
618
619define nd_nth
620  printf "u2.argc: "
621  p ($arg0).u2.argc
622end
623
624
625define nd_tag
626  printf "u1.id: "
627  p ($arg0).u1.id
628end
629
630define nd_tval
631  printf "u2.value: "
632  rp ($arg0).u2.value
633end
634
635define rb_p
636  call rb_p($arg0)
637end
638
639define rb_numtable_entry
640  set $rb_numtable_tbl = $arg0
641  set $rb_numtable_id = (st_data_t)$arg1
642  set $rb_numtable_key = 0
643  set $rb_numtable_rec = 0
644  if $rb_numtable_tbl->entries_packed
645    set $rb_numtable_p = $rb_numtable_tbl->as.packed.bins
646    while $rb_numtable_p && $rb_numtable_p < $rb_numtable_tbl->as.packed.bins+$rb_numtable_tbl->num_entries
647      if $rb_numtable_p.k == $rb_numtable_id
648	set $rb_numtable_key = $rb_numtable_p.k
649	set $rb_numtable_rec = $rb_numtable_p.v
650	set $rb_numtable_p = 0
651      else
652	set $rb_numtable_p = $rb_numtable_p + 1
653      end
654    end
655  else
656    set $rb_numtable_p = $rb_numtable_tbl->as.big.bins[$rb_numtable_id % $rb_numtable_tbl->num_bins]
657    while $rb_numtable_p
658      if $rb_numtable_p->key == $rb_numtable_id
659	set $rb_numtable_key = $rb_numtable_p->key
660	set $rb_numtable_rec = $rb_numtable_p->record
661	set $rb_numtable_p = 0
662      else
663	set $rb_numtable_p = $rb_numtable_p->next
664      end
665    end
666  end
667end
668
669define rb_id2name
670  rb_numtable_entry global_symbols.id_str (ID)$arg0
671  if $rb_numtable_rec
672    rp $rb_numtable_rec
673  else
674    echo undef\n
675  end
676end
677document rb_id2name
678  Print the name of id
679end
680
681define rb_method_entry
682  set $rb_method_entry_klass = (struct RClass *)$arg0
683  set $rb_method_entry_id = (ID)$arg1
684  set $rb_method_entry_me = (rb_method_entry_t *)0
685  while !$rb_method_entry_me && $rb_method_entry_klass
686    rb_numtable_entry $rb_method_entry_klass->m_tbl $rb_method_entry_id
687    set $rb_method_entry_me = (rb_method_entry_t *)$rb_numtable_rec
688    if !$rb_method_entry_me
689      set $rb_method_entry_klass = (struct RClass *)$rb_method_entry_klass->ptr->super
690    end
691  end
692  if $rb_method_entry_me
693    print *$rb_method_entry_klass
694    print *$rb_method_entry_me
695  else
696    echo method not found\n
697  end
698end
699document rb_method_entry
700  Search method entry by class and id
701end
702
703define rb_classname
704  call classname($arg0)
705  rb_p $
706  print *(struct RClass*)($arg0)
707end
708
709define rb_ancestors
710  set $rb_ancestors_module = $arg0
711  while $rb_ancestors_module
712    rp $rb_ancestors_module
713    set $rb_ancestors_module = ((struct RClass *)($rb_ancestors_module))->ptr.super
714  end
715end
716document rb_ancestors
717  Print ancestors.
718end
719
720define rb_backtrace
721  call rb_backtrace()
722end
723
724define iseq
725  if ruby_dummy_gdb_enums.special_consts
726  end
727  if ($arg0)->type == ISEQ_ELEMENT_NONE
728    echo [none]\n
729  end
730  if ($arg0)->type == ISEQ_ELEMENT_LABEL
731    print *(LABEL*)($arg0)
732  end
733  if ($arg0)->type == ISEQ_ELEMENT_INSN
734    print *(INSN*)($arg0)
735    if ((INSN*)($arg0))->insn_id != YARVINSN_jump
736      set $i = 0
737      set $operand_size = ((INSN*)($arg0))->operand_size
738      set $operands = ((INSN*)($arg0))->operands
739      while $i < $operand_size
740	rp $operands[$i++]
741      end
742    end
743  end
744  if ($arg0)->type == ISEQ_ELEMENT_ADJUST
745    print *(ADJUST*)($arg0)
746  end
747end
748
749define rb_ps
750  rb_ps_vm ruby_current_vm
751end
752document rb_ps
753Dump all threads and their callstacks
754end
755
756define rb_ps_vm
757  print $ps_vm = (rb_vm_t*)$arg0
758  set $ps_threads = (st_table*)$ps_vm->living_threads
759  if $ps_threads->entries_packed
760    set $ps_threads_i = 0
761    while $ps_threads_i < $ps_threads->num_entries
762      set $ps_threads_key = (st_data_t)$ps_threads->as.packed.entries[$ps_threads_i].key
763      set $ps_threads_val = (st_data_t)$ps_threads->as.packed.entries[$ps_threads_i].val
764      rb_ps_thread $ps_threads_key $ps_threads_val
765      set $ps_threads_i = $ps_threads_i + 1
766    end
767  else
768    set $ps_threads_ptr = (st_table_entry*)$ps_threads->head
769    while $ps_threads_ptr
770      set $ps_threads_key = (st_data_t)$ps_threads_ptr->key
771      set $ps_threads_val = (st_data_t)$ps_threads_ptr->record
772      rb_ps_thread $ps_threads_key $ps_threads_val
773      set $ps_threads_ptr = (st_table_entry*)$ps_threads_ptr->fore
774    end
775  end
776end
777document rb_ps_vm
778Dump all threads in a (rb_vm_t*) and their callstacks
779end
780
781define rb_ps_thread
782  set $ps_thread = (struct RTypedData*)$arg0
783  set $ps_thread_id = $arg1
784  print $ps_thread_th = (rb_thread_t*)$ps_thread->data
785end
786
787# Details: https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/MachineInstructionsTraceWithGDB
788define trace_machine_instructions
789  set logging on
790  set height 0
791  set width 0
792  display/i $pc
793  while !$exit_code
794    info line *$pc
795    si
796  end
797end
798
799define SDR
800  call rb_vmdebug_stack_dump_raw_current()
801end
802
803