ruby-debug 0.4.2-mswin32 → 0.4.3-mswin32

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/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ 0.4.3
2
+ - Added Debugger.skip method which allows escaping a block from the debugger reach.
3
+ - Bugfixes.
4
+
1
5
  0.4.2
2
6
  - Module#deubg_method added.
3
7
  - Added rdoc.
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rake/rdoctask'
5
5
  SO_NAME = "ruby_debug.so"
6
6
 
7
7
  # ------- Default Package ----------
8
- RUBY_DEBUG_VERSION = "0.4.2"
8
+ RUBY_DEBUG_VERSION = "0.4.3"
9
9
 
10
10
  FILES = FileList[
11
11
  'Rakefile',
data/bin/rdebug CHANGED
@@ -70,14 +70,16 @@ else
70
70
  trap('INT') { Debugger.interrupt_last }
71
71
  Debugger.stop_on_connect = !options.nostop
72
72
  Debugger.wait_connection = options.wait
73
+ load "#{ENV["HOME"]}/.rdebugrc" if File.exists?("#{ENV["HOME"]}/.rdebugrc")
73
74
  if options.server
74
75
  Debugger.start_remote(options.host, [options.port, options.cport])
76
+ Debugger.debug_load ARGV.shift
75
77
  else
76
78
  Debugger.start
77
79
  if options.script
78
80
  Debugger.run_script(options.script)
79
81
  end
80
82
  debugger 2
83
+ Debugger.debug_load ARGV.shift
81
84
  end
82
- load ARGV.shift
83
85
  end
data/ext/ruby_debug.c CHANGED
@@ -4,7 +4,7 @@
4
4
  #include <rubysig.h>
5
5
  #include <st.h>
6
6
 
7
- #define DEBUG_VERSION "0.4.2"
7
+ #define DEBUG_VERSION "0.4.3"
8
8
 
9
9
  typedef struct {
10
10
  int thnum;
@@ -39,6 +39,7 @@ static VALUE breakpoints = Qnil;
39
39
  static VALUE catchpoint = Qnil;
40
40
  static VALUE waiting = Qnil;
41
41
  static VALUE tracing = Qfalse;
42
+ static VALUE locker = Qnil;
42
43
 
43
44
  static VALUE mDebugger;
44
45
  static VALUE cContext;
@@ -67,6 +68,64 @@ static VALUE debug_suspend(VALUE);
67
68
  static VALUE create_binding(VALUE);
68
69
  static VALUE debug_stop(VALUE);
69
70
 
71
+ typedef struct locked_thread_t {
72
+ VALUE thread;
73
+ struct locked_thread_t *next;
74
+ } locked_thread_t;
75
+
76
+ static locked_thread_t *locked_head = NULL;
77
+ static locked_thread_t *locked_tail = NULL;
78
+
79
+ static int
80
+ is_in_locked(VALUE thread)
81
+ {
82
+ locked_thread_t *node;
83
+
84
+ if(!locked_head)
85
+ return 0;
86
+
87
+ for(node = locked_head; node != locked_tail; node = node->next)
88
+ {
89
+ if(node->thread == thread) return 1;
90
+ }
91
+ return 0;
92
+ }
93
+
94
+ static void
95
+ add_to_locked(VALUE thread)
96
+ {
97
+ locked_thread_t *node;
98
+
99
+ if(is_in_locked(thread))
100
+ return;
101
+
102
+ node = ALLOC(locked_thread_t);
103
+ node->thread = thread;
104
+ node->next = NULL;
105
+ if(locked_tail)
106
+ locked_tail->next = node;
107
+ locked_tail = node;
108
+ if(!locked_head)
109
+ locked_head = node;
110
+ }
111
+
112
+ static VALUE
113
+ remove_from_locked()
114
+ {
115
+ VALUE thread;
116
+ locked_thread_t *node;
117
+
118
+ if(locked_head == NULL)
119
+ return Qnil;
120
+ node = locked_head;
121
+ locked_head = locked_head->next;
122
+ if(locked_tail == node)
123
+ locked_tail = NULL;
124
+ thread = node->thread;
125
+ xfree(node);
126
+ return thread;
127
+ }
128
+
70
129
  #define IS_STARTED (threads_tbl != Qnil)
71
130
 
72
131
  /*
@@ -359,15 +418,20 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
359
418
  VALUE file = Qnil, line = Qnil;
360
419
  int breakpoint_index = -1;
361
420
 
362
- static int debugging = 0;
363
-
364
421
  if (mid == ID_ALLOCATOR) return;
365
- if(debugging) return;
366
422
  if(!node) return;
423
+
424
+ thread = rb_thread_current();
425
+ while(locker != Qnil && locker != thread)
426
+ {
427
+ add_to_locked(thread);
428
+ rb_thread_stop();
429
+ }
430
+
431
+ if(locker != Qnil) return;
367
432
 
368
- debugging++;
433
+ locker = rb_thread_current();
369
434
 
370
- thread = rb_thread_current();
371
435
  context = thread_context_lookup(thread);
372
436
  Data_Get_Struct(context, debug_context_t, debug_context);
373
437
  check_suspend(debug_context);
@@ -420,7 +484,9 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
420
484
  {
421
485
  breakpoint = get_breakpoint_at(breakpoint_index);
422
486
  if(check_breakpoint_expression(breakpoint, binding))
487
+ {
423
488
  rb_funcall(context, idAtBreakpoint, 1, breakpoint);
489
+ }
424
490
  else
425
491
  break;
426
492
  }
@@ -508,7 +574,10 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
508
574
  }
509
575
  }
510
576
 
511
- debugging--;
577
+ locker = Qnil;
578
+ thread = remove_from_locked();
579
+ if(thread != Qnil)
580
+ rb_thread_run(thread);
512
581
  }
513
582
 
514
583
  static VALUE
@@ -543,15 +612,12 @@ debug_start(VALUE self)
543
612
  threads_tbl = rb_hash_new();
544
613
  breakpoints = rb_ary_new();
545
614
  waiting = rb_ary_new();
615
+ locker = Qnil;
546
616
 
547
- rb_add_event_hook(debug_event_hook,
548
- RUBY_EVENT_LINE | RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN |
549
- RUBY_EVENT_CALL | RUBY_EVENT_RETURN | RUBY_EVENT_CLASS |
550
- RUBY_EVENT_END | RUBY_EVENT_RAISE
551
- );
617
+ rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL);
552
618
 
553
619
  if(rb_block_given_p())
554
- return rb_ensure(rb_yield, Qnil, debug_stop_i, Qnil);
620
+ return rb_ensure(rb_yield, Qnil, debug_stop_i, self);
555
621
 
556
622
  return Qtrue;
557
623
  }
@@ -578,6 +644,7 @@ debug_stop(VALUE self)
578
644
  rb_remove_event_hook(debug_event_hook);
579
645
 
580
646
  waiting = Qnil;
647
+ locker = Qnil;
581
648
  breakpoints = Qnil;
582
649
  threads_tbl = Qnil;
583
650
 
@@ -799,7 +866,7 @@ debug_suspend(VALUE self)
799
866
  rb_thread_critical = saved_crit;
800
867
 
801
868
  if(rb_thread_critical == Qfalse)
802
- rb_thread_schedule();
869
+ rb_thread_schedule();
803
870
 
804
871
  return self;
805
872
  }
@@ -837,8 +904,8 @@ debug_resume(VALUE self)
837
904
  }
838
905
  for(i = 0; i < RARRAY(waiting)->len; i++)
839
906
  {
840
- thread = rb_ary_entry(waiting, i);
841
- rb_thread_run(thread);
907
+ thread = rb_ary_entry(waiting, i);
908
+ rb_thread_run(thread);
842
909
  }
843
910
  rb_ary_clear(waiting);
844
911
  rb_thread_critical = saved_crit;
@@ -873,6 +940,94 @@ debug_set_tracing(VALUE self, VALUE value)
873
940
  return value;
874
941
  }
875
942
 
943
+ /*
944
+ * call-seq:
945
+ * Debugger.debug_load(file) -> nil
946
+ *
947
+ * Same as Kernel#load but resets current context's frames.
948
+ * FOR INTERNAL USE ONLY.
949
+ */
950
+ static VALUE
951
+ debug_debug_load(VALUE self, VALUE file)
952
+ {
953
+ VALUE context;
954
+ debug_context_t *debug_context;
955
+
956
+ debug_start(self);
957
+
958
+ context = debug_current_context(self);
959
+ Data_Get_Struct(context, debug_context_t, debug_context);
960
+ rb_ary_clear(debug_context->frames);
961
+ rb_load(file, 0);
962
+
963
+ debug_stop(self);
964
+ return Qnil;
965
+ }
966
+
967
+ static VALUE
968
+ debug_skip_i(VALUE value)
969
+ {
970
+ rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL);
971
+ return Qnil;
972
+ }
973
+
974
+ /*
975
+ * call-seq:
976
+ * Debugger.skip { block } -> obj or nil
977
+ *
978
+ * The code inside of the block is escaped from the debugger.
979
+ */
980
+ static VALUE
981
+ debug_skip(VALUE self)
982
+ {
983
+ if (!rb_block_given_p()) {
984
+ rb_raise(rb_eArgError, "called without a block");
985
+ }
986
+ if(!IS_STARTED)
987
+ return rb_yield(Qnil);
988
+ rb_remove_event_hook(debug_event_hook);
989
+ return rb_ensure(rb_yield, Qnil, debug_skip_i, Qnil);
990
+ }
991
+
992
+ static VALUE
993
+ debug_at_exit_c(VALUE proc)
994
+ {
995
+ return rb_funcall(proc, rb_intern("call"), 0);
996
+ }
997
+
998
+ static void
999
+ debug_at_exit_i(VALUE proc)
1000
+ {
1001
+ if(!IS_STARTED)
1002
+ {
1003
+ debug_at_exit_c(proc);
1004
+ }
1005
+ else
1006
+ {
1007
+ rb_remove_event_hook(debug_event_hook);
1008
+ rb_ensure(debug_at_exit_c, proc, debug_skip_i, Qnil);
1009
+ }
1010
+ }
1011
+
1012
+ /*
1013
+ * call-seq:
1014
+ * Debugger.debug_at_exit { block } -> proc
1015
+ *
1016
+ * Register <tt>at_exit</tt> hook which is escaped from the debugger.
1017
+ * FOR INTERNAL USE ONLY.
1018
+ */
1019
+ static VALUE
1020
+ debug_at_exit(VALUE self)
1021
+ {
1022
+ VALUE proc;
1023
+ if (!rb_block_given_p()) {
1024
+ rb_raise(rb_eArgError, "called without a block");
1025
+ }
1026
+ proc = rb_block_proc();
1027
+ rb_set_end_proc(debug_at_exit_i, proc);
1028
+ return proc;
1029
+ }
1030
+
876
1031
  /*
877
1032
  * call-seq:
878
1033
  * context.stop_next = steps
@@ -1259,6 +1414,9 @@ Init_ruby_debug()
1259
1414
  rb_define_module_function(mDebugger, "resume", debug_resume, 0);
1260
1415
  rb_define_module_function(mDebugger, "tracing", debug_tracing, 0);
1261
1416
  rb_define_module_function(mDebugger, "tracing=", debug_set_tracing, 1);
1417
+ rb_define_module_function(mDebugger, "debug_load", debug_debug_load, 1);
1418
+ rb_define_module_function(mDebugger, "skip", debug_skip, 0);
1419
+ rb_define_module_function(mDebugger, "debug_at_exit", debug_at_exit, 0);
1262
1420
 
1263
1421
  Init_context();
1264
1422
  Init_frame();
@@ -1282,6 +1440,7 @@ Init_ruby_debug()
1282
1440
  rb_global_variable(&breakpoints);
1283
1441
  rb_global_variable(&catchpoint);
1284
1442
  rb_global_variable(&waiting);
1443
+ rb_global_variable(&locker);
1285
1444
  rb_global_variable(&file_separator);
1286
1445
  rb_global_variable(&alt_file_separator);
1287
1446
  }
data/lib/ruby-debug.rb CHANGED
@@ -156,7 +156,6 @@ module Debugger
156
156
  end
157
157
  end
158
158
  socket.close
159
- puts
160
159
  end
161
160
 
162
161
  def stop_main_thread # :nodoc:
@@ -19,25 +19,26 @@ module Debugger
19
19
 
20
20
  begin
21
21
  require 'readline'
22
- FILE_HISTORY = ".rdebug_hist"
23
-
24
- save_file = File.join(Dir.getwd, FILE_HISTORY)
25
- open(save_file, 'r') do |file|
26
- file.each do |line|
27
- line.chomp!
28
- Readline::HISTORY << line
29
- end
30
- end if File.exists?(save_file)
31
-
32
- class << Debugger; self end.send('define_method', 'save_history') do
33
- open(save_file, 'w') do |file|
34
- Readline::HISTORY.each do |line|
35
- file.puts line unless line.strip.empty?
22
+ class << Debugger
23
+ FILE_HISTORY = ".rdebug_hist"
24
+ save_file = File.join(ENV["HOME"]||ENV["HOMEPATH"], FILE_HISTORY)
25
+ open(save_file, 'r') do |file|
26
+ file.each do |line|
27
+ line.chomp!
28
+ Readline::HISTORY << line
29
+ end
30
+ end if File.exists?(save_file)
31
+
32
+ define_method(:save_history) do
33
+ open(save_file, 'w') do |file|
34
+ Readline::HISTORY.to_a.last(500).each do |line|
35
+ file.puts line unless line.strip.empty?
36
+ end
36
37
  end
37
38
  end
39
+ public :save_history
38
40
  end
39
- class << Debugger; public :save_history end
40
- at_exit { Debugger.save_history }
41
+ Debugger.debug_at_exit { Debugger.save_history }
41
42
 
42
43
  def readline(prompt, hist)
43
44
  Readline::readline(prompt, hist)
@@ -51,7 +52,6 @@ module Debugger
51
52
  line.chomp!
52
53
  line
53
54
  end
54
- USE_READLINE = false
55
55
  end
56
56
  end
57
57
 
data/lib/ruby_debug.so CHANGED
Binary file
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: ruby-debug
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.4.2
7
- date: 2006-09-15 10:57:34 -04:00
6
+ version: 0.4.3
7
+ date: 2006-10-09 18:04:00 -04:00
8
8
  summary: Fast Ruby debugger
9
9
  require_paths:
10
10
  - lib