@@ -413,6 +413,13 @@ document rp_id
413
413
Print an ID.
414
414
end
415
415
416
+ define output_string
417
+ set $flags = ((struct RBasic*)($arg0 ))->flags
418
+ printf " %s" , (char *)(($flags & RUBY_FL_USER1) ? \
419
+ ((struct RString*)($arg0 ))->as.heap.ptr : \
420
+ ((struct RString*)($arg0 ))->as.ary)
421
+ end
422
+
416
423
define rp_string
417
424
set $flags = ((struct RBasic*)($arg0 ))->flags
418
425
set print address off
@@ -936,11 +943,226 @@ document rb_ps_vm
936
943
Dump all threads in a (rb_vm_t*) and their callstacks
937
944
end
938
945
946
+ define print_lineno
947
+ set $cfp = $arg0
948
+ set $iseq = $cfp ->iseq
949
+ set $pos = $cfp ->pc - $iseq ->body->iseq_encoded
950
+ if $pos != 0
951
+ set $pos = $pos - 1
952
+ end
953
+
954
+ set $i = 0
955
+ set $size = $iseq ->body->line_info_size
956
+ set $table = $iseq ->body->line_info_table
957
+ # printf "size: %d\n", $size
958
+ if $size == 0
959
+ else
960
+ set $i = 1
961
+ while $i < $size
962
+ # printf "table[%d]: position: %d, line: %d, pos: %d\n", $i, $table[$i].position, $table[$i].line_no, $pos
963
+ if $table [$i ].position > $pos
964
+ loop_break
965
+ end
966
+ set $i = $i + 1
967
+ if $table [$i ].position == $pos
968
+ loop_break
969
+ end
970
+ end
971
+ printf " %d" , $table [$i -1 ].line_no
972
+ end
973
+ end
974
+
975
+ define check_method_entry
976
+ # get $immeo and $can_be_svar and return $me
977
+ set $imemo = (struct RBasic *)$arg0
978
+ set $can_be_svar = $arg1
979
+ if $imemo != Qfalse
980
+ set $type = ($imemo ->flags >> 12 ) & 0x07
981
+ if $type == imemo_ment
982
+ set $me = (rb_callable_method_entry_t *)$imemo
983
+ else
984
+ if $type == imemo_svar
985
+ set $imemo == ((struct vm_svar *)$imemo )->cref_or_me
986
+ check_method_entry $imemo 0
987
+ end
988
+ end
989
+ end
990
+ end
991
+
992
+ define output_id
993
+ set $id = $arg0
994
+ # rb_id_to_serial
995
+ if $id > tLAST_OP_ID
996
+ set $serial = (rb_id_serial_t)($id >> ID_SCOPE_SHIFT)
997
+ else
998
+ set $serial = (rb_id_serial_t)$id
999
+ end
1000
+ if $serial && $serial <= global_symbols.last_id
1001
+ set $idx = $serial / ID_ENTRY_UNIT
1002
+ set $ids = (struct RArray *)global_symbols.ids
1003
+ set $flags = $ids ->basic.flags
1004
+ if ($flags & RUBY_FL_USER1)
1005
+ set $idsptr = $ids ->as.ary
1006
+ set $idslen = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3 ))
1007
+ else
1008
+ set $idsptr = $ids ->as.heap.ptr
1009
+ set $idslen = $ids ->as.heap.len
1010
+ end
1011
+ if $idx < $idslen
1012
+ set $t = 0
1013
+ set $ary = (struct RArray *)$idsptr [$idx ]
1014
+ if $ary != Qnil
1015
+ set $flags = $ary ->basic.flags
1016
+ if ($flags & RUBY_FL_USER1)
1017
+ set $aryptr = $ary ->as.ary
1018
+ set $arylen = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3 ))
1019
+ else
1020
+ set $aryptr = $ary ->as.heap.ptr
1021
+ set $arylen = $ary ->as.heap.len
1022
+ end
1023
+ set $result = $aryptr [($serial % ID_ENTRY_UNIT) * ID_ENTRY_SIZE + $t ]
1024
+ output_string $result
1025
+ end
1026
+ end
1027
+ end
1028
+ end
1029
+
939
1030
define rb_ps_thread
940
1031
set $ps_thread = (struct RTypedData*)$arg0
941
1032
set $ps_thread_th = (rb_thread_t*)$ps_thread ->data
942
1033
printf " * #<Thread:%p rb_thread_t:%p native_thread:%p>\n " , \
943
1034
$ps_thread , $ps_thread_th , $ps_thread_th ->thread_id
1035
+ set $cfp = $ps_thread_th ->cfp
1036
+ set $cfpend = (rb_control_frame_t *)($ps_thread_th ->stack + $ps_thread_th ->stack_size)-1
1037
+ while $cfp < $cfpend
1038
+ if $cfp ->iseq
1039
+ if $cfp ->pc
1040
+ set $location = $cfp ->iseq->body->location
1041
+ output_string $location .path
1042
+ printf " :"
1043
+ print_lineno $cfp
1044
+ printf " :in `"
1045
+ output_string $location .label
1046
+ printf " '\n "
1047
+ else
1048
+ printf " ???.rb:???:in `???'\n "
1049
+ end
1050
+ else
1051
+ # if ($cfp->flag & VM_FRAME_MAGIC_MASK) == VM_FRAME_MAGIC_CFUNC
1052
+ if ($cfp ->flag & 255 ) == 0x61
1053
+ # define VM_ENVVAL_BLOCK_PTR_FLAG 0x02
1054
+ # define VM_EP_PREV_EP(ep) ((VALUE *)GC_GUARDED_PTR_REF((ep)[0]))
1055
+ set $ep = $cfp ->ep
1056
+ set $me = NULL
1057
+ while ($ep [0 ] & 0x02 ) != 0
1058
+ check_method_entry $ep [-1 ] 0
1059
+ if $me != NULL
1060
+ loop_break
1061
+ end
1062
+ set $ep = $ep [0 ]
1063
+ end
1064
+ if $me == NULL
1065
+ check_method_entry $ep [-1 ] 1
1066
+ end
1067
+ set print symbol -filename on
1068
+ output /a $me ->def->body.cfunc.func
1069
+ set print symbol -filename off
1070
+ set $mid = $me ->def->original_id
1071
+ printf " :in `"
1072
+ output_id $mid
1073
+ printf " '\n "
1074
+ else
1075
+ printf " unknown_frame:???:in `???'\n "
1076
+ end
1077
+ end
1078
+ set $cfp = $cfp + 1
1079
+ end
1080
+ end
1081
+
1082
+ define rb_count_objects
1083
+ set $objspace = ruby_current_vm->objspace
1084
+ set $counts_00 = 0
1085
+ set $counts_01 = 0
1086
+ set $counts_02 = 0
1087
+ set $counts_03 = 0
1088
+ set $counts_04 = 0
1089
+ set $counts_05 = 0
1090
+ set $counts_06 = 0
1091
+ set $counts_07 = 0
1092
+ set $counts_08 = 0
1093
+ set $counts_09 = 0
1094
+ set $counts_0a = 0
1095
+ set $counts_0b = 0
1096
+ set $counts_0c = 0
1097
+ set $counts_0d = 0
1098
+ set $counts_0e = 0
1099
+ set $counts_0f = 0
1100
+ set $counts_10 = 0
1101
+ set $counts_11 = 0
1102
+ set $counts_12 = 0
1103
+ set $counts_13 = 0
1104
+ set $counts_14 = 0
1105
+ set $counts_15 = 0
1106
+ set $counts_16 = 0
1107
+ set $counts_17 = 0
1108
+ set $counts_18 = 0
1109
+ set $counts_19 = 0
1110
+ set $counts_1a = 0
1111
+ set $counts_1b = 0
1112
+ set $counts_1c = 0
1113
+ set $counts_1d = 0
1114
+ set $counts_1e = 0
1115
+ set $counts_1f = 0
1116
+ set $total = 0
1117
+ set $i = 0
1118
+ while $i < $objspace ->heap_pages.allocated_pages
1119
+ printf " \r counting... %d/%d" , $i , $objspace ->heap_pages.allocated_pages
1120
+ set $page = $objspace ->heap_pages.sorted[$i ]
1121
+ set $p = $page ->start
1122
+ set $pend = $p + $page ->total_slots
1123
+ while $p < $pend
1124
+ set $flags = $p ->as.basic.flags & 0x1f
1125
+ eval " set $counts_%02x = $counts_%02x + 1" , $flags , $flags
1126
+ set $p = $p + 1
1127
+ end
1128
+ set $total = $total + $page ->total_slots
1129
+ set $i = $i + 1
1130
+ end
1131
+ printf " \r TOTAL: %d, FREE: %d\n " , $total , $counts_00
1132
+ printf " T_OBJECT: %d\n " , $counts_01
1133
+ printf " T_CLASS: %d\n " , $counts_02
1134
+ printf " T_MODULE: %d\n " , $counts_03
1135
+ printf " T_FLOAT: %d\n " , $counts_04
1136
+ printf " T_STRING: %d\n " , $counts_05
1137
+ printf " T_REGEXP: %d\n " , $counts_06
1138
+ printf " T_ARRAY: %d\n " , $counts_07
1139
+ printf " T_HASH: %d\n " , $counts_08
1140
+ printf " T_STRUCT: %d\n " , $counts_09
1141
+ printf " T_BIGNUM: %d\n " , $counts_0a
1142
+ printf " T_FILE: %d\n " , $counts_0b
1143
+ printf " T_DATA: %d\n " , $counts_0c
1144
+ printf " T_MATCH: %d\n " , $counts_0d
1145
+ printf " T_COMPLEX: %d\n " , $counts_0e
1146
+ printf " T_RATIONAL: %d\n " , $counts_0f
1147
+ # printf "UNKNOWN_10: %d\n", $counts_10
1148
+ printf " T_NIL: %d\n " , $counts_11
1149
+ printf " T_TRUE: %d\n " , $counts_12
1150
+ printf " T_FALSE: %d\n " , $counts_13
1151
+ printf " T_SYMBOL: %d\n " , $counts_14
1152
+ printf " T_FIXNUM: %d\n " , $counts_15
1153
+ printf " T_UNDEF: %d\n " , $counts_16
1154
+ # printf "UNKNOWN_17: %d\n", $counts_17
1155
+ # printf "UNKNOWN_18: %d\n", $counts_18
1156
+ # printf "UNKNOWN_19: %d\n", $counts_19
1157
+ printf " T_IMEMO: %d\n " , $counts_1a
1158
+ printf " T_NODE: %d\n " , $counts_1b
1159
+ printf " T_ICLASS: %d\n " , $counts_1c
1160
+ printf " T_ZOMBIE: %d\n " , $counts_1d
1161
+ # printf "UNKNOWN_1E: %d\n", $counts_1e
1162
+ printf " T_MASK: %d\n " , $counts_1f
1163
+ end
1164
+ document rb_count_objects
1165
+ Counts all objects grouped by type.
944
1166
end
945
1167
946
1168
# Details: https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/MachineInstructionsTraceWithGDB
0 commit comments