ruby-debug 0.4.3-mswin32 → 0.4.4-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,8 @@
1
+ 0.4.4
2
+ - Renamed Context#set_suspend and Context#clear_suspend methods to Context#suspend and Context#resume respectively.
3
+ - Context#resume method not only clears suspend flag, but also resumes the thread execution.
4
+ - Bugfixes.
5
+
1
6
  0.4.3
2
7
  - Added Debugger.skip method which allows escaping a block from the debugger reach.
3
8
  - Bugfixes.
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.3"
8
+ RUBY_DEBUG_VERSION = open("ext/ruby_debug.c"){|f| f.grep(/^#define DEBUG_VERSION/).first[/"(.+)"/,1]}
9
9
 
10
10
  FILES = FileList[
11
11
  'Rakefile',
data/bin/rdebug CHANGED
@@ -29,6 +29,9 @@ EOB
29
29
  opts.on("-c", "--client", "Connect to remote debugger") {options.client = true}
30
30
  opts.on("-h", "--host HOST", "Host name used for remote debugging") {|options.host|}
31
31
  opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") {|options.port|}
32
+ opts.on("-I", "--include PATH", String, "Add PATH to $LOAD_PATH") do |path|
33
+ $LOAD_PATH.unshift(path)
34
+ end
32
35
  opts.on("--script FILE", String, "Name of the script file to run") do |options.script|
33
36
  unless File.exists?(options.script)
34
37
  puts "Script file '#{options.script}' is not found"
data/ext/ruby_debug.c CHANGED
@@ -4,21 +4,35 @@
4
4
  #include <rubysig.h>
5
5
  #include <st.h>
6
6
 
7
- #define DEBUG_VERSION "0.4.3"
7
+ #define DEBUG_VERSION "0.4.4"
8
+
9
+ #define CTX_FL_MOVED (1<<1)
10
+ #define CTX_FL_SUSPEND (1<<2)
11
+ #define CTX_FL_TRACING (1<<3)
12
+ #define CTX_FL_SKIPPED (1<<4)
13
+ #define CTX_FL_IGNORE (1<<5)
14
+
15
+ #define CTX_FL_TEST(c,f) ((c)->flags & (f))
16
+ #define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0)
17
+ #define CTX_FL_UNSET(c,f) do { (c)->flags &= ~(f); } while (0)
18
+
19
+ #define DID_MOVED (debug_context->last_line != line || \
20
+ debug_context->last_file == Qnil || \
21
+ rb_str_cmp(debug_context->last_file, file) != 0)
22
+
23
+ #define IS_STARTED (threads_tbl != Qnil)
8
24
 
9
25
  typedef struct {
10
26
  int thnum;
11
- VALUE last_file;
12
- VALUE last_line;
13
- int moved;
27
+ int flags;
14
28
  int stop_next;
15
29
  int dest_frame;
16
30
  int stop_line;
17
31
  int stop_frame;
18
- int suspend;
19
- int tracing;
20
32
  VALUE frames;
21
33
  VALUE thread;
34
+ VALUE last_file;
35
+ VALUE last_line;
22
36
  } debug_context_t;
23
37
 
24
38
  typedef struct {
@@ -34,14 +48,18 @@ typedef struct {
34
48
  VALUE expr;
35
49
  } debug_breakpoint_t;
36
50
 
51
+ typedef struct {
52
+ st_table *tbl;
53
+ } threads_table_t;
54
+
37
55
  static VALUE threads_tbl = Qnil;
38
56
  static VALUE breakpoints = Qnil;
39
57
  static VALUE catchpoint = Qnil;
40
- static VALUE waiting = Qnil;
41
58
  static VALUE tracing = Qfalse;
42
59
  static VALUE locker = Qnil;
43
60
 
44
61
  static VALUE mDebugger;
62
+ static VALUE cThreadsTable;
45
63
  static VALUE cContext;
46
64
  static VALUE cFrame;
47
65
  static VALUE cBreakpoint;
@@ -64,7 +82,6 @@ static int start_count = 0;
64
82
  static int thnum_max = 0;
65
83
  static int last_debugged_thnum = -1;
66
84
 
67
- static VALUE debug_suspend(VALUE);
68
85
  static VALUE create_binding(VALUE);
69
86
  static VALUE debug_stop(VALUE);
70
87
 
@@ -126,7 +143,72 @@ remove_from_locked()
126
143
  return thread;
127
144
  }
128
145
 
129
- #define IS_STARTED (threads_tbl != Qnil)
146
+ static int
147
+ thread_hash(VALUE thread)
148
+ {
149
+ return (int)FIX2LONG(rb_obj_id(thread));
150
+ }
151
+
152
+ static int
153
+ thread_cmp(VALUE a, VALUE b)
154
+ {
155
+ if(a == b) return 0;
156
+ if(a < b) return -1;
157
+ return 1;
158
+ }
159
+
160
+ static struct st_hash_type st_thread_hash = {
161
+ thread_cmp,
162
+ thread_hash
163
+ };
164
+
165
+ static int
166
+ threads_table_mark_keyvalue(VALUE key, VALUE value, int dummy)
167
+ {
168
+ rb_gc_mark(key);
169
+ rb_gc_mark(value);
170
+ return ST_CONTINUE;
171
+ }
172
+
173
+ static void
174
+ threads_table_mark(void* data)
175
+ {
176
+ threads_table_t *threads_table = (threads_table_t*)data;
177
+ st_foreach(threads_table->tbl, threads_table_mark_keyvalue, 0);
178
+ }
179
+
180
+ static void
181
+ threads_table_free(void* data)
182
+ {
183
+ threads_table_t *threads_table = (threads_table_t*)data;
184
+ st_free_table(threads_table->tbl);
185
+ xfree(threads_table);
186
+ }
187
+
188
+ static VALUE
189
+ threads_table_create()
190
+ {
191
+ threads_table_t *threads_table;
192
+
193
+ threads_table = ALLOC(threads_table_t);
194
+ threads_table->tbl = st_init_table(&st_thread_hash);
195
+ return Data_Wrap_Struct(cThreadsTable, threads_table_mark, threads_table_free, threads_table);
196
+ }
197
+
198
+ static int
199
+ threads_table_clear_i(VALUE key, VALUE value, VALUE dummy)
200
+ {
201
+ return ST_DELETE;
202
+ }
203
+
204
+ static void
205
+ threads_table_clear(VALUE table)
206
+ {
207
+ threads_table_t *threads_table;
208
+
209
+ Data_Get_Struct(table, threads_table_t, threads_table);
210
+ st_foreach(threads_table->tbl, threads_table_clear_i, 0);
211
+ }
130
212
 
131
213
  /*
132
214
  * call-seq:
@@ -170,14 +252,12 @@ debug_context_create(VALUE thread)
170
252
 
171
253
  debug_context->last_file = Qnil;
172
254
  debug_context->last_line = Qnil;
173
- debug_context->moved = 0;
255
+ debug_context->flags = 0;
174
256
 
175
257
  debug_context->stop_next = -1;
176
258
  debug_context->dest_frame = -1;
177
259
  debug_context->stop_line = -1;
178
260
  debug_context->stop_frame = -1;
179
- debug_context->suspend = 0;
180
- debug_context->tracing = 0;
181
261
  debug_context->frames = rb_ary_new();
182
262
  debug_context->thread = thread;
183
263
  result = Data_Wrap_Struct(cContext, debug_context_mark, xfree, debug_context);
@@ -188,14 +268,15 @@ static VALUE
188
268
  thread_context_lookup(VALUE thread)
189
269
  {
190
270
  VALUE context;
271
+ threads_table_t *threads_table;
191
272
 
192
273
  debug_check_started();
193
274
 
194
- context = rb_hash_aref(threads_tbl, thread);
195
- if(context == Qnil)
275
+ Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
276
+ if(!st_lookup(threads_table->tbl, thread, &context))
196
277
  {
197
- context = debug_context_create(thread);
198
- rb_hash_aset(threads_tbl, thread, context);
278
+ context = debug_context_create(thread);
279
+ st_insert(threads_table->tbl, thread, context);
199
280
  }
200
281
  return context;
201
282
  }
@@ -241,13 +322,9 @@ save_current_position(VALUE context)
241
322
 
242
323
  debug_context->last_file = debug_frame->file;
243
324
  debug_context->last_line = debug_frame->line;
244
- debug_context->moved = 0;
325
+ CTX_FL_UNSET(debug_context, CTX_FL_MOVED);
245
326
  }
246
327
 
247
- #define did_moved() (debug_context->last_line != line || \
248
- debug_context->last_file == Qnil || \
249
- rb_str_cmp(debug_context->last_file, file) != 0)
250
-
251
328
  static VALUE
252
329
  call_at_line_unprotected(VALUE args)
253
330
  {
@@ -263,7 +340,6 @@ call_at_line(VALUE context, int thnum, VALUE binding, VALUE file, VALUE line)
263
340
 
264
341
  last_debugged_thnum = thnum;
265
342
  save_current_position(context);
266
- debug_suspend(mDebugger);
267
343
 
268
344
  args = rb_ary_new3(4, context, file, line, binding);
269
345
  return rb_protect(call_at_line_unprotected, args, 0);
@@ -330,7 +406,7 @@ check_breakpoints(debug_context_t *debug_context, VALUE file, VALUE klass, VALUE
330
406
 
331
407
  if(RARRAY(breakpoints)->len == 0)
332
408
  return -1;
333
- if(!debug_context->moved)
409
+ if(!CTX_FL_TEST(debug_context, CTX_FL_MOVED))
334
410
  return -1;
335
411
 
336
412
  for(i = 0; i < RARRAY(breakpoints)->len; i++)
@@ -366,23 +442,6 @@ create_binding(VALUE self)
366
442
  return f_binding(self);
367
443
  }
368
444
 
369
- static void
370
- check_suspend(debug_context_t *debug_context)
371
- {
372
- if(rb_thread_critical == Qtrue)
373
- return;
374
- while(1)
375
- {
376
- rb_thread_critical = Qtrue;
377
- if(!debug_context->suspend)
378
- break;
379
- rb_ary_push(waiting, rb_thread_current());
380
- debug_context->suspend = 0;
381
- rb_thread_stop();
382
- }
383
- rb_thread_critical = Qfalse;
384
- }
385
-
386
445
  static VALUE
387
446
  get_breakpoint_at(int index)
388
447
  {
@@ -422,25 +481,45 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
422
481
  if(!node) return;
423
482
 
424
483
  thread = rb_thread_current();
425
- while(locker != Qnil && locker != thread)
484
+ context = thread_context_lookup(thread);
485
+ Data_Get_Struct(context, debug_context_t, debug_context);
486
+
487
+ /* return if thread is marked as 'ignored'.
488
+ debugger's threads are marked this way
489
+ */
490
+ if(CTX_FL_TEST(debug_context, CTX_FL_IGNORE)) return;
491
+
492
+ while(1)
426
493
  {
427
- add_to_locked(thread);
428
- rb_thread_stop();
494
+ /* halt execution of the current thread if the debugger
495
+ is activated in another
496
+ */
497
+ while(locker != Qnil && locker != thread)
498
+ {
499
+ add_to_locked(thread);
500
+ rb_thread_stop();
501
+ }
502
+
503
+ /* stop the current thread if it's marked as suspended */
504
+ if(CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
505
+ rb_thread_stop();
506
+ else break;
429
507
  }
430
508
 
509
+ /* return if the current thread is the locker */
431
510
  if(locker != Qnil) return;
511
+
512
+ /* only the current thread can proceed */
513
+ locker = thread;
432
514
 
433
- locker = rb_thread_current();
434
-
435
- context = thread_context_lookup(thread);
436
- Data_Get_Struct(context, debug_context_t, debug_context);
437
- check_suspend(debug_context);
515
+ /* ignore a skipped section of code */
516
+ if(CTX_FL_TEST(debug_context, CTX_FL_SKIPPED)) goto cleanup;
438
517
 
439
518
  file = rb_str_new2(node->nd_file);
440
519
  line = INT2FIX(nd_line(node));
441
520
 
442
- if(did_moved())
443
- debug_context->moved = 1;
521
+ if(DID_MOVED)
522
+ CTX_FL_SET(debug_context, CTX_FL_MOVED);
444
523
 
445
524
  switch(event)
446
525
  {
@@ -448,7 +527,7 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
448
527
  {
449
528
  set_frame_source(debug_context, file, line);
450
529
 
451
- if(RTEST(tracing) || debug_context->tracing )
530
+ if(RTEST(tracing) || CTX_FL_TEST(debug_context, CTX_FL_TRACING))
452
531
  {
453
532
  rb_funcall(context, idAtTracing, 2, file, line);
454
533
  }
@@ -460,7 +539,7 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
460
539
  if(debug_context->stop_next < 0)
461
540
  debug_context->stop_next = -1;
462
541
  /* we check that we actualy moved to another line */
463
- if(did_moved())
542
+ if(DID_MOVED)
464
543
  {
465
544
  debug_context->stop_line--;
466
545
  }
@@ -574,17 +653,21 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
574
653
  }
575
654
  }
576
655
 
656
+ cleanup:
657
+
658
+ /* release a lock */
577
659
  locker = Qnil;
660
+ /* let the next thread to run */
578
661
  thread = remove_from_locked();
579
662
  if(thread != Qnil)
580
663
  rb_thread_run(thread);
581
664
  }
582
665
 
583
666
  static VALUE
584
- debug_stop_i(VALUE value)
667
+ debug_stop_i(VALUE self)
585
668
  {
586
669
  if(IS_STARTED)
587
- debug_stop(value);
670
+ debug_stop(self);
588
671
  return Qnil;
589
672
  }
590
673
 
@@ -595,8 +678,8 @@ debug_stop_i(VALUE value)
595
678
  *
596
679
  * This method activates the debugger.
597
680
  * If it's called without a block it returns +true+, unless debugger was already started.
598
- * If a block is given, it starts debugger and yields to block. At the end of stops the debugger
599
- * with Debugger.stop method.
681
+ * If a block is given, it starts debugger and yields to block. When the block is finished
682
+ * executing it stops the debugger with Debugger.stop method.
600
683
  *
601
684
  * <i>Note that if you want to stop debugger, you must call Debugger.stop as many time as you
602
685
  * called Debugger.start method.</i>
@@ -604,22 +687,24 @@ debug_stop_i(VALUE value)
604
687
  static VALUE
605
688
  debug_start(VALUE self)
606
689
  {
690
+ VALUE result;
607
691
  start_count++;
608
692
 
609
693
  if(IS_STARTED)
610
- return Qfalse;
611
-
612
- threads_tbl = rb_hash_new();
613
- breakpoints = rb_ary_new();
614
- waiting = rb_ary_new();
615
- locker = Qnil;
694
+ result = Qfalse;
695
+ else
696
+ {
697
+ breakpoints = rb_ary_new();
698
+ locker = Qnil;
699
+ threads_tbl = threads_table_create();
616
700
 
617
- rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL);
701
+ rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL);
702
+ result = Qtrue;
703
+ }
618
704
 
619
705
  if(rb_block_given_p())
620
706
  return rb_ensure(rb_yield, Qnil, debug_stop_i, self);
621
-
622
- return Qtrue;
707
+ return result;
623
708
  }
624
709
 
625
710
  /*
@@ -643,7 +728,6 @@ debug_stop(VALUE self)
643
728
 
644
729
  rb_remove_event_hook(debug_event_hook);
645
730
 
646
- waiting = Qnil;
647
731
  locker = Qnil;
648
732
  breakpoints = Qnil;
649
733
  threads_tbl = Qnil;
@@ -767,10 +851,13 @@ static VALUE
767
851
  debug_last_interrupted(VALUE self)
768
852
  {
769
853
  VALUE result = Qnil;
854
+ threads_table_t *threads_table;
770
855
 
771
856
  debug_check_started();
772
857
 
773
- rb_hash_foreach(threads_tbl, find_last_context_func, (st_data_t)&result);
858
+ Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
859
+
860
+ st_foreach(threads_table->tbl, find_last_context_func, (st_data_t)&result);
774
861
  return result;
775
862
  }
776
863
 
@@ -806,6 +893,7 @@ debug_contexts(VALUE self)
806
893
  volatile VALUE list;
807
894
  volatile VALUE new_list;
808
895
  VALUE thread, context;
896
+ threads_table_t *threads_table;
809
897
  debug_context_t *debug_context;
810
898
  int i;
811
899
 
@@ -819,15 +907,13 @@ debug_contexts(VALUE self)
819
907
  context = thread_context_lookup(thread);
820
908
  rb_ary_push(new_list, context);
821
909
  }
822
- /*
823
- * I wonder why rb_hash_clear is declared static?
824
- */
825
- rb_funcall(threads_tbl, idClear, 0);
910
+ threads_table_clear(threads_tbl);
911
+ Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
826
912
  for(i = 0; i < RARRAY(new_list)->len; i++)
827
913
  {
828
914
  context = rb_ary_entry(new_list, i);
829
915
  Data_Get_Struct(context, debug_context_t, debug_context);
830
- rb_hash_aset(threads_tbl, debug_context->thread, context);
916
+ st_insert(threads_table->tbl, debug_context->thread, context);
831
917
  }
832
918
 
833
919
  return new_list;
@@ -861,7 +947,7 @@ debug_suspend(VALUE self)
861
947
  if(current == context)
862
948
  continue;
863
949
  Data_Get_Struct(context, debug_context_t, debug_context);
864
- debug_context->suspend = 1;
950
+ CTX_FL_SET(debug_context, CTX_FL_SUSPEND);
865
951
  }
866
952
  rb_thread_critical = saved_crit;
867
953
 
@@ -882,7 +968,6 @@ debug_resume(VALUE self)
882
968
  {
883
969
  VALUE current, context;
884
970
  VALUE saved_crit;
885
- VALUE thread;
886
971
  VALUE context_list;
887
972
  debug_context_t *debug_context;
888
973
  int i;
@@ -900,14 +985,12 @@ debug_resume(VALUE self)
900
985
  if(current == context)
901
986
  continue;
902
987
  Data_Get_Struct(context, debug_context_t, debug_context);
903
- debug_context->suspend = 0;
904
- }
905
- for(i = 0; i < RARRAY(waiting)->len; i++)
906
- {
907
- thread = rb_ary_entry(waiting, i);
908
- rb_thread_run(thread);
988
+ if(CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
989
+ {
990
+ CTX_FL_UNSET(debug_context, CTX_FL_SUSPEND);
991
+ rb_thread_run(debug_context->thread);
992
+ }
909
993
  }
910
- rb_ary_clear(waiting);
911
994
  rb_thread_critical = saved_crit;
912
995
 
913
996
  rb_thread_schedule();
@@ -965,9 +1048,17 @@ debug_debug_load(VALUE self, VALUE file)
965
1048
  }
966
1049
 
967
1050
  static VALUE
968
- debug_skip_i(VALUE value)
1051
+ set_current_skipped_status(VALUE status)
969
1052
  {
970
- rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL);
1053
+ VALUE context;
1054
+ debug_context_t *debug_context;
1055
+
1056
+ context = debug_current_context(Qnil);
1057
+ Data_Get_Struct(context, debug_context_t, debug_context);
1058
+ if(status)
1059
+ CTX_FL_SET(debug_context, CTX_FL_SKIPPED);
1060
+ else
1061
+ CTX_FL_UNSET(debug_context, CTX_FL_SKIPPED);
971
1062
  return Qnil;
972
1063
  }
973
1064
 
@@ -985,8 +1076,8 @@ debug_skip(VALUE self)
985
1076
  }
986
1077
  if(!IS_STARTED)
987
1078
  return rb_yield(Qnil);
988
- rb_remove_event_hook(debug_event_hook);
989
- return rb_ensure(rb_yield, Qnil, debug_skip_i, Qnil);
1079
+ set_current_skipped_status(Qtrue);
1080
+ return rb_ensure(rb_yield, Qnil, set_current_skipped_status, Qfalse);
990
1081
  }
991
1082
 
992
1083
  static VALUE
@@ -1004,8 +1095,8 @@ debug_at_exit_i(VALUE proc)
1004
1095
  }
1005
1096
  else
1006
1097
  {
1007
- rb_remove_event_hook(debug_event_hook);
1008
- rb_ensure(debug_at_exit_c, proc, debug_skip_i, Qnil);
1098
+ set_current_skipped_status(Qtrue);
1099
+ rb_ensure(debug_at_exit_c, proc, set_current_skipped_status, Qfalse);
1009
1100
  }
1010
1101
  }
1011
1102
 
@@ -1151,37 +1242,42 @@ context_thnum(VALUE self)
1151
1242
 
1152
1243
  /*
1153
1244
  * call-seq:
1154
- * context.set_suspend -> nil
1245
+ * context.suspend -> nil
1155
1246
  *
1156
1247
  * Suspends the thread when it is running.
1157
1248
  */
1158
1249
  static VALUE
1159
- context_set_suspend(VALUE self)
1250
+ context_suspend(VALUE self)
1160
1251
  {
1161
1252
  debug_context_t *debug_context;
1162
1253
 
1163
1254
  debug_check_started();
1164
1255
 
1165
1256
  Data_Get_Struct(self, debug_context_t, debug_context);
1166
- debug_context->suspend = 1;
1257
+ if(CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
1258
+ rb_raise(rb_eRuntimeError, "Already suspended.");
1259
+ CTX_FL_SET(debug_context, CTX_FL_SUSPEND);
1167
1260
  return Qnil;
1168
1261
  }
1169
1262
 
1170
1263
  /*
1171
1264
  * call-seq:
1172
- * context.clear_suspend -> nil
1265
+ * context.resume -> nil
1173
1266
  *
1174
- * Clears a suspend flag.
1267
+ * Resumes the thread from the suspended mode.
1175
1268
  */
1176
1269
  static VALUE
1177
- context_clear_suspend(VALUE self)
1270
+ context_resume(VALUE self)
1178
1271
  {
1179
1272
  debug_context_t *debug_context;
1180
1273
 
1181
1274
  debug_check_started();
1182
1275
 
1183
1276
  Data_Get_Struct(self, debug_context_t, debug_context);
1184
- debug_context->suspend = 0;
1277
+ if(!CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
1278
+ rb_raise(rb_eRuntimeError, "Thread is not suspended.");
1279
+ CTX_FL_UNSET(debug_context, CTX_FL_SUSPEND);
1280
+ rb_thread_run(debug_context->thread);
1185
1281
  return Qnil;
1186
1282
  }
1187
1283
 
@@ -1199,7 +1295,7 @@ context_tracing(VALUE self)
1199
1295
  debug_check_started();
1200
1296
 
1201
1297
  Data_Get_Struct(self, debug_context_t, debug_context);
1202
- return debug_context->tracing ? Qtrue : Qfalse;
1298
+ return CTX_FL_TEST(debug_context, CTX_FL_TRACING) ? Qtrue : Qfalse;
1203
1299
  }
1204
1300
 
1205
1301
  /*
@@ -1216,7 +1312,48 @@ context_set_tracing(VALUE self, VALUE value)
1216
1312
  debug_check_started();
1217
1313
 
1218
1314
  Data_Get_Struct(self, debug_context_t, debug_context);
1219
- debug_context->tracing = RTEST(value) ? 1 : 0;
1315
+ if(RTEST(value))
1316
+ CTX_FL_SET(debug_context, CTX_FL_TRACING);
1317
+ else
1318
+ CTX_FL_UNSET(debug_context, CTX_FL_TRACING);
1319
+ return value;
1320
+ }
1321
+
1322
+ /*
1323
+ * call-seq:
1324
+ * context.ignore -> bool
1325
+ *
1326
+ * Returns the ignore flag for the current context.
1327
+ */
1328
+ static VALUE
1329
+ context_ignore(VALUE self)
1330
+ {
1331
+ debug_context_t *debug_context;
1332
+
1333
+ debug_check_started();
1334
+
1335
+ Data_Get_Struct(self, debug_context_t, debug_context);
1336
+ return CTX_FL_TEST(debug_context, CTX_FL_IGNORE) ? Qtrue : Qfalse;
1337
+ }
1338
+
1339
+ /*
1340
+ * call-seq:
1341
+ * context.tracking = bool
1342
+ *
1343
+ * Controls the ignore flag for this context.
1344
+ */
1345
+ static VALUE
1346
+ context_set_ignore(VALUE self, VALUE value)
1347
+ {
1348
+ debug_context_t *debug_context;
1349
+
1350
+ debug_check_started();
1351
+
1352
+ Data_Get_Struct(self, debug_context_t, debug_context);
1353
+ if(RTEST(value))
1354
+ CTX_FL_SET(debug_context, CTX_FL_IGNORE);
1355
+ else
1356
+ CTX_FL_UNSET(debug_context, CTX_FL_IGNORE);
1220
1357
  return value;
1221
1358
  }
1222
1359
 
@@ -1344,10 +1481,12 @@ Init_context()
1344
1481
  rb_define_method(cContext, "frames", context_frames, 0);
1345
1482
  rb_define_method(cContext, "thread", context_thread, 0);
1346
1483
  rb_define_method(cContext, "thnum", context_thnum, 0);
1347
- rb_define_method(cContext, "set_suspend", context_set_suspend, 0);
1348
- rb_define_method(cContext, "clear_suspend", context_clear_suspend, 0);
1484
+ rb_define_method(cContext, "suspend", context_suspend, 0);
1485
+ rb_define_method(cContext, "resume", context_resume, 0);
1349
1486
  rb_define_method(cContext, "tracing", context_tracing, 0);
1350
1487
  rb_define_method(cContext, "tracing=", context_set_tracing, 1);
1488
+ rb_define_method(cContext, "ignore", context_ignore, 0);
1489
+ rb_define_method(cContext, "ignore=", context_set_ignore, 1);
1351
1490
  }
1352
1491
 
1353
1492
  /*
@@ -1418,6 +1557,8 @@ Init_ruby_debug()
1418
1557
  rb_define_module_function(mDebugger, "skip", debug_skip, 0);
1419
1558
  rb_define_module_function(mDebugger, "debug_at_exit", debug_at_exit, 0);
1420
1559
 
1560
+ cThreadsTable = rb_define_class_under(mDebugger, "ThreadsTable", rb_cObject);
1561
+
1421
1562
  Init_context();
1422
1563
  Init_frame();
1423
1564
  Init_breakpoint();
@@ -1439,7 +1580,6 @@ Init_ruby_debug()
1439
1580
  rb_global_variable(&threads_tbl);
1440
1581
  rb_global_variable(&breakpoints);
1441
1582
  rb_global_variable(&catchpoint);
1442
- rb_global_variable(&waiting);
1443
1583
  rb_global_variable(&locker);
1444
1584
  rb_global_variable(&file_separator);
1445
1585
  rb_global_variable(&alt_file_separator);
data/lib/ruby-debug.rb CHANGED
@@ -2,13 +2,11 @@ require 'pp'
2
2
  require 'stringio'
3
3
  require 'thread'
4
4
  require 'ruby_debug.so'
5
- require 'ruby-debug/lock'
6
5
  require 'ruby-debug/processor'
7
6
 
8
7
  SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
9
8
 
10
9
  module Debugger
11
- MUTEX = Lock.new
12
10
  PORT = 8989
13
11
 
14
12
  @processor = CommandProcessor.new
@@ -37,10 +35,7 @@ module Debugger
37
35
  end
38
36
 
39
37
  def at_line(file, line, binding)
40
- MUTEX.lock
41
38
  processor.at_line(self, file, line, binding)
42
- MUTEX.unlock
43
- Debugger.resume
44
39
  end
45
40
  end
46
41
 
@@ -97,6 +92,7 @@ module Debugger
97
92
  end
98
93
 
99
94
  @control_thread = Thread.start do
95
+ current_context.ignore = true
100
96
  server = TCPServer.new(host, ctrl_port)
101
97
  while (session = server.accept)
102
98
  interface = RemoteInterface.new(session)
@@ -109,6 +105,7 @@ module Debugger
109
105
  proceed = ConditionVariable.new
110
106
 
111
107
  @thread = Thread.start do
108
+ current_context.ignore = true
112
109
  server = TCPServer.new(host, cmd_port)
113
110
  while (session = server.accept)
114
111
  self.interface = RemoteInterface.new(session)
@@ -36,10 +36,6 @@ module Debugger
36
36
  self.always_run = true
37
37
  include DisplayFunctions
38
38
 
39
- def initialize(state)
40
- super
41
- end
42
-
43
39
  def regexp
44
40
  /^\s*disp(?:lay)?$/
45
41
  end
@@ -100,7 +100,7 @@ module Debugger
100
100
  print "Already stopped.\n"
101
101
  else
102
102
  display_context(c)
103
- c.set_suspend
103
+ c.suspend
104
104
  end
105
105
  end
106
106
 
@@ -160,7 +160,7 @@ module Debugger
160
160
  print "Already running."
161
161
  else
162
162
  display_context(c)
163
- c.thread.run
163
+ c.resume
164
164
  end
165
165
  end
166
166
 
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.3
7
- date: 2006-10-09 18:04:00 -04:00
6
+ version: 0.4.4
7
+ date: 2006-10-15 18:27:41 -04:00
8
8
  summary: Fast Ruby debugger
9
9
  require_paths:
10
10
  - lib
@@ -38,7 +38,6 @@ files:
38
38
  - lib/ruby-debug/command.rb
39
39
  - lib/ruby-debug/commands
40
40
  - lib/ruby-debug/interface.rb
41
- - lib/ruby-debug/lock.rb
42
41
  - lib/ruby-debug/processor.rb
43
42
  - lib/ruby-debug/commands/breakpoints.rb
44
43
  - lib/ruby-debug/commands/catchpoint.rb
@@ -1,41 +0,0 @@
1
- module Debugger
2
- class Lock # :nodoc:
3
- def initialize
4
- @locker = nil
5
- @waiting = []
6
- @locked = false;
7
- end
8
-
9
- def locked?
10
- @locked
11
- end
12
-
13
- def lock
14
- return if Thread.critical
15
- return if @locker == Thread.current
16
- while (Thread.critical = true; @locked)
17
- @waiting.push Thread.current
18
- Thread.stop
19
- end
20
- @locked = true
21
- @locker = Thread.current
22
- Thread.critical = false
23
- self
24
- end
25
-
26
- def unlock
27
- return if Thread.critical
28
- return unless @locked
29
- unless @locker == Thread.current
30
- raise RuntimeError, "unlocked by other"
31
- end
32
- Thread.critical = true
33
- t = @waiting.shift
34
- @locked = false
35
- @locker = nil
36
- Thread.critical = false
37
- t.run if t
38
- self
39
- end
40
- end
41
- end