gdb.rb 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|