ruby-debug-base 0.10.0 → 0.10.1

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.
@@ -1,11 +1,13 @@
1
+ #include "ruby_debug.h"
2
+
1
3
  #include <stdio.h>
2
- #include <ruby.h>
3
4
  #include <node.h>
4
5
  #include <rubysig.h>
5
6
  #include <st.h>
6
7
  #include <version.h>
7
8
 
8
- #define DEBUG_VERSION "0.10.0"
9
+ #define DEBUG_VERSION "0.10.1"
10
+
9
11
 
10
12
  #ifdef _WIN32
11
13
  struct FRAME {
@@ -43,21 +45,6 @@ RUBY_EXTERN struct RVarmap *ruby_dyna_vars;
43
45
  #include <env.h>
44
46
  #endif
45
47
 
46
- #define CTX_FL_SUSPEND (1<<1)
47
- #define CTX_FL_TRACING (1<<2)
48
- #define CTX_FL_SKIPPED (1<<3)
49
- #define CTX_FL_IGNORE (1<<4)
50
- #define CTX_FL_DEAD (1<<5)
51
- #define CTX_FL_WAS_RUNNING (1<<6)
52
- #define CTX_FL_ENABLE_BKPT (1<<7)
53
- #define CTX_FL_STEPPED (1<<8)
54
- #define CTX_FL_FORCE_MOVE (1<<9)
55
-
56
- #define CTX_FL_TEST(c,f) ((c)->flags & (f))
57
- #define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0)
58
- #define CTX_FL_UNSET(c,f) do { (c)->flags &= ~(f); } while (0)
59
-
60
- #define IS_STARTED (threads_tbl != Qnil)
61
48
  #define FRAME_N(n) (&debug_context->frames[debug_context->stack_size-(n)-1])
62
49
  #define GET_FRAME (FRAME_N(check_frame_number(debug_context, frame)))
63
50
 
@@ -67,75 +54,10 @@ RUBY_EXTERN struct RVarmap *ruby_dyna_vars;
67
54
 
68
55
  #define STACK_SIZE_INCREMENT 128
69
56
 
70
- typedef struct {
71
- int argc; /* Number of arguments a frame should have. */
72
- VALUE binding;
73
- ID id;
74
- ID orig_id;
75
- int line;
76
- const char * file;
77
- short dead;
78
- VALUE self;
79
- VALUE arg_ary;
80
- union {
81
- struct {
82
- struct FRAME *frame;
83
- struct SCOPE *scope;
84
- struct RVarmap *dyna_vars;
85
- } runtime;
86
- struct {
87
- VALUE args;
88
- VALUE locals;
89
- VALUE arg_ary;
90
- } copy;
91
- } info;
92
- } debug_frame_t;
93
-
94
- enum ctx_stop_reason {CTX_STOP_NONE, CTX_STOP_STEP, CTX_STOP_BREAKPOINT, CTX_STOP_CATCHPOINT};
95
-
96
- typedef struct {
97
- VALUE thread_id;
98
- int thnum;
99
- int flags;
100
- enum ctx_stop_reason stop_reason;
101
- int stop_next;
102
- int dest_frame;
103
- int stop_line;
104
- int stop_frame;
105
- int stack_size;
106
- int stack_len;
107
- debug_frame_t *frames;
108
- const char * last_file;
109
- int last_line;
110
- VALUE breakpoint;
111
- } debug_context_t;
112
-
113
- enum bp_type {BP_POS_TYPE, BP_METHOD_TYPE};
114
- enum hit_condition {HIT_COND_NONE, HIT_COND_GE, HIT_COND_EQ, HIT_COND_MOD};
115
-
116
- typedef struct {
117
- int id;
118
- enum bp_type type;
119
- VALUE source;
120
- union
121
- {
122
- int line;
123
- ID mid;
124
- } pos;
125
- VALUE expr;
126
- VALUE enabled;
127
- int hit_count;
128
- int hit_value;
129
- enum hit_condition hit_condition;
130
- } debug_breakpoint_t;
131
-
132
57
  typedef struct {
133
58
  st_table *tbl;
134
59
  } threads_table_t;
135
60
 
136
- static VALUE threads_tbl = Qnil;
137
- static VALUE breakpoints = Qnil;
138
- static VALUE catchpoint = Qnil;
139
61
  static VALUE tracing = Qfalse;
140
62
  static VALUE locker = Qnil;
141
63
  static VALUE post_mortem = Qfalse;
@@ -147,20 +69,21 @@ static VALUE last_context = Qnil;
147
69
  static VALUE last_thread = Qnil;
148
70
  static debug_context_t *last_debug_context = NULL;
149
71
 
150
- static VALUE mDebugger;
72
+ VALUE rdebug_threads_tbl = Qnil; /* Context for each of the threads */
73
+ VALUE mDebugger; /* Ruby Debugger Module object */
74
+
151
75
  static VALUE cThreadsTable;
152
76
  static VALUE cContext;
153
- static VALUE cBreakpoint;
154
77
  static VALUE cDebugThread;
155
78
 
156
79
  static VALUE rb_mObjectSpace;
157
80
 
158
- static ID idAtLine;
159
81
  static ID idAtBreakpoint;
160
82
  static ID idAtCatchpoint;
83
+ static ID idAtLine;
84
+ static ID idAtReturn;
161
85
  static ID idAtTracing;
162
86
  static ID idList;
163
- static ID idEval;
164
87
 
165
88
  static int start_count = 0;
166
89
  static int thnum_max = 0;
@@ -186,6 +109,17 @@ typedef struct locked_thread_t {
186
109
  static locked_thread_t *locked_head = NULL;
187
110
  static locked_thread_t *locked_tail = NULL;
188
111
 
112
+ /* "Step", "Next" and "Finish" do their work by saving information
113
+ about where to stop next. reset_stopping_points removes/resets this
114
+ information. */
115
+ inline static void
116
+ reset_stepping_stop_points(debug_context_t *debug_context)
117
+ {
118
+ debug_context->dest_frame = -1;
119
+ debug_context->stop_line = -1;
120
+ debug_context->stop_next = -1;
121
+ }
122
+
189
123
  inline static VALUE
190
124
  real_class(VALUE klass)
191
125
  {
@@ -379,7 +313,7 @@ check_thread_contexts()
379
313
  {
380
314
  threads_table_t *threads_table;
381
315
 
382
- Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
316
+ Data_Get_Struct(rdebug_threads_tbl, threads_table_t, threads_table);
383
317
  st_foreach(threads_table->tbl, threads_table_check_i, 0);
384
318
  }
385
319
 
@@ -395,15 +329,6 @@ debug_is_started(VALUE self)
395
329
  return IS_STARTED ? Qtrue : Qfalse;
396
330
  }
397
331
 
398
- static void
399
- debug_check_started()
400
- {
401
- if(!IS_STARTED)
402
- {
403
- rb_raise(rb_eRuntimeError, "Debugger.start is not called yet.");
404
- }
405
- }
406
-
407
332
  static void
408
333
  debug_context_mark(void *data)
409
334
  {
@@ -505,7 +430,7 @@ thread_context_lookup(VALUE thread, VALUE *context, debug_context_t **debug_cont
505
430
  return;
506
431
  }
507
432
  thread_id = ref2id(thread);
508
- Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
433
+ Data_Get_Struct(rdebug_threads_tbl, threads_table_t, threads_table);
509
434
  if(!st_lookup(threads_table->tbl, thread_id, context))
510
435
  {
511
436
  *context = debug_context_create(thread);
@@ -541,6 +466,26 @@ call_at_line(VALUE context, debug_context_t *debug_context, VALUE file, VALUE li
541
466
  return rb_protect(call_at_line_unprotected, args, 0);
542
467
  }
543
468
 
469
+ static VALUE
470
+ call_at_return_unprotected(VALUE args)
471
+ {
472
+ VALUE context;
473
+ context = *RARRAY(args)->ptr;
474
+ return rb_funcall2(context, idAtReturn, RARRAY(args)->len - 1, RARRAY(args)->ptr + 1);
475
+ }
476
+
477
+ static VALUE
478
+ call_at_return(VALUE context, debug_context_t *debug_context, VALUE file, VALUE line)
479
+ {
480
+ VALUE args;
481
+
482
+ last_debugged_thnum = debug_context->thnum;
483
+ save_current_position(debug_context);
484
+
485
+ args = rb_ary_new3(3, context, file, line);
486
+ return rb_protect(call_at_return_unprotected, args, 0);
487
+ }
488
+
544
489
  static void
545
490
  save_call_frame(rb_event_t event, VALUE self, char *file, int line, ID mid, debug_context_t *debug_context)
546
491
  {
@@ -579,7 +524,7 @@ save_call_frame(rb_event_t event, VALUE self, char *file, int line, ID mid, debu
579
524
  #define isdirsep(x) ((x) == '/')
580
525
  #endif
581
526
 
582
- static int
527
+ int
583
528
  filename_cmp(VALUE source, char *file)
584
529
  {
585
530
  char *source_ptr, *file_ptr;
@@ -606,133 +551,6 @@ filename_cmp(VALUE source, char *file)
606
551
  return 1;
607
552
  }
608
553
 
609
- inline static int
610
- classname_cmp(VALUE name, VALUE klass)
611
- {
612
- VALUE class_name = (Qnil == name) ? rb_str_new2("main") : name;
613
- return (klass != Qnil
614
- && rb_str_cmp(class_name, rb_mod_name(klass)) == 0);
615
- }
616
-
617
- static int
618
- check_breakpoint_hit_condition(VALUE breakpoint)
619
- {
620
- debug_breakpoint_t *debug_breakpoint;
621
-
622
- if(breakpoint == Qnil)
623
- return 0;
624
- Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
625
-
626
- debug_breakpoint->hit_count++;
627
- if (!Qtrue == debug_breakpoint->enabled) return 0;
628
- switch(debug_breakpoint->hit_condition)
629
- {
630
- case HIT_COND_NONE:
631
- return 1;
632
- case HIT_COND_GE:
633
- {
634
- if(debug_breakpoint->hit_count >= debug_breakpoint->hit_value)
635
- return 1;
636
- break;
637
- }
638
- case HIT_COND_EQ:
639
- {
640
- if(debug_breakpoint->hit_count == debug_breakpoint->hit_value)
641
- return 1;
642
- break;
643
- }
644
- case HIT_COND_MOD:
645
- {
646
- if(debug_breakpoint->hit_count % debug_breakpoint->hit_value == 0)
647
- return 1;
648
- break;
649
- }
650
- }
651
- return 0;
652
- }
653
-
654
- static int
655
- check_breakpoint_by_pos(VALUE breakpoint, char *file, int line)
656
- {
657
- debug_breakpoint_t *debug_breakpoint;
658
-
659
- if(breakpoint == Qnil)
660
- return 0;
661
- Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
662
- if (!Qtrue == debug_breakpoint->enabled) return 0;
663
- if(debug_breakpoint->type != BP_POS_TYPE)
664
- return 0;
665
- if(debug_breakpoint->pos.line != line)
666
- return 0;
667
- if(filename_cmp(debug_breakpoint->source, file))
668
- return 1;
669
- return 0;
670
- }
671
-
672
- static int
673
- check_breakpoint_by_method(VALUE breakpoint, VALUE klass, ID mid)
674
- {
675
- debug_breakpoint_t *debug_breakpoint;
676
-
677
- if(breakpoint == Qnil)
678
- return 0;
679
- Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
680
- if (!Qtrue == debug_breakpoint->enabled) return 0;
681
- if(debug_breakpoint->type != BP_METHOD_TYPE)
682
- return 0;
683
- if(debug_breakpoint->pos.mid != mid)
684
- return 0;
685
- if(classname_cmp(debug_breakpoint->source, klass))
686
- return 1;
687
- return 0;
688
- }
689
-
690
- static VALUE
691
- check_breakpoints_by_pos(debug_context_t *debug_context, char *file, int line)
692
- {
693
- VALUE breakpoint;
694
- int i;
695
-
696
- if(!CTX_FL_TEST(debug_context, CTX_FL_ENABLE_BKPT))
697
- return Qnil;
698
-
699
- if(check_breakpoint_by_pos(debug_context->breakpoint, file, line))
700
- return debug_context->breakpoint;
701
-
702
- if(RARRAY(breakpoints)->len == 0)
703
- return Qnil;
704
- for(i = 0; i < RARRAY(breakpoints)->len; i++)
705
- {
706
- breakpoint = rb_ary_entry(breakpoints, i);
707
- if(check_breakpoint_by_pos(breakpoint, file, line))
708
- return breakpoint;
709
- }
710
- return Qnil;
711
- }
712
-
713
- static VALUE
714
- check_breakpoints_by_method(debug_context_t *debug_context, VALUE klass, ID mid)
715
- {
716
- VALUE breakpoint;
717
- int i;
718
-
719
- if(!CTX_FL_TEST(debug_context, CTX_FL_ENABLE_BKPT))
720
- return Qnil;
721
-
722
- if(check_breakpoint_by_method(debug_context->breakpoint, klass, mid))
723
- return debug_context->breakpoint;
724
-
725
- if(RARRAY(breakpoints)->len == 0)
726
- return Qnil;
727
- for(i = 0; i < RARRAY(breakpoints)->len; i++)
728
- {
729
- breakpoint = rb_ary_entry(breakpoints, i);
730
- if(check_breakpoint_by_method(breakpoint, klass, mid))
731
- return breakpoint;
732
- }
733
- return Qnil;
734
- }
735
-
736
554
  /*
737
555
  * This is a NASTY HACK. For some reasons rb_f_binding is declared
738
556
  * static in eval.c. So we create a cons up call to binding in C.
@@ -750,27 +568,6 @@ create_binding(VALUE self)
750
568
  return f_binding(self);
751
569
  }
752
570
 
753
- static VALUE
754
- eval_expression(VALUE args)
755
- {
756
- return rb_funcall2(rb_mKernel, idEval, 2, RARRAY(args)->ptr);
757
- }
758
-
759
- inline static int
760
- check_breakpoint_expression(VALUE breakpoint, VALUE binding)
761
- {
762
- debug_breakpoint_t *debug_breakpoint;
763
- VALUE args, expr_result;
764
-
765
- Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
766
- if(NIL_P(debug_breakpoint->expr))
767
- return 1;
768
-
769
- args = rb_ary_new3(2, debug_breakpoint->expr, binding);
770
- expr_result = rb_protect(eval_expression, args, 0);
771
- return RTEST(expr_result);
772
- }
773
-
774
571
  inline static debug_frame_t *
775
572
  get_top_frame(debug_context_t *debug_context)
776
573
  {
@@ -999,12 +796,9 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
999
796
  debug_context->breakpoint = Qnil;
1000
797
  }
1001
798
 
1002
- /* reset all pointers */
1003
- debug_context->dest_frame = -1;
1004
- debug_context->stop_line = -1;
1005
- debug_context->stop_next = -1;
1006
-
1007
- call_at_line(context, debug_context, rb_str_new2(file), INT2FIX(line));
799
+ reset_stepping_stop_points(debug_context);
800
+ call_at_line(context, debug_context, rb_str_new2(file),
801
+ INT2FIX(line));
1008
802
  }
1009
803
  break;
1010
804
  }
@@ -1056,8 +850,15 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1056
850
  {
1057
851
  if(debug_context->stack_size == debug_context->stop_frame)
1058
852
  {
1059
- debug_context->stop_next = 1;
1060
- debug_context->stop_frame = 0;
853
+ if(debug_context->stack_size == 0)
854
+ save_call_frame(event, self, file, line, mid, debug_context);
855
+ else
856
+ set_frame_source(event, debug_context, self, file, line, mid);
857
+ binding = self? create_binding(self) : Qnil;
858
+ save_top_binding(debug_context, binding);
859
+ call_at_return(context, debug_context, rb_str_new2(file),
860
+ INT2FIX(line));
861
+ debug_context->dest_frame = -1;
1061
862
  }
1062
863
  while(debug_context->stack_size > 0)
1063
864
  {
@@ -1065,7 +866,6 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1065
866
  if(debug_context->frames[debug_context->stack_size].orig_id == mid)
1066
867
  break;
1067
868
  }
1068
- CTX_FL_SET(debug_context, CTX_FL_ENABLE_BKPT);
1069
869
  break;
1070
870
  }
1071
871
  case RUBY_EVENT_CLASS:
@@ -1092,21 +892,43 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1092
892
  }
1093
893
 
1094
894
  expn_class = rb_obj_class(ruby_errinfo);
895
+
896
+ /* This code goes back to the earliest days of ruby-debug. It
897
+ tends to disallow catching an exception via the
898
+ "catchpoint" command. To address this one possiblilty is to
899
+ move this after testing for catchponts. Kent however thinks
900
+ there may be a misfeature in Ruby's eval.c: the problem was
901
+ in the fact that Ruby doesn't reset exception flag on the
902
+ current thread before it calls a notification handler.
903
+
904
+ See also the #ifdef'd code below as well.
905
+ */
906
+ #ifdef NORMAL_CODE
1095
907
  if( !NIL_P(rb_class_inherited_p(expn_class, rb_eSystemExit)) )
1096
908
  {
1097
909
  debug_stop(mDebugger);
1098
910
  break;
1099
911
  }
912
+ #endif
1100
913
 
1101
- if(catchpoint == Qnil)
914
+ if (rdebug_catchpoints == Qnil ||
915
+ RHASH(rdebug_catchpoints)->tbl->num_entries == 0)
1102
916
  break;
1103
917
 
1104
918
  ancestors = rb_mod_ancestors(expn_class);
1105
919
  for(i = 0; i < RARRAY(ancestors)->len; i++)
1106
920
  {
1107
- aclass = rb_ary_entry(ancestors, i);
1108
- if(rb_str_cmp(rb_mod_name(aclass), catchpoint) == 0)
921
+ VALUE mod_name;
922
+ VALUE hit_count;
923
+
924
+ aclass = rb_ary_entry(ancestors, i);
925
+ mod_name = rb_mod_name(aclass);
926
+ hit_count = rb_hash_aref(rdebug_catchpoints, mod_name);
927
+ if(hit_count != Qnil)
1109
928
  {
929
+ hit_count = INT2FIX(FIX2INT(rb_hash_aref(rdebug_catchpoints,
930
+ mod_name)+1));
931
+ rb_hash_aset(rdebug_catchpoints, mod_name, hit_count);
1110
932
  debug_context->stop_reason = CTX_STOP_CATCHPOINT;
1111
933
  rb_funcall(context, idAtCatchpoint, 1, ruby_errinfo);
1112
934
  if(self && binding == Qnil)
@@ -1117,6 +939,18 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1117
939
  }
1118
940
  }
1119
941
 
942
+ /* If we stop the debugger, we may not be able to trace into
943
+ code that has an exception handler wrapped around it. So
944
+ the alternative is to force the user to do his own
945
+ Debugger.stop. */
946
+ #ifdef NORMAL_CODE_MOVING_AFTER_
947
+ if( !NIL_P(rb_class_inherited_p(expn_class, rb_eSystemExit)) )
948
+ {
949
+ debug_stop(mDebugger);
950
+ break;
951
+ }
952
+ #endif
953
+
1120
954
  break;
1121
955
  }
1122
956
  }
@@ -1150,16 +984,20 @@ debug_stop_i(VALUE self)
1150
984
 
1151
985
  /*
1152
986
  * call-seq:
1153
- * Debugger.start -> bool
1154
- * Debugger.start { ... } -> obj
987
+ * Debugger.start_ -> bool
988
+ * Debugger.start_ { ... } -> obj
989
+ *
990
+ * This method is internal and activates the debugger. Use
991
+ * Debugger.start (from ruby-debug-base.rb) instead.
1155
992
  *
1156
- * This method activates the debugger.
1157
- * If it's called without a block it returns +true+, unless debugger was already started.
1158
- * If a block is given, it starts debugger and yields to block. When the block is finished
1159
- * executing it stops the debugger with Debugger.stop method.
993
+ * If it's called without a block it returns +true+, unless debugger
994
+ * was already started. If a block is given, it starts debugger and
995
+ * yields to block. When the block is finished executing it stops
996
+ * the debugger with Debugger.stop method.
1160
997
  *
1161
- * <i>Note that if you want to stop debugger, you must call Debugger.stop as many time as you
1162
- * called Debugger.start method.</i>
998
+ * <i>Note that if you want to stop debugger, you must call
999
+ * Debugger.stop as many time as you called Debugger.start
1000
+ * method.</i>
1163
1001
  */
1164
1002
  static VALUE
1165
1003
  debug_start(VALUE self)
@@ -1171,9 +1009,10 @@ debug_start(VALUE self)
1171
1009
  result = Qfalse;
1172
1010
  else
1173
1011
  {
1174
- breakpoints = rb_ary_new();
1175
- locker = Qnil;
1176
- threads_tbl = threads_table_create();
1012
+ locker = Qnil;
1013
+ rdebug_breakpoints = rb_ary_new();
1014
+ rdebug_catchpoints = rb_hash_new();
1015
+ rdebug_threads_tbl = threads_table_create();
1177
1016
 
1178
1017
  rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL);
1179
1018
  result = Qtrue;
@@ -1206,156 +1045,13 @@ debug_stop(VALUE self)
1206
1045
 
1207
1046
  rb_remove_event_hook(debug_event_hook);
1208
1047
 
1209
- locker = Qnil;
1210
- breakpoints = Qnil;
1211
- threads_tbl = Qnil;
1048
+ locker = Qnil;
1049
+ rdebug_breakpoints = Qnil;
1050
+ rdebug_threads_tbl = Qnil;
1212
1051
 
1213
1052
  return Qtrue;
1214
1053
  }
1215
1054
 
1216
- static void
1217
- breakpoint_mark(void *data)
1218
- {
1219
- debug_breakpoint_t *breakpoint;
1220
- breakpoint = (debug_breakpoint_t *)data;
1221
- rb_gc_mark(breakpoint->source);
1222
- rb_gc_mark(breakpoint->expr);
1223
- }
1224
-
1225
- static VALUE
1226
- create_breakpoint_from_args(int argc, VALUE *argv, int id)
1227
- {
1228
- VALUE source, pos, expr;
1229
- debug_breakpoint_t *breakpoint;
1230
- int type;
1231
-
1232
- if(rb_scan_args(argc, argv, "21", &source, &pos, &expr) == 2)
1233
- {
1234
- expr = Qnil;
1235
- }
1236
- type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
1237
- if(type == BP_POS_TYPE)
1238
- source = StringValue(source);
1239
- else
1240
- pos = StringValue(pos);
1241
- breakpoint = ALLOC(debug_breakpoint_t);
1242
- breakpoint->id = id;
1243
- breakpoint->source = source;
1244
- breakpoint->type = type;
1245
- if(type == BP_POS_TYPE)
1246
- breakpoint->pos.line = FIX2INT(pos);
1247
- else
1248
- breakpoint->pos.mid = rb_intern(RSTRING(pos)->ptr);
1249
- breakpoint->enabled = Qtrue;
1250
- breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
1251
- breakpoint->hit_count = 0;
1252
- breakpoint->hit_value = 0;
1253
- breakpoint->hit_condition = HIT_COND_NONE;
1254
- return Data_Wrap_Struct(cBreakpoint, breakpoint_mark, xfree, breakpoint);
1255
- }
1256
-
1257
- /*
1258
- * call-seq:
1259
- * Debugger.add_breakpoint(source, pos, condition = nil) -> breakpoint
1260
- *
1261
- * Adds a new breakpoint.
1262
- * <i>source</i> is a name of a file or a class.
1263
- * <i>pos</i> is a line number or a method name if <i>source</i> is a class name.
1264
- * <i>condition</i> is a string which is evaluated to +true+ when this breakpoint
1265
- * is activated.
1266
- */
1267
- static VALUE
1268
- debug_add_breakpoint(int argc, VALUE *argv, VALUE self)
1269
- {
1270
- VALUE result;
1271
-
1272
- debug_check_started();
1273
-
1274
- result = create_breakpoint_from_args(argc, argv, ++bkp_count);
1275
- rb_ary_push(breakpoints, result);
1276
- return result;
1277
- }
1278
-
1279
- /*
1280
- * call-seq:
1281
- * Debugger.remove_breakpoint(id) -> breakpoint
1282
- *
1283
- * Removes breakpoint by its id.
1284
- * <i>id</i> is an identificator of a breakpoint.
1285
- */
1286
- static VALUE
1287
- debug_remove_breakpoint(VALUE self, VALUE id_value)
1288
- {
1289
- int i;
1290
- int id;
1291
- VALUE breakpoint;
1292
- debug_breakpoint_t *debug_breakpoint;
1293
-
1294
- id = FIX2INT(id_value);
1295
-
1296
- for( i = 0; i < RARRAY(breakpoints)->len; i += 1 )
1297
- {
1298
- breakpoint = rb_ary_entry(breakpoints, i);
1299
- Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
1300
- if(debug_breakpoint->id == id)
1301
- {
1302
- rb_ary_delete_at(breakpoints, i);
1303
- return breakpoint;
1304
- }
1305
- }
1306
- return Qnil;
1307
- }
1308
-
1309
- /*
1310
- * call-seq:
1311
- * Debugger.breakpoints -> array
1312
- *
1313
- * Returns an array of breakpoints.
1314
- */
1315
- static VALUE
1316
- debug_breakpoints(VALUE self)
1317
- {
1318
- debug_check_started();
1319
-
1320
- return breakpoints;
1321
- }
1322
-
1323
- /*
1324
- * call-seq:
1325
- * Debugger.checkpoint -> string
1326
- *
1327
- * Returns a current checkpoint, which is a name of exception that will
1328
- * trigger a debugger when raised.
1329
- */
1330
- static VALUE
1331
- debug_catchpoint(VALUE self)
1332
- {
1333
- debug_check_started();
1334
-
1335
- return catchpoint;
1336
- }
1337
-
1338
- /*
1339
- * call-seq:
1340
- * Debugger.checkpoint = string -> string
1341
- *
1342
- * Sets checkpoint.
1343
- */
1344
- static VALUE
1345
- debug_set_catchpoint(VALUE self, VALUE value)
1346
- {
1347
- debug_check_started();
1348
-
1349
- if (!NIL_P(value) && TYPE(value) != T_STRING) {
1350
- rb_raise(rb_eTypeError, "value of checkpoint must be String");
1351
- }
1352
- if(NIL_P(value))
1353
- catchpoint = Qnil;
1354
- else
1355
- catchpoint = rb_str_dup(value);
1356
- return value;
1357
- }
1358
-
1359
1055
  static int
1360
1056
  find_last_context_func(VALUE key, VALUE value, VALUE *result)
1361
1057
  {
@@ -1383,7 +1079,7 @@ debug_last_interrupted(VALUE self)
1383
1079
 
1384
1080
  debug_check_started();
1385
1081
 
1386
- Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
1082
+ Data_Get_Struct(rdebug_threads_tbl, threads_table_t, threads_table);
1387
1083
 
1388
1084
  st_foreach(threads_table->tbl, find_last_context_func, (st_data_t)&result);
1389
1085
  return result;
@@ -1451,8 +1147,8 @@ debug_contexts(VALUE self)
1451
1147
  thread_context_lookup(thread, &context, NULL);
1452
1148
  rb_ary_push(new_list, context);
1453
1149
  }
1454
- threads_table_clear(threads_tbl);
1455
- Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
1150
+ threads_table_clear(rdebug_threads_tbl);
1151
+ Data_Get_Struct(rdebug_threads_tbl, threads_table_t, threads_table);
1456
1152
  for(i = 0; i < RARRAY(new_list)->len; i++)
1457
1153
  {
1458
1154
  context = rb_ary_entry(new_list, i);
@@ -1676,7 +1372,8 @@ debug_debug_load(int argc, VALUE *argv, VALUE self)
1676
1372
  {
1677
1373
  VALUE file, stop, context;
1678
1374
  debug_context_t *debug_context;
1679
-
1375
+ int state = 0;
1376
+
1680
1377
  if(rb_scan_args(argc, argv, "11", &file, &stop) == 1)
1681
1378
  stop = Qfalse;
1682
1379
 
@@ -1686,8 +1383,14 @@ debug_debug_load(int argc, VALUE *argv, VALUE self)
1686
1383
  debug_context->stack_size = 0;
1687
1384
  if(RTEST(stop))
1688
1385
  debug_context->stop_next = 1;
1689
- rb_load(file, 0);
1690
-
1386
+ rb_load_protect(file, 0, &state);
1387
+ if (0 != state) {
1388
+ VALUE errinfo = ruby_errinfo;
1389
+ debug_suspend(self);
1390
+ reset_stepping_stop_points(debug_context);
1391
+ ruby_errinfo = Qnil;
1392
+ return errinfo;
1393
+ }
1691
1394
  debug_stop(self);
1692
1395
  return Qnil;
1693
1396
  }
@@ -1836,7 +1539,7 @@ context_step_over(int argc, VALUE *argv, VALUE self)
1836
1539
  * call-seq:
1837
1540
  * context.stop_frame(frame)
1838
1541
  *
1839
- * Stops when a frame with number +frame+ is activated. Implements +up+ and +down+ commands.
1542
+ * Stops when a frame with number +frame+ is activated. Implements +finish+ and +next+ commands.
1840
1543
  */
1841
1544
  static VALUE
1842
1545
  context_stop_frame(VALUE self, VALUE frame)
@@ -2395,50 +2098,6 @@ context_dead(VALUE self)
2395
2098
  return CTX_FL_TEST(debug_context, CTX_FL_DEAD) ? Qtrue : Qfalse;
2396
2099
  }
2397
2100
 
2398
- /*
2399
- * call-seq:
2400
- * context.breakpoint -> breakpoint
2401
- *
2402
- * Returns a context-specific temporary Breakpoint object.
2403
- */
2404
- static VALUE
2405
- context_breakpoint(VALUE self)
2406
- {
2407
- debug_context_t *debug_context;
2408
-
2409
- debug_check_started();
2410
-
2411
- Data_Get_Struct(self, debug_context_t, debug_context);
2412
- return debug_context->breakpoint;
2413
- }
2414
-
2415
- /*
2416
- * call-seq:
2417
- * context.set_breakpoint(source, pos, condition = nil) -> breakpoint
2418
- *
2419
- * Sets a context-specific temporary breakpoint, which can be used to implement
2420
- * 'Run to Cursor' debugger function. When this breakpoint is reached, it will be
2421
- * cleared out.
2422
- *
2423
- * <i>source</i> is a name of a file or a class.
2424
- * <i>pos</i> is a line number or a method name if <i>source</i> is a class name.
2425
- * <i>condition</i> is a string which is evaluated to +true+ when this breakpoint
2426
- * is activated.
2427
- */
2428
- static VALUE
2429
- context_set_breakpoint(int argc, VALUE *argv, VALUE self)
2430
- {
2431
- VALUE result;
2432
- debug_context_t *debug_context;
2433
-
2434
- debug_check_started();
2435
-
2436
- Data_Get_Struct(self, debug_context_t, debug_context);
2437
- result = create_breakpoint_from_args(argc, argv, 0);
2438
- debug_context->breakpoint = result;
2439
- return result;
2440
- }
2441
-
2442
2101
  /*
2443
2102
  * call-seq:
2444
2103
  * context.stop_reason -> sym
@@ -2478,256 +2137,6 @@ context_stop_reason(VALUE self)
2478
2137
  }
2479
2138
 
2480
2139
 
2481
- /*
2482
- * call-seq:
2483
- * breakpoint.enabled?
2484
- *
2485
- * Returns whether breakpoint is enabled or not.
2486
- */
2487
- static VALUE
2488
- breakpoint_enabled(VALUE self)
2489
- {
2490
- debug_breakpoint_t *breakpoint;
2491
-
2492
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2493
- return breakpoint->enabled;
2494
- }
2495
-
2496
- /*
2497
- * call-seq:
2498
- * breakpoint.enabled = bool
2499
- *
2500
- * Enables or disables breakpoint.
2501
- */
2502
- static VALUE
2503
- breakpoint_set_enabled(VALUE self, VALUE bool)
2504
- {
2505
- debug_breakpoint_t *breakpoint;
2506
-
2507
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2508
- return breakpoint->enabled = bool;
2509
- }
2510
-
2511
- /*
2512
- * call-seq:
2513
- * breakpoint.source -> string
2514
- *
2515
- * Returns a source of the breakpoint.
2516
- */
2517
- static VALUE
2518
- breakpoint_source(VALUE self)
2519
- {
2520
- debug_breakpoint_t *breakpoint;
2521
-
2522
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2523
- return breakpoint->source;
2524
- }
2525
-
2526
- /*
2527
- * call-seq:
2528
- * breakpoint.source = string
2529
- *
2530
- * Sets the source of the breakpoint.
2531
- */
2532
- static VALUE
2533
- breakpoint_set_source(VALUE self, VALUE value)
2534
- {
2535
- debug_breakpoint_t *breakpoint;
2536
-
2537
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2538
- breakpoint->source = StringValue(value);
2539
- return value;
2540
- }
2541
-
2542
- /*
2543
- * call-seq:
2544
- * breakpoint.pos -> string or int
2545
- *
2546
- * Returns a position of this breakpoint.
2547
- */
2548
- static VALUE
2549
- breakpoint_pos(VALUE self)
2550
- {
2551
- debug_breakpoint_t *breakpoint;
2552
-
2553
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2554
- if(breakpoint->type == BP_METHOD_TYPE)
2555
- return rb_str_new2(rb_id2name(breakpoint->pos.mid));
2556
- else
2557
- return INT2FIX(breakpoint->pos.line);
2558
- }
2559
-
2560
- /*
2561
- * call-seq:
2562
- * breakpoint.pos = string or int
2563
- *
2564
- * Sets the position of this breakpoint.
2565
- */
2566
- static VALUE
2567
- breakpoint_set_pos(VALUE self, VALUE value)
2568
- {
2569
- debug_breakpoint_t *breakpoint;
2570
-
2571
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2572
- if(breakpoint->type == BP_METHOD_TYPE)
2573
- {
2574
- breakpoint->pos.mid = rb_to_id(StringValue(value));
2575
- }
2576
- else
2577
- breakpoint->pos.line = FIX2INT(value);
2578
- return value;
2579
- }
2580
-
2581
- /*
2582
- * call-seq:
2583
- * breakpoint.expr -> string
2584
- *
2585
- * Returns a codition expression when this breakpoint should be activated.
2586
- */
2587
- static VALUE
2588
- breakpoint_expr(VALUE self)
2589
- {
2590
- debug_breakpoint_t *breakpoint;
2591
-
2592
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2593
- return breakpoint->expr;
2594
- }
2595
-
2596
- /*
2597
- * call-seq:
2598
- * breakpoint.expr = string
2599
- *
2600
- * Sets the codition expression when this breakpoint should be activated.
2601
- */
2602
- static VALUE
2603
- breakpoint_set_expr(VALUE self, VALUE value)
2604
- {
2605
- debug_breakpoint_t *breakpoint;
2606
-
2607
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2608
- breakpoint->expr = StringValue(value);
2609
- return value;
2610
- }
2611
-
2612
- /*
2613
- * call-seq:
2614
- * breakpoint.id -> int
2615
- *
2616
- * Returns id of the breakpoint.
2617
- */
2618
- static VALUE
2619
- breakpoint_id(VALUE self)
2620
- {
2621
- debug_breakpoint_t *breakpoint;
2622
-
2623
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2624
- return INT2FIX(breakpoint->id);
2625
- }
2626
-
2627
- /*
2628
- * call-seq:
2629
- * breakpoint.hit_count -> int
2630
- *
2631
- * Returns the hit count of the breakpoint.
2632
- */
2633
- static VALUE
2634
- breakpoint_hit_count(VALUE self)
2635
- {
2636
- debug_breakpoint_t *breakpoint;
2637
-
2638
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2639
- return INT2FIX(breakpoint->hit_count);
2640
- }
2641
-
2642
- /*
2643
- * call-seq:
2644
- * breakpoint.hit_value -> int
2645
- *
2646
- * Returns the hit value of the breakpoint.
2647
- */
2648
- static VALUE
2649
- breakpoint_hit_value(VALUE self)
2650
- {
2651
- debug_breakpoint_t *breakpoint;
2652
-
2653
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2654
- return INT2FIX(breakpoint->hit_value);
2655
- }
2656
-
2657
- /*
2658
- * call-seq:
2659
- * breakpoint.hit_value = int
2660
- *
2661
- * Sets the hit value of the breakpoint.
2662
- */
2663
- static VALUE
2664
- breakpoint_set_hit_value(VALUE self, VALUE value)
2665
- {
2666
- debug_breakpoint_t *breakpoint;
2667
-
2668
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2669
- breakpoint->hit_value = FIX2INT(value);
2670
- return value;
2671
- }
2672
-
2673
- /*
2674
- * call-seq:
2675
- * breakpoint.hit_condition -> symbol
2676
- *
2677
- * Returns the hit condition of the breakpoint:
2678
- *
2679
- * +nil+ if it is an unconditional breakpoint, or
2680
- * :greater_or_equal, :equal, :modulo
2681
- */
2682
- static VALUE
2683
- breakpoint_hit_condition(VALUE self)
2684
- {
2685
- debug_breakpoint_t *breakpoint;
2686
-
2687
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2688
- switch(breakpoint->hit_condition)
2689
- {
2690
- case HIT_COND_GE:
2691
- return ID2SYM(rb_intern("greater_or_equal"));
2692
- case HIT_COND_EQ:
2693
- return ID2SYM(rb_intern("equal"));
2694
- case HIT_COND_MOD:
2695
- return ID2SYM(rb_intern("modulo"));
2696
- case HIT_COND_NONE:
2697
- default:
2698
- return Qnil;
2699
- }
2700
- }
2701
-
2702
- /*
2703
- * call-seq:
2704
- * breakpoint.hit_condition = symbol
2705
- *
2706
- * Sets the hit condition of the breakpoint which must be one of the following values:
2707
- *
2708
- * +nil+ if it is an unconditional breakpoint, or
2709
- * :greater_or_equal(:ge), :equal(:eq), :modulo(:mod)
2710
- */
2711
- static VALUE
2712
- breakpoint_set_hit_condition(VALUE self, VALUE value)
2713
- {
2714
- debug_breakpoint_t *breakpoint;
2715
- ID id_value;
2716
-
2717
- Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
2718
- id_value = rb_to_id(value);
2719
-
2720
- if(rb_intern("greater_or_equal") == id_value || rb_intern("ge") == id_value)
2721
- breakpoint->hit_condition = HIT_COND_GE;
2722
- else if(rb_intern("equal") == id_value || rb_intern("eq") == id_value)
2723
- breakpoint->hit_condition = HIT_COND_EQ;
2724
- else if(rb_intern("modulo") == id_value || rb_intern("mod") == id_value)
2725
- breakpoint->hit_condition = HIT_COND_MOD;
2726
- else
2727
- rb_raise(rb_eArgError, "Invalid condition parameter");
2728
- return value;
2729
- }
2730
-
2731
2140
  /*
2732
2141
  * Document-class: Context
2733
2142
  *
@@ -2764,38 +2173,47 @@ Init_context()
2764
2173
  rb_define_method(cContext, "frame_self", context_frame_self, -1);
2765
2174
  rb_define_method(cContext, "stack_size", context_stack_size, 0);
2766
2175
  rb_define_method(cContext, "dead?", context_dead, 0);
2767
- rb_define_method(cContext, "breakpoint", context_breakpoint, 0);
2768
- rb_define_method(cContext, "set_breakpoint", context_set_breakpoint, -1);
2176
+ rb_define_method(cContext, "breakpoint",
2177
+ context_breakpoint, 0); /* in breakpoint.c */
2178
+ rb_define_method(cContext, "set_breakpoint",
2179
+ context_set_breakpoint, -1); /* in breakpoint.c */
2769
2180
  }
2770
2181
 
2771
2182
  /*
2772
- * Document-class: Breakpoint
2773
- *
2774
- * == Summary
2183
+ * call-seq:
2184
+ * Debugger.breakpoints -> array
2775
2185
  *
2776
- * This class represents a breakpoint. It defines position of the breakpoint and
2777
- * condition when this breakpoint should be triggered.
2186
+ * Returns an array of breakpoints.
2778
2187
  */
2779
- static void
2780
- Init_breakpoint()
2781
- {
2782
- cBreakpoint = rb_define_class_under(mDebugger, "Breakpoint", rb_cObject);
2783
- rb_define_method(cBreakpoint, "id", breakpoint_id, 0);
2784
- rb_define_method(cBreakpoint, "source", breakpoint_source, 0);
2785
- rb_define_method(cBreakpoint, "source=", breakpoint_set_source, 1);
2786
- rb_define_method(cBreakpoint, "enabled?", breakpoint_enabled, 0);
2787
- rb_define_method(cBreakpoint, "enabled=", breakpoint_set_enabled, 1);
2788
- rb_define_method(cBreakpoint, "pos", breakpoint_pos, 0);
2789
- rb_define_method(cBreakpoint, "pos=", breakpoint_set_pos, 1);
2790
- rb_define_method(cBreakpoint, "expr", breakpoint_expr, 0);
2791
- rb_define_method(cBreakpoint, "expr=", breakpoint_set_expr, 1);
2792
- rb_define_method(cBreakpoint, "hit_count", breakpoint_hit_count, 0);
2793
- rb_define_method(cBreakpoint, "hit_value", breakpoint_hit_value, 0);
2794
- rb_define_method(cBreakpoint, "hit_value=", breakpoint_set_hit_value, 1);
2795
- rb_define_method(cBreakpoint, "hit_condition", breakpoint_hit_condition, 0);
2796
- rb_define_method(cBreakpoint, "hit_condition=", breakpoint_set_hit_condition, 1);
2188
+ static VALUE
2189
+ debug_breakpoints(VALUE self)
2190
+ {
2191
+ debug_check_started();
2192
+
2193
+ return rdebug_breakpoints;
2797
2194
  }
2798
2195
 
2196
+ /*
2197
+ * call-seq:
2198
+ * Debugger.add_breakpoint(source, pos, condition = nil) -> breakpoint
2199
+ *
2200
+ * Adds a new breakpoint.
2201
+ * <i>source</i> is a name of a file or a class.
2202
+ * <i>pos</i> is a line number or a method name if <i>source</i> is a class name.
2203
+ * <i>condition</i> is a string which is evaluated to +true+ when this breakpoint
2204
+ * is activated.
2205
+ */
2206
+ static VALUE
2207
+ debug_add_breakpoint(int argc, VALUE *argv, VALUE self)
2208
+ {
2209
+ VALUE result;
2210
+
2211
+ debug_check_started();
2212
+
2213
+ result = create_breakpoint_from_args(argc, argv, ++bkp_count);
2214
+ rb_ary_push(rdebug_breakpoints, result);
2215
+ return result;
2216
+ }
2799
2217
 
2800
2218
  /*
2801
2219
  * Document-class: Debugger
@@ -2813,15 +2231,18 @@ Init_ruby_debug()
2813
2231
  {
2814
2232
  mDebugger = rb_define_module("Debugger");
2815
2233
  rb_define_const(mDebugger, "VERSION", rb_str_new2(DEBUG_VERSION));
2816
- rb_define_module_function(mDebugger, "start", debug_start, 0);
2234
+ rb_define_module_function(mDebugger, "start_", debug_start, 0);
2817
2235
  rb_define_module_function(mDebugger, "stop", debug_stop, 0);
2818
2236
  rb_define_module_function(mDebugger, "started?", debug_is_started, 0);
2819
2237
  rb_define_module_function(mDebugger, "breakpoints", debug_breakpoints, 0);
2820
2238
  rb_define_module_function(mDebugger, "add_breakpoint", debug_add_breakpoint, -1);
2821
2239
  rb_define_module_function(mDebugger, "remove_breakpoint",
2822
- debug_remove_breakpoint, 1);
2823
- rb_define_module_function(mDebugger, "catchpoint", debug_catchpoint, 0);
2824
- rb_define_module_function(mDebugger, "catchpoint=", debug_set_catchpoint, 1);
2240
+ rdebug_remove_breakpoint,
2241
+ 1); /* in breakpoint.c */
2242
+ rb_define_module_function(mDebugger, "add_catchpoint",
2243
+ rdebug_add_catchpoint, 1); /* in breakpoint.c */
2244
+ rb_define_module_function(mDebugger, "catchpoints",
2245
+ debug_catchpoints, 0); /* in breakpoint.c */
2825
2246
  rb_define_module_function(mDebugger, "last_context", debug_last_interrupted, 0);
2826
2247
  rb_define_module_function(mDebugger, "contexts", debug_contexts, 0);
2827
2248
  rb_define_module_function(mDebugger, "current_context", debug_current_context, 0);
@@ -2835,8 +2256,10 @@ Init_ruby_debug()
2835
2256
  rb_define_module_function(mDebugger, "debug_at_exit", debug_at_exit, 0);
2836
2257
  rb_define_module_function(mDebugger, "post_mortem?", debug_post_mortem, 0);
2837
2258
  rb_define_module_function(mDebugger, "post_mortem=", debug_set_post_mortem, 1);
2838
- rb_define_module_function(mDebugger, "keep_frame_binding?", debug_keep_frame_binding, 0);
2839
- rb_define_module_function(mDebugger, "keep_frame_binding=", debug_set_keep_frame_binding, 1);
2259
+ rb_define_module_function(mDebugger, "keep_frame_binding?",
2260
+ debug_keep_frame_binding, 0);
2261
+ rb_define_module_function(mDebugger, "keep_frame_binding=",
2262
+ debug_set_keep_frame_binding, 1);
2840
2263
  rb_define_module_function(mDebugger, "track_frame_args?",
2841
2264
  debug_track_frame_args, 0);
2842
2265
  rb_define_module_function(mDebugger, "track_frame_args=",
@@ -2847,24 +2270,25 @@ Init_ruby_debug()
2847
2270
  cThreadsTable = rb_define_class_under(mDebugger, "ThreadsTable", rb_cObject);
2848
2271
 
2849
2272
  cDebugThread = rb_define_class_under(mDebugger, "DebugThread", rb_cThread);
2850
- rb_define_singleton_method(cDebugThread, "inherited", debug_thread_inherited, 1);
2273
+ rb_define_singleton_method(cDebugThread, "inherited",
2274
+ debug_thread_inherited, 1);
2851
2275
 
2852
2276
  Init_context();
2853
2277
  Init_breakpoint();
2854
2278
 
2855
- idAtLine = rb_intern("at_line");
2856
2279
  idAtBreakpoint = rb_intern("at_breakpoint");
2857
2280
  idAtCatchpoint = rb_intern("at_catchpoint");
2281
+ idAtLine = rb_intern("at_line");
2282
+ idAtReturn = rb_intern("at_return");
2858
2283
  idAtTracing = rb_intern("at_tracing");
2859
- idEval = rb_intern("eval");
2860
2284
  idList = rb_intern("list");
2861
2285
 
2862
2286
  rb_mObjectSpace = rb_const_get(rb_mKernel, rb_intern("ObjectSpace"));
2863
2287
 
2864
- rb_global_variable(&threads_tbl);
2865
- rb_global_variable(&breakpoints);
2866
- rb_global_variable(&catchpoint);
2867
- rb_global_variable(&locker);
2868
2288
  rb_global_variable(&last_context);
2869
2289
  rb_global_variable(&last_thread);
2290
+ rb_global_variable(&locker);
2291
+ rb_global_variable(&rdebug_breakpoints);
2292
+ rb_global_variable(&rdebug_catchpoints);
2293
+ rb_global_variable(&rdebug_threads_tbl);
2870
2294
  }