gdb.rb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+