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.
Files changed (4) hide show
  1. data/ext/extconf.rb +7 -7
  2. data/gdb.rb.gemspec +4 -4
  3. data/scripts/ruby-gdb.py +178 -86
  4. metadata +6 -11
@@ -11,27 +11,27 @@ end
11
11
  require 'mkmf'
12
12
  require 'fileutils'
13
13
 
14
- if RUBY_VERSION >= "1.9"
14
+ if RUBY_PLATFORM !~ /(i686|x86_64)-linux/
15
15
  STDERR.puts "\n\n"
16
16
  STDERR.puts "***************************************************************************************"
17
- STDERR.puts "************************** ruby 1.9 is not supported (yet) =( *************************"
17
+ STDERR.puts "*********************** Only x86 linux is supported (for now) =( **********************"
18
18
  STDERR.puts "***************************************************************************************"
19
19
  exit(1)
20
20
  end
21
21
 
22
- if RUBY_PLATFORM !~ /(i686|x86_64)-linux/
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 "*********************** Only x86 linux is supported (for now) =( **********************"
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
- dir_config('python')
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 "***************** Python required (apt-get install python2.5-dev) =( ******************"
34
+ STDERR.puts "**************** ncurses required (apt-get install libncurses5-dev) =( ****************"
35
35
  STDERR.puts "***************************************************************************************"
36
36
  exit(1)
37
37
  end
@@ -1,10 +1,10 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'gdb.rb'
3
- s.version = '0.1.5'
4
- s.date = '2010-11-04'
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 REE'
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
 
@@ -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
- return ['classes', 'strings', 'nodes', 'hashes', 'arrays']
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 == 0x3f:
264
- nodes[ (int(obj['as']['node']['flags']) >> 12) & 0xff ] += 1
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 == 0x7:
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 & 0x3f) ] += 1
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 & 0x3f)
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("((struct RString*)rb_eval_string_protect(\"begin; (%s).inspect; rescue Exception => e; e.inspect; end\", 0))->ptr" % arg).string()
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 MRI vs REE
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
- # Define common macros
483
+ # Common macros for 1.8 and 1.9
483
484
 
484
485
  macros = """
485
- macro define R_CAST(st) (struct st*)
486
- macro define RNODE(obj) (R_CAST(RNode)(obj))
487
- macro define CHAR_BIT 8
488
- macro define NODE_LSHIFT (FL_USHIFT+8)
489
- macro define NODE_LMASK (((long)1<<(sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT))-1)
490
- macro define nd_line(n) ((unsigned int)(((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK))
491
- macro define nd_type(n) ((int)(((RNODE(n))->flags>>FL_USHIFT)&0xff))
492
-
493
- macro define T_MASK 0x3f
494
- macro define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
495
-
496
- macro define WAIT_FD (1<<0)
497
- macro define WAIT_SELECT (1<<1)
498
- macro define WAIT_TIME (1<<2)
499
- macro define WAIT_JOIN (1<<3)
500
- macro define WAIT_PID (1<<4)
501
-
502
- macro define RUBY_EVENT_CALL 0x08
503
- macro define RUBY_EVENT_C_CALL 0x20
504
- """.split("\n")
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
- for m in macros:
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
- for t in types:
547
- if len(t.strip()) > 0:
548
- name, val = t.split()
549
- gdb.execute("macro define %s %s" % (name, val))
550
- RubyObjects.TYPES[int(val,16)] = name[2:].lower()
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
- - 5
10
- version: 0.1.5
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-04 00:00:00 -07:00
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.7
65
+ rubygems_version: 1.3.6
71
66
  signing_key:
72
67
  specification_version: 3
73
- summary: gdb hooks for MRI and REE
68
+ summary: gdb hooks for MRI/REE and YARV
74
69
  test_files: []
75
70