gdb.rb 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ diff --git a/python/py-value.c b/python/py-value.c
2
+ index 0146593..8f8c610 100644
3
+ --- a/python/py-value.c
4
+ +++ b/python/py-value.c
5
+ @@ -972,6 +972,27 @@ gdbpy_history (PyObject *self, PyObject *args)
6
+ return value_to_value_object (res_val);
7
+ }
8
+
9
+ +/* Returns value object for a given expression. */
10
+ +PyObject *
11
+ +gdbpy_eval (PyObject *self, PyObject *args)
12
+ +{
13
+ + char *arg;
14
+ + struct value *res_val = NULL; /* Initialize to appease gcc warning. */
15
+ + volatile struct gdb_exception except;
16
+ +
17
+ + if (! PyArg_ParseTuple (args, "s", &arg))
18
+ + return NULL;
19
+ +
20
+ + TRY_CATCH (except, RETURN_MASK_ALL)
21
+ + {
22
+ + res_val = parse_and_eval (arg);
23
+ + }
24
+ + GDB_PY_HANDLE_EXCEPTION (except);
25
+ +
26
+ + return value_to_value_object (res_val);
27
+ +}
28
+ +
29
+ +
30
+ void
31
+ gdbpy_initialize_values (void)
32
+ {
33
+ diff --git a/python/python-internal.h b/python/python-internal.h
34
+ index 67a78af..fbf8247 100644
35
+ --- a/python/python-internal.h
36
+ +++ b/python/python-internal.h
37
+ @@ -68,6 +68,7 @@ extern PyObject *gdb_module;
38
+ extern PyTypeObject value_object_type;
39
+
40
+ PyObject *gdbpy_history (PyObject *self, PyObject *args);
41
+ +PyObject *gdbpy_eval (PyObject *self, PyObject *args);
42
+ PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
43
+ PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
44
+ PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
45
+ diff --git a/python/python.c b/python/python.c
46
+ index 254bd28..c96fa29 100644
47
+ --- a/python/python.c
48
+ +++ b/python/python.c
49
+ @@ -651,6 +651,8 @@ static PyMethodDef GdbMethods[] =
50
+ {
51
+ { "history", gdbpy_history, METH_VARARGS,
52
+ "Get a value from history" },
53
+ + { "eval", gdbpy_eval, METH_VARARGS,
54
+ + "Get a value of an expression" },
55
+ { "execute", execute_gdb_command, METH_VARARGS,
56
+ "Execute a gdb command" },
57
+ { "parameter", gdbpy_parameter, METH_VARARGS,
@@ -0,0 +1,183 @@
1
+ diff --git a/python/py-value.c b/python/py-value.c
2
+ index 8f8c610..c3a6cbf 100644
3
+ --- a/python/py-value.c
4
+ +++ b/python/py-value.c
5
+ @@ -139,7 +139,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
6
+ }
7
+
8
+ value_obj->value = value;
9
+ - value_incref (value);
10
+ + release_value_or_incref (value);
11
+ value_obj->address = NULL;
12
+ value_obj->type = NULL;
13
+ note_value (value_obj);
14
+ @@ -263,6 +263,7 @@ valpy_cast (PyObject *self, PyObject *args)
15
+ {
16
+ PyObject *type_obj;
17
+ struct type *type;
18
+ + PyObject *res_obj = NULL;
19
+ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
20
+ volatile struct gdb_exception except;
21
+
22
+ @@ -301,8 +302,10 @@ valpy_getitem (PyObject *self, PyObject *key)
23
+ {
24
+ value_object *self_value = (value_object *) self;
25
+ char *field = NULL;
26
+ + PyObject *res_obj = NULL;
27
+ struct value *res_val = NULL;
28
+ volatile struct gdb_exception except;
29
+ + struct value *mark = value_mark ();
30
+
31
+ if (gdbpy_is_string (key))
32
+ {
33
+ @@ -340,9 +343,13 @@ valpy_getitem (PyObject *self, PyObject *key)
34
+ }
35
+
36
+ xfree (field);
37
+ - GDB_PY_HANDLE_EXCEPTION (except);
38
+ + GDB_PY_HANDLE_EXCEPTION_AND_CLEANUP (except, mark);
39
+ +
40
+ + if (res_val)
41
+ + res_obj = value_to_value_object (res_val);
42
+
43
+ - return res_val ? value_to_value_object (res_val) : NULL;
44
+ + value_free_to_mark (mark);
45
+ + return res_obj;
46
+ }
47
+
48
+ static int
49
+ @@ -423,8 +430,10 @@ enum valpy_opcode
50
+ static PyObject *
51
+ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
52
+ {
53
+ + PyObject *res_obj = NULL;
54
+ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
55
+ volatile struct gdb_exception except;
56
+ + struct value *mark = value_mark ();
57
+
58
+ TRY_CATCH (except, RETURN_MASK_ALL)
59
+ {
60
+ @@ -515,9 +524,13 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
61
+ break;
62
+ }
63
+ }
64
+ - GDB_PY_HANDLE_EXCEPTION (except);
65
+ + GDB_PY_HANDLE_EXCEPTION_AND_CLEANUP (except, mark);
66
+ +
67
+ + if (res_val)
68
+ + res_obj = value_to_value_object (res_val);
69
+
70
+ - return res_val ? value_to_value_object (res_val) : NULL;
71
+ + value_free_to_mark (mark);
72
+ + return res_obj;
73
+ }
74
+
75
+ static PyObject *
76
+ @@ -680,6 +693,7 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
77
+ int result = 0;
78
+ struct value *value_other;
79
+ volatile struct gdb_exception except;
80
+ + struct value *mark = value_mark ();
81
+
82
+ if (other == Py_None)
83
+ /* Comparing with None is special. From what I can tell, in Python
84
+ @@ -738,6 +752,7 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
85
+ break;
86
+ }
87
+ }
88
+ + value_free_to_mark (mark);
89
+ GDB_PY_HANDLE_EXCEPTION (except);
90
+
91
+ /* In this case, the Python exception has already been set. */
92
+ @@ -858,7 +873,7 @@ value_to_value_object (struct value *val)
93
+ if (val_obj != NULL)
94
+ {
95
+ val_obj->value = val;
96
+ - value_incref (val);
97
+ + release_value_or_incref (val);
98
+ val_obj->address = NULL;
99
+ val_obj->type = NULL;
100
+ note_value (val_obj);
101
+ diff --git a/python/python-internal.h b/python/python-internal.h
102
+ index fa4a62b..bc9c8c0 100644
103
+ --- a/python/python-internal.h
104
+ +++ b/python/python-internal.h
105
+ @@ -103,11 +103,17 @@ extern const struct language_defn *python_language;
106
+ /* Use this after a TRY_EXCEPT to throw the appropriate Python
107
+ exception. */
108
+ #define GDB_PY_HANDLE_EXCEPTION(Exception) \
109
+ + GDB_PY_HANDLE_EXCEPTION_AND_CLEANUP(Exception, NULL)
110
+ +
111
+ +#define GDB_PY_HANDLE_EXCEPTION_AND_CLEANUP(Exception, mark) \
112
+ do { \
113
+ - if (Exception.reason < 0) \
114
+ + if (Exception.reason < 0) { \
115
+ + if (mark) \
116
+ + value_free_to_mark (mark); \
117
+ return PyErr_Format (Exception.reason == RETURN_QUIT \
118
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
119
+ "%s", Exception.message); \
120
+ + } \
121
+ } while (0)
122
+
123
+
124
+ diff --git a/value.c b/value.c
125
+ index 589e03b..59a0196 100644
126
+ --- a/value.c
127
+ +++ b/value.c
128
+ @@ -675,7 +675,7 @@ free_all_values (void)
129
+ /* Remove VAL from the chain all_values
130
+ so it will not be freed automatically. */
131
+
132
+ -void
133
+ +int
134
+ release_value (struct value *val)
135
+ {
136
+ struct value *v;
137
+ @@ -683,7 +683,7 @@ release_value (struct value *val)
138
+ if (all_values == val)
139
+ {
140
+ all_values = val->next;
141
+ - return;
142
+ + return 1;
143
+ }
144
+
145
+ for (v = all_values; v; v = v->next)
146
+ @@ -691,9 +691,21 @@ release_value (struct value *val)
147
+ if (v->next == val)
148
+ {
149
+ v->next = val->next;
150
+ - break;
151
+ + return 1;
152
+ }
153
+ }
154
+ +
155
+ + return 0;
156
+ +}
157
+ +
158
+ +/* Release VAL or increment its reference count if
159
+ + it was released already */
160
+ +
161
+ +void
162
+ +release_value_or_incref (struct value *val)
163
+ +{
164
+ + if (release_value (val) == 0)
165
+ + value_incref (val);
166
+ }
167
+
168
+ /* Release all values up to mark */
169
+ diff --git a/value.h b/value.h
170
+ index 51e6960..4760c4a 100644
171
+ --- a/value.h
172
+ +++ b/value.h
173
+ @@ -594,7 +594,9 @@ extern void value_free (struct value *val);
174
+
175
+ extern void free_all_values (void);
176
+
177
+ -extern void release_value (struct value *val);
178
+ +extern int release_value (struct value *val);
179
+ +
180
+ +extern void release_value_or_incref (struct value *val);
181
+
182
+ extern int record_latest_value (struct value *val);
183
+
@@ -0,0 +1,404 @@
1
+ import re
2
+ import gdb
3
+
4
+ class ZeroDict(dict):
5
+ def __getitem__(self, i):
6
+ if i not in self: self[i] = 0
7
+ return dict.__getitem__(self, i)
8
+
9
+ class Ruby (gdb.Command):
10
+ def __init__ (self):
11
+ super (Ruby, self).__init__ ("ruby", gdb.COMMAND_NONE, gdb.COMPLETE_COMMAND, True)
12
+
13
+ class RubyThreads (gdb.Command):
14
+ def __init__ (self):
15
+ super (RubyThreads, self).__init__ ("ruby threads", gdb.COMMAND_NONE)
16
+
17
+ def complete (self, text, word):
18
+ if text == word:
19
+ if word == '':
20
+ return ['trace', 'list']
21
+ elif word[0] == 't':
22
+ return ['trace']
23
+ elif word[0] == 'l':
24
+ return ['list']
25
+
26
+ def invoke (self, arg, from_tty):
27
+ if re.match('trace', arg):
28
+ self.trace()
29
+ else:
30
+ self.type = arg if arg == 'list' else None
31
+ self.show()
32
+
33
+ def trace (self):
34
+ self.type = 'list'
35
+ self.curr = None
36
+ self.main = gdb.eval('rb_main_thread')
37
+
38
+ self.height = gdb.parameter('height') or 26
39
+ self.unwind = gdb.parameter('unwindonsignal')
40
+ gdb.execute('set height 0')
41
+ gdb.execute('set unwindonsignal on')
42
+
43
+ gdb.execute('watch rb_curr_thread')
44
+ gdb.breakpoints()[-1].silent = True
45
+ num = gdb.breakpoints()[-1].number
46
+
47
+ try:
48
+ prev = None
49
+ while True:
50
+ gdb.execute('continue')
51
+ curr = gdb.eval('rb_curr_thread')
52
+ if curr == prev: break
53
+ self.print_thread(curr)
54
+ prev = curr
55
+ except KeyboardInterrupt:
56
+ None
57
+
58
+ gdb.execute('delete %d' % num)
59
+ gdb.execute('set unwindonsignal %s' % ('on' if self.unwind else 'off'))
60
+ gdb.execute('set height %d' % self.height)
61
+
62
+ def show (self):
63
+ self.main = gdb.eval('rb_main_thread')
64
+ self.curr = gdb.eval('rb_curr_thread')
65
+ self.now = gdb.eval('timeofday()')
66
+
67
+ try:
68
+ gdb.eval('rb_thread_start_2')
69
+ except RuntimeError:
70
+ self.is_heap_stack = False
71
+ else:
72
+ self.is_heap_stack = True
73
+
74
+ if self.main == 0:
75
+ print "Ruby VM is not running!"
76
+ else:
77
+ th = self.main
78
+ while True:
79
+ self.print_thread(th)
80
+ th = th['next']
81
+ if th == self.main: break
82
+
83
+ print
84
+
85
+ def print_thread (self, th):
86
+ if self.type != 'list': print
87
+ print th,
88
+ print 'main' if th == self.main else ' ',
89
+ print 'curr' if th == self.curr else ' ',
90
+ print "thread", " %s" % str(th['status']).ljust(16), "%s" % self.wait_state(th), " ",
91
+ if th != self.curr:
92
+ print "% 8d bytes" % th['stk_len']
93
+ else:
94
+ print
95
+
96
+ if self.type == 'list': return
97
+
98
+ if th == self.curr:
99
+ frame = gdb.eval('ruby_frame')
100
+ node = gdb.eval('ruby_current_node')
101
+ else:
102
+ frame = th['frame']
103
+ node = frame['node']
104
+
105
+ self.print_stack(th, frame, node)
106
+
107
+ def wait_state (self, th):
108
+ mask = th['wait_for']
109
+ state = list()
110
+ if mask == 0: state.append('WAIT_NONE')
111
+ if mask & 1: state.append('WAIT_FD(%d)' % th['fd'])
112
+ if mask & 2: state.append('WAIT_SELECT')
113
+ if mask & 4:
114
+ delay = th['delay']
115
+ time = delay-self.now
116
+ state.append('WAIT_TIME(%5.2f)' % time)
117
+ if mask & 8: state.append('WAIT_JOIN(%s)' % th['join'])
118
+ if mask & 16: state.append('WAIT_PID')
119
+ return ', '.join(state).ljust(22)
120
+
121
+ def print_stack (self, th, frame, node):
122
+ while True:
123
+ stk_pos = th['stk_pos']
124
+ stk_ptr = th['stk_ptr']
125
+ stk_len = th['stk_len']
126
+ addr = gdb.eval('(VALUE*)%s' % frame)
127
+
128
+ if not self.is_heap_stack and th != self.curr and stk_pos < addr and addr < (stk_pos+stk_len):
129
+ frame = (addr-stk_pos) + stk_ptr
130
+ frame = gdb.eval('(struct FRAME *)%s' % frame)
131
+ node = frame['node']
132
+
133
+ file = node['nd_file'].string()
134
+ line = gdb.eval('nd_line(%s)' % node)
135
+ type = gdb.eval('(enum node_type) nd_type(%s)' % node)
136
+
137
+ if frame['last_func']:
138
+ method = gdb.eval('rb_id2name(%s)' % frame['last_func']).string()
139
+ else:
140
+ method = '(unknown)'
141
+
142
+ print " ",
143
+ print str(type).lower().center(18), "%s in %s:%d" % (method, file, line)
144
+
145
+ if frame['prev'] == 0 or frame['last_func'] == 0: break
146
+ frame = frame['prev']
147
+ node = frame['node']
148
+ if node == 0: break
149
+
150
+ class RubyTrace (gdb.Command):
151
+ def __init__ (self):
152
+ super (RubyTrace, self).__init__ ("ruby trace", gdb.COMMAND_NONE, gdb.COMPLETE_NONE)
153
+
154
+ def setup (self):
155
+ commands = """
156
+ set $func = malloc(1)
157
+ p ((char*)$func)[0] = '\xc3'
158
+ p mprotect(($func&0xfffffffffffff000), 1, 0x7)
159
+ p rb_add_event_hook($func, RUBY_EVENT_C_CALL|RUBY_EVENT_CALL)
160
+ b *$func
161
+ """.split("\n")
162
+
163
+ for c in commands:
164
+ gdb.execute(c)
165
+
166
+ gdb.breakpoints()[-1].silent = True
167
+ self.func = gdb.eval('$func')
168
+
169
+ self.height = gdb.parameter('height') or 26
170
+ self.unwind = gdb.parameter('unwindonsignal')
171
+ gdb.execute('set height 0')
172
+ gdb.execute('set unwindonsignal on')
173
+
174
+ def teardown (self):
175
+ commands = """
176
+ finish
177
+ clear *$func
178
+ p mprotect(($func&0xfffffffffffff000), 1, 0x3)
179
+ p rb_remove_event_hook($func)
180
+ p free($func)
181
+ set $func = 0
182
+ """.split("\n")
183
+
184
+ for c in commands:
185
+ gdb.execute(c)
186
+
187
+ gdb.execute('set unwindonsignal %s' % ('on' if self.unwind else 'off'))
188
+ gdb.execute('set height %d' % self.height)
189
+
190
+ def invoke (self, arg, from_tty):
191
+ self.dont_repeat()
192
+ num = int(arg) if arg else 100
193
+ self.setup()
194
+
195
+ try:
196
+ while num > 0:
197
+ num -= 1
198
+ gdb.execute('continue')
199
+
200
+ frame = gdb.selected_frame()
201
+ if frame.pc() != self.func:
202
+ raise KeyboardInterrupt
203
+
204
+ node = gdb.eval('(NODE*) $rsi')
205
+ file = node['nd_file'].string()
206
+ line = gdb.eval('nd_line(%s)' % node)
207
+ method = gdb.eval('rb_id2name($rcx)')
208
+ method = method.string() if method > 0 else '(unknown)'
209
+
210
+ print "%s in %s:%d" % (method,file,line)
211
+
212
+ self.teardown()
213
+ except KeyboardInterrupt:
214
+ self.teardown()
215
+ except RuntimeError, text:
216
+ self.teardown()
217
+ if not re.search('signaled while in a function called from GDB', text):
218
+ raise
219
+
220
+ class RubyObjects (gdb.Command):
221
+ def __init__ (self):
222
+ super (RubyObjects, self).__init__ ("ruby objects", gdb.COMMAND_NONE)
223
+
224
+ def invoke (self, arg, from_tty):
225
+ self.height = gdb.parameter('height') or 26
226
+ gdb.execute('set height 0')
227
+
228
+ if arg == 'classes':
229
+ self.print_classes()
230
+ elif arg == 'nodes':
231
+ self.print_nodes()
232
+ elif arg == 'strings':
233
+ self.print_strings()
234
+ else:
235
+ self.print_stats()
236
+
237
+ gdb.execute('set height %d' % self.height)
238
+
239
+ def complete (self, text, word):
240
+ if text == word:
241
+ if word == '':
242
+ return ['classes', 'strings', 'nodes']
243
+ elif word[0] == 'c':
244
+ return ['classes']
245
+ elif word[0] == 'n':
246
+ return ['nodes']
247
+ elif word[0] == 's':
248
+ return ['strings']
249
+
250
+ def print_nodes (self):
251
+ nodes = ZeroDict()
252
+
253
+ for (obj, type) in self.live_objects():
254
+ if type == 0x3f:
255
+ nodes[ (int(obj['as']['node']['flags']) >> 12) & 0xff ] += 1
256
+
257
+ for (node, num) in sorted(nodes.items(), key=lambda(k,v):(v,k)):
258
+ print "% 8d %s" % (num, gdb.eval('(enum node_type) (%d)' % node))
259
+
260
+ def print_classes (self):
261
+ classes = ZeroDict()
262
+
263
+ for (obj, type) in self.live_objects():
264
+ if type == 0x2:
265
+ classes[ int(obj['as']['basic']['klass']) ] += 1
266
+
267
+ for (klass, num) in sorted(classes.items(), key=lambda(k,v):(v,k)):
268
+ print "% 8d %s" % (num, gdb.eval('rb_class2name(%d)' % klass).string())
269
+
270
+ def print_strings (self):
271
+ strings = ZeroDict()
272
+ bytes = 0
273
+
274
+ for (obj, type) in self.live_objects():
275
+ if type == 0x7:
276
+ s = obj['as']['string']
277
+ ptr = s['ptr']
278
+ if ptr:
279
+ bytes += s['len']
280
+ strings[ ptr.string() ] += 1
281
+
282
+ for (s, num) in sorted(strings.items(), key=lambda(k,v):(v,k)):
283
+ print "% 9d" % num, repr(s)
284
+
285
+ print
286
+ print "% 9d" % len(strings), "unique strings"
287
+ print "% 9d" % bytes, "bytes"
288
+ print
289
+
290
+ def print_stats (self):
291
+ total = live = free = 0
292
+ types = ZeroDict()
293
+
294
+ for (obj, flags) in self.all_objects():
295
+ if flags:
296
+ live += 1
297
+ types[ int(flags & 0x3f) ] += 1
298
+ else:
299
+ free += 1
300
+
301
+ total += 1
302
+
303
+ print
304
+ print " HEAPS % 9d" % self.heaps_used
305
+ print " SLOTS % 9d" % total
306
+ print " LIVE % 9d (%3.2f%%)" % (live, 100.0*live/total)
307
+ print " FREE % 9d (%3.2f%%)" % (free, 100.0*free/total)
308
+ print
309
+
310
+ for (type, num) in sorted(types.items(), key=lambda(k,v):(v,k)):
311
+ print " %s % 9d (%3.2f%%)" % (self.obj_type(type).ljust(8), num, 100.0*num/live)
312
+
313
+ print
314
+
315
+ def all_objects (self):
316
+ self.heaps_used = gdb.eval('heaps_used')
317
+
318
+ for i in xrange(self.heaps_used):
319
+ p = gdb.eval("(RVALUE*) heaps[%i].slot" % i)
320
+ pend = p + gdb.eval("heaps[%i].limit" % i)
321
+
322
+ while p < pend:
323
+ yield p, p['as']['basic']['flags']
324
+ p += 1
325
+
326
+ def live_objects (self):
327
+ for (obj, flags) in self.all_objects():
328
+ if flags:
329
+ yield obj, int(flags & 0x3f)
330
+
331
+ def obj_type (self, type):
332
+ return RubyObjects.TYPES.get(type, 'unknown')
333
+
334
+ Ruby()
335
+ RubyThreads()
336
+ RubyTrace()
337
+ RubyObjects()
338
+
339
+ macros = """
340
+ macro define R_CAST(st) (struct st*)
341
+ macro define RNODE(obj) (R_CAST(RNode)(obj))
342
+ macro define FL_USHIFT 12
343
+ macro define CHAR_BIT 8
344
+ macro define NODE_LSHIFT (FL_USHIFT+8)
345
+ macro define NODE_LMASK (((long)1<<(sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT))-1)
346
+ macro define nd_line(n) ((unsigned int)(((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK))
347
+ macro define nd_type(n) ((int)(((RNODE(n))->flags>>FL_USHIFT)&0xff))
348
+
349
+ macro define T_MASK 0x3f
350
+ macro define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
351
+
352
+ macro define WAIT_FD (1<<0)
353
+ macro define WAIT_SELECT (1<<1)
354
+ macro define WAIT_TIME (1<<2)
355
+ macro define WAIT_JOIN (1<<3)
356
+ macro define WAIT_PID (1<<4)
357
+
358
+ macro define RUBY_EVENT_CALL 0x08
359
+ macro define RUBY_EVENT_C_CALL 0x20
360
+ """.split("\n")
361
+
362
+ for m in macros:
363
+ if len(m.strip()) > 0:
364
+ gdb.execute(m)
365
+
366
+ types = """
367
+ T_NONE 0x00
368
+
369
+ T_NIL 0x01
370
+ T_OBJECT 0x02
371
+ T_CLASS 0x03
372
+ T_ICLASS 0x04
373
+ T_MODULE 0x05
374
+ T_FLOAT 0x06
375
+ T_STRING 0x07
376
+ T_REGEXP 0x08
377
+ T_ARRAY 0x09
378
+ T_FIXNUM 0x0a
379
+ T_HASH 0x0b
380
+ T_STRUCT 0x0c
381
+ T_BIGNUM 0x0d
382
+ T_FILE 0x0e
383
+
384
+ T_TRUE 0x20
385
+ T_FALSE 0x21
386
+ T_DATA 0x22
387
+ T_MATCH 0x23
388
+ T_SYMBOL 0x24
389
+
390
+ T_BLKTAG 0x3b
391
+ T_UNDEF 0x3c
392
+ T_VARMAP 0x3d
393
+ T_SCOPE 0x3e
394
+ T_NODE 0x3f
395
+ """.split("\n")
396
+
397
+ RubyObjects.TYPES = {}
398
+
399
+ for t in types:
400
+ if len(t.strip()) > 0:
401
+ name, val = t.split()
402
+ gdb.execute("macro define %s %s" % (name, val))
403
+ RubyObjects.TYPES[int(val,16)] = name[2:].lower()
404
+