gdb.rb 0.1.5 → 0.1.6
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.
- data/ext/extconf.rb +7 -7
- data/gdb.rb.gemspec +4 -4
- data/scripts/ruby-gdb.py +178 -86
- metadata +6 -11
data/ext/extconf.rb
CHANGED
@@ -11,27 +11,27 @@ end
|
|
11
11
|
require 'mkmf'
|
12
12
|
require 'fileutils'
|
13
13
|
|
14
|
-
if
|
14
|
+
if RUBY_PLATFORM !~ /(i686|x86_64)-linux/
|
15
15
|
STDERR.puts "\n\n"
|
16
16
|
STDERR.puts "***************************************************************************************"
|
17
|
-
STDERR.puts "
|
17
|
+
STDERR.puts "*********************** Only x86 linux is supported (for now) =( **********************"
|
18
18
|
STDERR.puts "***************************************************************************************"
|
19
19
|
exit(1)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
dir_config('python')
|
23
|
+
unless have_header('python2.5/Python.h') or have_header('python2.6/Python.h') or have_header('python2.4/Python.h')
|
23
24
|
STDERR.puts "\n\n"
|
24
25
|
STDERR.puts "***************************************************************************************"
|
25
|
-
STDERR.puts "
|
26
|
+
STDERR.puts "***************** Python required (apt-get install python2.5-dev) =( ******************"
|
26
27
|
STDERR.puts "***************************************************************************************"
|
27
28
|
exit(1)
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
unless have_header('python2.5/Python.h') or have_header('python2.6/Python.h') or have_header('python2.4/Python.h')
|
31
|
+
unless have_header('ncurses.h') or have_header('ncurses/ncurses.h')
|
32
32
|
STDERR.puts "\n\n"
|
33
33
|
STDERR.puts "***************************************************************************************"
|
34
|
-
STDERR.puts "
|
34
|
+
STDERR.puts "**************** ncurses required (apt-get install libncurses5-dev) =( ****************"
|
35
35
|
STDERR.puts "***************************************************************************************"
|
36
36
|
exit(1)
|
37
37
|
end
|
data/gdb.rb.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'gdb.rb'
|
3
|
-
s.version = '0.1.
|
4
|
-
s.date = '2010-11-
|
3
|
+
s.version = '0.1.6'
|
4
|
+
s.date = '2010-11-16'
|
5
5
|
s.rubyforge_project = 'gdb-rb'
|
6
|
-
s.summary = 'gdb hooks for MRI and
|
7
|
-
s.description = 'A set of gdb7 extensions for the MRI/REE 1.8.x interpreter'
|
6
|
+
s.summary = 'gdb hooks for MRI/REE and YARV'
|
7
|
+
s.description = 'A set of gdb7 extensions for the MRI/REE 1.8.x interpreter (and basic support for YARV 1.9.2)'
|
8
8
|
|
9
9
|
s.homepage = "http://github.com/tmm1/gdb.rb"
|
10
10
|
|
data/scripts/ruby-gdb.py
CHANGED
@@ -234,9 +234,9 @@ class RubyObjects (gdb.Command):
|
|
234
234
|
self.print_nodes()
|
235
235
|
elif arg == 'strings':
|
236
236
|
self.print_strings()
|
237
|
-
elif arg == 'hashes':
|
237
|
+
elif Ruby.is_18 and arg == 'hashes':
|
238
238
|
self.print_hashes()
|
239
|
-
elif arg == 'arrays':
|
239
|
+
elif Ruby.is_18 and arg == 'arrays':
|
240
240
|
self.print_arrays()
|
241
241
|
else:
|
242
242
|
self.print_stats()
|
@@ -244,24 +244,33 @@ class RubyObjects (gdb.Command):
|
|
244
244
|
def complete (self, text, word):
|
245
245
|
if text == word:
|
246
246
|
if word == '':
|
247
|
-
|
247
|
+
if Ruby.is_18:
|
248
|
+
return ['classes', 'nodes', 'strings', 'hashes', 'arrays']
|
249
|
+
else:
|
250
|
+
return ['classes', 'nodes', 'strings']
|
248
251
|
elif word[0] == 'c':
|
249
252
|
return ['classes']
|
250
253
|
elif word[0] == 'n':
|
251
254
|
return ['nodes']
|
252
255
|
elif word[0] == 's':
|
253
256
|
return ['strings']
|
254
|
-
elif word[0] == 'h':
|
257
|
+
elif Ruby.is_18 and word[0] == 'h':
|
255
258
|
return ['hashes']
|
256
|
-
elif word[0] == 'a':
|
259
|
+
elif Ruby.is_18 and word[0] == 'a':
|
257
260
|
return ['arrays']
|
258
261
|
|
259
262
|
def print_nodes (self):
|
260
263
|
nodes = ZeroDict()
|
261
264
|
|
262
265
|
for (obj, type) in self.live_objects():
|
263
|
-
if type ==
|
264
|
-
|
266
|
+
if type == RubyObjects.ITYPES['node']:
|
267
|
+
if Ruby.is_18:
|
268
|
+
# for performance only, the 1.9 path below will work as well
|
269
|
+
# but requires a call to gdb.parse_and_eval
|
270
|
+
type = (int(obj['as']['node']['flags']) >> 12) & 0xff
|
271
|
+
else:
|
272
|
+
type = int(gdb.parse_and_eval('nd_type(%s)' % obj))
|
273
|
+
nodes[ type ] += 1
|
265
274
|
|
266
275
|
for (node, num) in sorted(nodes.items(), key=lambda(k,v):(v,k)):
|
267
276
|
print "% 8d %s" % (num, gdb.parse_and_eval('(enum node_type) (%d)' % node))
|
@@ -295,11 +304,11 @@ class RubyObjects (gdb.Command):
|
|
295
304
|
bytes = 0
|
296
305
|
|
297
306
|
for (obj, type) in self.live_objects():
|
298
|
-
if type ==
|
307
|
+
if type == RubyObjects.ITYPES['string']:
|
299
308
|
s = obj['as']['string']
|
300
|
-
ptr = s['ptr']
|
301
|
-
if ptr:
|
302
|
-
bytes += s['len']
|
309
|
+
ptr = Ruby.is_18 and s['ptr'] or gdb.parse_and_eval('RSTRING_PTR(%s)' % obj)
|
310
|
+
if ptr != None:
|
311
|
+
bytes += (Ruby.is_18 and s['len'] or int(gdb.parse_and_eval('RSTRING_LEN(%s)' % obj)))
|
303
312
|
try:
|
304
313
|
strings[ ptr.string() ] += 1
|
305
314
|
except:
|
@@ -310,7 +319,7 @@ class RubyObjects (gdb.Command):
|
|
310
319
|
|
311
320
|
print
|
312
321
|
print "% 9d" % len(strings), "unique strings"
|
313
|
-
print "% 9d" % bytes, "bytes"
|
322
|
+
print "% 9d" % bytes, "bytes (this double counts shared strings)"
|
314
323
|
print
|
315
324
|
|
316
325
|
def print_hashes (self):
|
@@ -367,7 +376,7 @@ class RubyObjects (gdb.Command):
|
|
367
376
|
for (obj, flags) in self.all_objects():
|
368
377
|
if flags:
|
369
378
|
live += 1
|
370
|
-
types[ int(flags &
|
379
|
+
types[ int(flags & RubyObjects.T_MASK) ] += 1
|
371
380
|
else:
|
372
381
|
free += 1
|
373
382
|
|
@@ -399,7 +408,7 @@ class RubyObjects (gdb.Command):
|
|
399
408
|
def live_objects (self):
|
400
409
|
for (obj, flags) in self.all_objects():
|
401
410
|
if flags:
|
402
|
-
yield obj, int(flags &
|
411
|
+
yield obj, int(flags & RubyObjects.T_MASK)
|
403
412
|
|
404
413
|
def obj_type (self, type):
|
405
414
|
return RubyObjects.TYPES.get(type, 'unknown')
|
@@ -450,104 +459,187 @@ class RubyEval (gdb.Command):
|
|
450
459
|
|
451
460
|
def invoke (self, arg, from_tty):
|
452
461
|
self.dont_repeat()
|
462
|
+
# check if rb_during_gc
|
453
463
|
arg = arg.replace('\\', '\\\\').replace('"', '\\\"')
|
454
|
-
print gdb.parse_and_eval("(
|
464
|
+
print gdb.parse_and_eval("RSTRING_PTR(rb_eval_string_protect(\"begin; (%s).inspect; rescue Exception => e; e.inspect; end\", 0))" % arg).string()
|
455
465
|
|
456
466
|
|
457
467
|
##
|
458
|
-
# Create GDB commands
|
468
|
+
# Create common GDB commands
|
459
469
|
|
460
470
|
Ruby()
|
461
|
-
RubyThreads()
|
462
|
-
RubyTrace()
|
463
|
-
RubyObjects()
|
464
|
-
RubyMethodCache()
|
465
|
-
RubyPrint()
|
466
471
|
RubyEval()
|
472
|
+
RubyObjects()
|
467
473
|
|
468
474
|
##
|
469
|
-
# Detect
|
475
|
+
# Detect ruby version
|
470
476
|
|
471
477
|
ruby = gdb.execute("info files", to_string=True).split("\n")[0]
|
472
478
|
ruby = re.search('"(.+)"\.?$', ruby)
|
473
479
|
ruby = ruby.group(1)
|
474
480
|
ruby = os.popen("%s -v" % ruby).read()
|
475
481
|
|
476
|
-
if re.search('Enterprise', ruby):
|
477
|
-
gdb.execute("macro define FL_USHIFT 12")
|
478
|
-
else:
|
479
|
-
gdb.execute("macro define FL_USHIFT 11")
|
480
|
-
|
481
482
|
##
|
482
|
-
#
|
483
|
+
# Common macros for 1.8 and 1.9
|
483
484
|
|
484
485
|
macros = """
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
486
|
+
#define R_CAST(st) (struct st*)
|
487
|
+
#define RBASIC(obj) (R_CAST(RBasic)(obj))
|
488
|
+
#define RSTRING(obj) (R_CAST(RString)(obj))
|
489
|
+
#define RNODE(obj) (R_CAST(RNode)(obj))
|
490
|
+
|
491
|
+
#define FL_USER0 (((VALUE)1)<<(FL_USHIFT+0))
|
492
|
+
#define FL_USER1 (((VALUE)1)<<(FL_USHIFT+1))
|
493
|
+
#define FL_USER2 (((VALUE)1)<<(FL_USHIFT+2))
|
494
|
+
#define FL_USER3 (((VALUE)1)<<(FL_USHIFT+3))
|
495
|
+
#define FL_USER4 (((VALUE)1)<<(FL_USHIFT+4))
|
496
|
+
#define FL_USER5 (((VALUE)1)<<(FL_USHIFT+5))
|
497
|
+
#define FL_USER6 (((VALUE)1)<<(FL_USHIFT+6))
|
498
|
+
#define FL_USER7 (((VALUE)1)<<(FL_USHIFT+7))
|
499
|
+
#define FL_USER8 (((VALUE)1)<<(FL_USHIFT+8))
|
500
|
+
"""
|
501
|
+
|
502
|
+
##
|
503
|
+
# Constants
|
504
|
+
|
505
|
+
Ruby.is_18 = False
|
506
|
+
Ruby.is_19 = False
|
507
|
+
Ruby.is_ree = False
|
508
|
+
|
509
|
+
##
|
510
|
+
# Version specific macros and commands
|
511
|
+
|
512
|
+
if re.search('1\.9\.\d', ruby):
|
513
|
+
Ruby.is_19 = True
|
514
|
+
RubyObjects.T_MASK = 0x1f
|
515
|
+
|
516
|
+
##
|
517
|
+
# Common 1.9 macros
|
518
|
+
macros += """
|
519
|
+
#define NODE_TYPESHIFT 8
|
520
|
+
#define NODE_TYPEMASK (((VALUE)0x7f)<<NODE_TYPESHIFT)
|
521
|
+
#define nd_type(n) ((int) (((RNODE(n))->flags & NODE_TYPEMASK)>>NODE_TYPESHIFT))
|
505
522
|
|
506
|
-
|
523
|
+
#define RSTRING_NOEMBED FL_USER1
|
524
|
+
#define RSTRING_PTR(str) (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? RSTRING(str)->as.ary : RSTRING(str)->as.heap.ptr)
|
525
|
+
#define RSTRING_EMBED_LEN_MASK (FL_USER2|FL_USER3|FL_USER4|FL_USER5|FL_USER6)
|
526
|
+
#define RSTRING_EMBED_LEN_SHIFT (FL_USHIFT+2)
|
527
|
+
#define RSTRING_LEN(str) (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? (long)((RBASIC(str)->flags >> RSTRING_EMBED_LEN_SHIFT) & (RSTRING_EMBED_LEN_MASK >> RSTRING_EMBED_LEN_SHIFT)) : RSTRING(str)->as.heap.len)
|
528
|
+
|
529
|
+
#define FL_USHIFT 12
|
530
|
+
|
531
|
+
#define GET_VM() ruby_current_vm
|
532
|
+
#define rb_objspace (*GET_VM()->objspace)
|
533
|
+
#define objspace rb_objspace
|
534
|
+
|
535
|
+
#define heaps objspace->heap.ptr
|
536
|
+
#define heaps_length objspace->heap.length
|
537
|
+
#define heaps_used objspace->heap.used
|
538
|
+
"""
|
539
|
+
|
540
|
+
else:
|
541
|
+
Ruby.is_18 = True
|
542
|
+
RubyObjects.T_MASK = 0x3f
|
543
|
+
|
544
|
+
##
|
545
|
+
# 1.8 specific ruby commands
|
546
|
+
RubyThreads()
|
547
|
+
RubyTrace()
|
548
|
+
RubyMethodCache()
|
549
|
+
RubyPrint()
|
550
|
+
|
551
|
+
##
|
552
|
+
# Detect REE vs MRI
|
553
|
+
if re.search('Enterprise', ruby):
|
554
|
+
Ruby.is_ree = True
|
555
|
+
macros += """
|
556
|
+
#define FL_USHIFT 12
|
557
|
+
"""
|
558
|
+
else:
|
559
|
+
macros += """
|
560
|
+
#define FL_USHIFT 11
|
561
|
+
"""
|
562
|
+
|
563
|
+
##
|
564
|
+
# Common 1.8 macros
|
565
|
+
macros += """
|
566
|
+
#define RSTRING_PTR(obj) (RSTRING(obj)->ptr)
|
567
|
+
#define CHAR_BIT 8
|
568
|
+
#define NODE_LSHIFT (FL_USHIFT+8)
|
569
|
+
#define NODE_LMASK (((long)1<<(sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT))-1)
|
570
|
+
#define nd_line(n) ((unsigned int)(((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK))
|
571
|
+
#define nd_type(n) ((int)(((RNODE(n))->flags>>FL_USHIFT)&0xff))
|
572
|
+
|
573
|
+
#define T_MASK 0x3f
|
574
|
+
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
|
575
|
+
|
576
|
+
#define WAIT_FD (1<<0)
|
577
|
+
#define WAIT_SELECT (1<<1)
|
578
|
+
#define WAIT_TIME (1<<2)
|
579
|
+
#define WAIT_JOIN (1<<3)
|
580
|
+
#define WAIT_PID (1<<4)
|
581
|
+
|
582
|
+
#define RUBY_EVENT_CALL 0x08
|
583
|
+
#define RUBY_EVENT_C_CALL 0x20
|
584
|
+
"""
|
585
|
+
|
586
|
+
##
|
587
|
+
# Execute macro definitions
|
588
|
+
|
589
|
+
for m in macros.split("\n"):
|
507
590
|
if len(m.strip()) > 0:
|
508
|
-
gdb.execute(m)
|
591
|
+
gdb.execute(m.replace('#', 'macro ', 1))
|
509
592
|
|
510
593
|
##
|
511
594
|
# Define types
|
512
595
|
|
513
|
-
types = """
|
514
|
-
T_NONE 0x00
|
515
|
-
|
516
|
-
T_NIL 0x01
|
517
|
-
T_OBJECT 0x02
|
518
|
-
T_CLASS 0x03
|
519
|
-
T_ICLASS 0x04
|
520
|
-
T_MODULE 0x05
|
521
|
-
T_FLOAT 0x06
|
522
|
-
T_STRING 0x07
|
523
|
-
T_REGEXP 0x08
|
524
|
-
T_ARRAY 0x09
|
525
|
-
T_FIXNUM 0x0a
|
526
|
-
T_HASH 0x0b
|
527
|
-
T_STRUCT 0x0c
|
528
|
-
T_BIGNUM 0x0d
|
529
|
-
T_FILE 0x0e
|
530
|
-
|
531
|
-
T_TRUE 0x20
|
532
|
-
T_FALSE 0x21
|
533
|
-
T_DATA 0x22
|
534
|
-
T_MATCH 0x23
|
535
|
-
T_SYMBOL 0x24
|
536
|
-
|
537
|
-
T_BLKTAG 0x3b
|
538
|
-
T_UNDEF 0x3c
|
539
|
-
T_VARMAP 0x3d
|
540
|
-
T_SCOPE 0x3e
|
541
|
-
T_NODE 0x3f
|
542
|
-
""".split("\n")
|
543
|
-
|
544
596
|
RubyObjects.TYPES = {}
|
545
597
|
|
546
|
-
|
547
|
-
|
548
|
-
name
|
549
|
-
gdb.
|
550
|
-
|
598
|
+
if Ruby.is_19:
|
599
|
+
for t in gdb.lookup_type('enum ruby_value_type').fields():
|
600
|
+
name = t.name
|
601
|
+
val = int(gdb.parse_and_eval(name))
|
602
|
+
gdb.execute("macro define %s %s" % (name[5:], val))
|
603
|
+
RubyObjects.TYPES[val] = name[7:].lower()
|
604
|
+
else:
|
605
|
+
types = """
|
606
|
+
T_NONE 0x00
|
607
|
+
|
608
|
+
T_NIL 0x01
|
609
|
+
T_OBJECT 0x02
|
610
|
+
T_CLASS 0x03
|
611
|
+
T_ICLASS 0x04
|
612
|
+
T_MODULE 0x05
|
613
|
+
T_FLOAT 0x06
|
614
|
+
T_STRING 0x07
|
615
|
+
T_REGEXP 0x08
|
616
|
+
T_ARRAY 0x09
|
617
|
+
T_FIXNUM 0x0a
|
618
|
+
T_HASH 0x0b
|
619
|
+
T_STRUCT 0x0c
|
620
|
+
T_BIGNUM 0x0d
|
621
|
+
T_FILE 0x0e
|
622
|
+
|
623
|
+
T_TRUE 0x20
|
624
|
+
T_FALSE 0x21
|
625
|
+
T_DATA 0x22
|
626
|
+
T_MATCH 0x23
|
627
|
+
T_SYMBOL 0x24
|
628
|
+
|
629
|
+
T_BLKTAG 0x3b
|
630
|
+
T_UNDEF 0x3c
|
631
|
+
T_VARMAP 0x3d
|
632
|
+
T_SCOPE 0x3e
|
633
|
+
T_NODE 0x3f
|
634
|
+
""".split("\n")
|
635
|
+
|
636
|
+
for t in types:
|
637
|
+
if len(t.strip()) > 0:
|
638
|
+
name, val = t.split()
|
639
|
+
gdb.execute("macro define %s %s" % (name, val))
|
640
|
+
RubyObjects.TYPES[int(val,16)] = name[2:].lower()
|
641
|
+
|
642
|
+
RubyObjects.ITYPES = dict([[v,k] for k,v in RubyObjects.TYPES.items()])
|
551
643
|
|
552
644
|
##
|
553
645
|
# Set GDB options
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gdb.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 17
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
8
|
+
- 6
|
9
|
+
version: 0.1.6
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Aman Gupta
|
@@ -15,11 +14,11 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-11-
|
17
|
+
date: 2010-11-16 00:00:00 -05:00
|
19
18
|
default_executable:
|
20
19
|
dependencies: []
|
21
20
|
|
22
|
-
description: A set of gdb7 extensions for the MRI/REE 1.8.x interpreter
|
21
|
+
description: A set of gdb7 extensions for the MRI/REE 1.8.x interpreter (and basic support for YARV 1.9.2)
|
23
22
|
email: gdb@tmm1.net
|
24
23
|
executables:
|
25
24
|
- gdb.rb
|
@@ -47,29 +46,25 @@ rdoc_options: []
|
|
47
46
|
require_paths:
|
48
47
|
- lib
|
49
48
|
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
49
|
requirements:
|
52
50
|
- - ">="
|
53
51
|
- !ruby/object:Gem::Version
|
54
|
-
hash: 3
|
55
52
|
segments:
|
56
53
|
- 0
|
57
54
|
version: "0"
|
58
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
-
none: false
|
60
56
|
requirements:
|
61
57
|
- - ">="
|
62
58
|
- !ruby/object:Gem::Version
|
63
|
-
hash: 3
|
64
59
|
segments:
|
65
60
|
- 0
|
66
61
|
version: "0"
|
67
62
|
requirements: []
|
68
63
|
|
69
64
|
rubyforge_project: gdb-rb
|
70
|
-
rubygems_version: 1.3.
|
65
|
+
rubygems_version: 1.3.6
|
71
66
|
signing_key:
|
72
67
|
specification_version: 3
|
73
|
-
summary: gdb hooks for MRI and
|
68
|
+
summary: gdb hooks for MRI/REE and YARV
|
74
69
|
test_files: []
|
75
70
|
|