byebug 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +8 -0
  3. data/AUTHORS +10 -0
  4. data/CHANGELOG.md +2 -0
  5. data/CONTRIBUTING.md +1 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +5 -0
  9. data/Rakefile +28 -0
  10. data/bin/byebug +395 -0
  11. data/byebug.gemspec +29 -0
  12. data/doc/hanoi.rb +35 -0
  13. data/doc/primes.rb +28 -0
  14. data/doc/rdebug-emacs.texi +1030 -0
  15. data/doc/test-tri2.rb +18 -0
  16. data/doc/tri3.rb +8 -0
  17. data/doc/triangle.rb +12 -0
  18. data/ext/byebug/breakpoint.c +476 -0
  19. data/ext/byebug/byebug.c +512 -0
  20. data/ext/byebug/byebug.h +131 -0
  21. data/ext/byebug/context.c +424 -0
  22. data/ext/byebug/extconf.rb +21 -0
  23. data/ext/byebug/locker.c +53 -0
  24. data/lib/byebug.rb +404 -0
  25. data/lib/byebug/command.rb +232 -0
  26. data/lib/byebug/commands/breakpoints.rb +153 -0
  27. data/lib/byebug/commands/catchpoint.rb +56 -0
  28. data/lib/byebug/commands/condition.rb +49 -0
  29. data/lib/byebug/commands/continue.rb +38 -0
  30. data/lib/byebug/commands/control.rb +110 -0
  31. data/lib/byebug/commands/display.rb +122 -0
  32. data/lib/byebug/commands/edit.rb +48 -0
  33. data/lib/byebug/commands/enable.rb +202 -0
  34. data/lib/byebug/commands/eval.rb +176 -0
  35. data/lib/byebug/commands/finish.rb +43 -0
  36. data/lib/byebug/commands/frame.rb +303 -0
  37. data/lib/byebug/commands/help.rb +56 -0
  38. data/lib/byebug/commands/info.rb +462 -0
  39. data/lib/byebug/commands/irb.rb +123 -0
  40. data/lib/byebug/commands/jump.rb +66 -0
  41. data/lib/byebug/commands/kill.rb +51 -0
  42. data/lib/byebug/commands/list.rb +94 -0
  43. data/lib/byebug/commands/method.rb +84 -0
  44. data/lib/byebug/commands/quit.rb +39 -0
  45. data/lib/byebug/commands/reload.rb +40 -0
  46. data/lib/byebug/commands/save.rb +90 -0
  47. data/lib/byebug/commands/set.rb +210 -0
  48. data/lib/byebug/commands/show.rb +246 -0
  49. data/lib/byebug/commands/skip.rb +35 -0
  50. data/lib/byebug/commands/source.rb +36 -0
  51. data/lib/byebug/commands/stepping.rb +83 -0
  52. data/lib/byebug/commands/threads.rb +189 -0
  53. data/lib/byebug/commands/tmate.rb +36 -0
  54. data/lib/byebug/commands/trace.rb +56 -0
  55. data/lib/byebug/commands/variables.rb +199 -0
  56. data/lib/byebug/context.rb +58 -0
  57. data/lib/byebug/helper.rb +69 -0
  58. data/lib/byebug/interface.rb +223 -0
  59. data/lib/byebug/processor.rb +468 -0
  60. data/lib/byebug/version.rb +3 -0
  61. data/man/rdebug.1 +241 -0
  62. data/test/breakpoints_test.rb +357 -0
  63. data/test/conditions_test.rb +77 -0
  64. data/test/continue_test.rb +44 -0
  65. data/test/display_test.rb +141 -0
  66. data/test/edit_test.rb +56 -0
  67. data/test/eval_test.rb +92 -0
  68. data/test/examples/breakpoint1.rb +15 -0
  69. data/test/examples/breakpoint2.rb +7 -0
  70. data/test/examples/conditions.rb +4 -0
  71. data/test/examples/continue.rb +4 -0
  72. data/test/examples/display.rb +5 -0
  73. data/test/examples/edit.rb +3 -0
  74. data/test/examples/edit2.rb +3 -0
  75. data/test/examples/eval.rb +4 -0
  76. data/test/examples/finish.rb +20 -0
  77. data/test/examples/frame.rb +20 -0
  78. data/test/examples/frame_threads.rb +31 -0
  79. data/test/examples/help.rb +2 -0
  80. data/test/examples/info.rb +38 -0
  81. data/test/examples/info2.rb +3 -0
  82. data/test/examples/info_threads.rb +48 -0
  83. data/test/examples/irb.rb +6 -0
  84. data/test/examples/jump.rb +14 -0
  85. data/test/examples/kill.rb +2 -0
  86. data/test/examples/list.rb +12 -0
  87. data/test/examples/method.rb +15 -0
  88. data/test/examples/post_mortem.rb +19 -0
  89. data/test/examples/quit.rb +2 -0
  90. data/test/examples/reload.rb +6 -0
  91. data/test/examples/restart.rb +6 -0
  92. data/test/examples/save.rb +3 -0
  93. data/test/examples/set.rb +3 -0
  94. data/test/examples/set_annotate.rb +12 -0
  95. data/test/examples/settings.rb +1 -0
  96. data/test/examples/show.rb +2 -0
  97. data/test/examples/source.rb +3 -0
  98. data/test/examples/stepping.rb +21 -0
  99. data/test/examples/thread.rb +32 -0
  100. data/test/examples/tmate.rb +10 -0
  101. data/test/examples/trace.rb +7 -0
  102. data/test/examples/trace_threads.rb +20 -0
  103. data/test/examples/variables.rb +26 -0
  104. data/test/finish_test.rb +48 -0
  105. data/test/frame_test.rb +143 -0
  106. data/test/help_test.rb +50 -0
  107. data/test/info_test.rb +313 -0
  108. data/test/irb_test.rb +81 -0
  109. data/test/jump_test.rb +70 -0
  110. data/test/kill_test.rb +48 -0
  111. data/test/list_test.rb +145 -0
  112. data/test/method_test.rb +70 -0
  113. data/test/post_mortem_test.rb +27 -0
  114. data/test/quit_test.rb +56 -0
  115. data/test/reload_test.rb +44 -0
  116. data/test/restart_test.rb +164 -0
  117. data/test/save_test.rb +92 -0
  118. data/test/set_test.rb +177 -0
  119. data/test/show_test.rb +293 -0
  120. data/test/source_test.rb +45 -0
  121. data/test/stepping_test.rb +130 -0
  122. data/test/support/breakpoint.rb +13 -0
  123. data/test/support/context.rb +14 -0
  124. data/test/support/matchers.rb +67 -0
  125. data/test/support/mocha_extensions.rb +72 -0
  126. data/test/support/processor.rb +7 -0
  127. data/test/support/test_dsl.rb +206 -0
  128. data/test/support/test_interface.rb +68 -0
  129. data/test/test_helper.rb +10 -0
  130. data/test/tmate_test.rb +44 -0
  131. data/test/trace_test.rb +159 -0
  132. data/test/variables_test.rb +119 -0
  133. metadata +265 -0
@@ -0,0 +1,512 @@
1
+ #include <byebug.h>
2
+
3
+ static VALUE mByebug; /* Ruby Byebug Module object */
4
+ static VALUE cContext;
5
+ static VALUE cDebugThread;
6
+
7
+ static VALUE debug = Qfalse;
8
+ static VALUE locker = Qnil;
9
+ static VALUE contexts;
10
+ static VALUE catchpoints;
11
+ static VALUE breakpoints;
12
+
13
+ static VALUE tpLine;
14
+ static VALUE tpCall;
15
+ static VALUE tpReturn;
16
+ static VALUE tpRaise;
17
+
18
+ static VALUE idAlive;
19
+ static VALUE idAtBreakpoint;
20
+ static VALUE idAtCatchpoint;
21
+ static VALUE idAtLine;
22
+ static VALUE idAtTracing;
23
+
24
+ static void
25
+ print_debug_info(char *event, VALUE path, VALUE lineno, VALUE method_id,
26
+ VALUE defined_class, int stack_size)
27
+ {
28
+ char *file;
29
+ const char *method_name, *class_name;
30
+
31
+ file = strrchr(RSTRING_PTR(path), '/');
32
+ method_name = rb_id2name(SYM2ID(method_id));
33
+ class_name = NIL_P(defined_class) ? "undef" : rb_class2name(defined_class);
34
+ fprintf(stderr, "%s: file=%s, line=%d, class=%s, method=%s, stack=%d\n",
35
+ event, ++file, FIX2INT(lineno), class_name, method_name, stack_size);
36
+ return;
37
+ }
38
+
39
+ static VALUE
40
+ Byebug_thread_context(VALUE self, VALUE thread)
41
+ {
42
+ VALUE context;
43
+
44
+ context = rb_hash_aref(contexts, thread);
45
+ if (context == Qnil) {
46
+ context = context_create(thread, cDebugThread);
47
+ rb_hash_aset(contexts, thread, context);
48
+ }
49
+ return context;
50
+ }
51
+
52
+ static VALUE
53
+ Byebug_current_context(VALUE self)
54
+ {
55
+ return Byebug_thread_context(self, rb_thread_current());
56
+ }
57
+
58
+ static int
59
+ remove_dead_threads(VALUE thread, VALUE context, VALUE ignored)
60
+ {
61
+ return (IS_THREAD_ALIVE(thread)) ? ST_CONTINUE : ST_DELETE;
62
+ }
63
+
64
+ static void
65
+ cleanup(debug_context_t *context)
66
+ {
67
+ VALUE thread;
68
+
69
+ context->stop_reason = CTX_STOP_NONE;
70
+
71
+ /* release a lock */
72
+ locker = Qnil;
73
+
74
+ /* let the next thread run */
75
+ thread = remove_from_locked();
76
+ if(thread != Qnil)
77
+ rb_thread_run(thread);
78
+ }
79
+
80
+ static int
81
+ check_start_processing(debug_context_t *context, VALUE thread)
82
+ {
83
+ /* return if thread is marked as 'ignored'.
84
+ byebug's threads are marked this way
85
+ */
86
+ if(CTX_FL_TEST(context, CTX_FL_IGNORE)) return 0;
87
+
88
+ while(1)
89
+ {
90
+ /* halt execution of the current thread if the byebug
91
+ is activated in another
92
+ */
93
+ while(locker != Qnil && locker != thread)
94
+ {
95
+ add_to_locked(thread);
96
+ rb_thread_stop();
97
+ }
98
+
99
+ /* stop the current thread if it's marked as suspended */
100
+ if(CTX_FL_TEST(context, CTX_FL_SUSPEND) && locker != thread)
101
+ {
102
+ CTX_FL_SET(context, CTX_FL_WAS_RUNNING);
103
+ rb_thread_stop();
104
+ }
105
+ else break;
106
+ }
107
+
108
+ /* return if the current thread is the locker */
109
+ if(locker != Qnil) return 0;
110
+
111
+ /* only the current thread can proceed */
112
+ locker = thread;
113
+
114
+ /* ignore a skipped section of code */
115
+ if(CTX_FL_TEST(context, CTX_FL_SKIPPED)) {
116
+ cleanup(context);
117
+ return 0;
118
+ }
119
+ return 1;
120
+ }
121
+
122
+ static inline void
123
+ load_frame_info(VALUE trace_point, VALUE *path, VALUE *lineno, VALUE *method_id,
124
+ VALUE *defined_class, VALUE *binding,
125
+ VALUE *self)
126
+ {
127
+ rb_trace_point_t *tp;
128
+
129
+ tp = rb_tracearg_from_tracepoint(trace_point);
130
+
131
+ *path = rb_tracearg_path(tp);
132
+ *lineno = rb_tracearg_lineno(tp);
133
+ *binding = rb_tracearg_binding(tp);
134
+ *self = rb_tracearg_self(tp);
135
+ *method_id = rb_tracearg_method_id(tp);
136
+ *defined_class = rb_tracearg_defined_class(tp);
137
+ }
138
+
139
+ static void
140
+ call_at_line(debug_context_t *context, char *file, int line,
141
+ VALUE context_object, VALUE path, VALUE lineno)
142
+ {
143
+ CTX_FL_UNSET(context, CTX_FL_STEPPED);
144
+ CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
145
+ context->last_file = file;
146
+ context->last_line = line;
147
+ rb_funcall(context_object, idAtLine, 2, path, lineno);
148
+ }
149
+
150
+ static void
151
+ process_line_event(VALUE trace_point, void *data)
152
+ {
153
+ VALUE path, lineno, method_id, defined_class, binding, self;
154
+ VALUE context_object;
155
+ VALUE breakpoint;
156
+ debug_context_t *context;
157
+ int moved;
158
+
159
+ context_object = Byebug_current_context(mByebug);
160
+ Data_Get_Struct(context_object, debug_context_t, context);
161
+ if (!check_start_processing(context, rb_thread_current())) return;
162
+
163
+ load_frame_info(trace_point, &path, &lineno, &method_id, &defined_class,
164
+ &binding, &self);
165
+ if (debug == Qtrue)
166
+ print_debug_info("line", path, lineno, method_id, defined_class,
167
+ context->stack_size);
168
+
169
+ update_frame(context_object, RSTRING_PTR(path), FIX2INT(lineno), method_id,
170
+ defined_class, binding, self);
171
+
172
+ moved = context->last_line != FIX2INT(lineno) || context->last_file == NULL ||
173
+ strcmp(context->last_file, RSTRING_PTR(path)) != 0;
174
+
175
+ if (CTX_FL_TEST(context, CTX_FL_TRACING))
176
+ rb_funcall(context_object, idAtTracing, 2, path, lineno);
177
+
178
+ if (context->dest_frame == -1 || context->stack_size == context->dest_frame)
179
+ {
180
+ if (moved || !CTX_FL_TEST(context, CTX_FL_FORCE_MOVE))
181
+ context->stop_next--;
182
+ if (context->stop_next < 0)
183
+ context->stop_next = -1;
184
+ if (moved || (CTX_FL_TEST(context, CTX_FL_STEPPED) && !CTX_FL_TEST(context, CTX_FL_FORCE_MOVE)))
185
+ {
186
+ context->stop_line--;
187
+ CTX_FL_UNSET(context, CTX_FL_STEPPED);
188
+ }
189
+ }
190
+ else if (context->stack_size < context->dest_frame)
191
+ {
192
+ context->stop_next = 0;
193
+ }
194
+
195
+ breakpoint = find_breakpoint_by_pos(breakpoints, path, lineno, binding);
196
+ if (context->stop_next == 0 || context->stop_line == 0 ||
197
+ breakpoint != Qnil)
198
+ {
199
+ context->stop_reason = CTX_STOP_STEP;
200
+ if (breakpoint != Qnil) {
201
+ rb_funcall(context_object, idAtBreakpoint, 1, breakpoint);
202
+ }
203
+ reset_stepping_stop_points(context);
204
+ call_at_line(context, RSTRING_PTR(path), FIX2INT(lineno), context_object,
205
+ path, lineno);
206
+ }
207
+ cleanup(context);
208
+ }
209
+
210
+ static void
211
+ process_return_event(VALUE trace_point, void *data)
212
+ {
213
+ VALUE path, lineno, method_id, defined_class, binding, self;
214
+ VALUE context_object;
215
+ debug_context_t *context;
216
+
217
+ context_object = Byebug_current_context(mByebug);
218
+ Data_Get_Struct(context_object, debug_context_t, context);
219
+ if (!check_start_processing(context, rb_thread_current())) return;
220
+
221
+ if(context->stack_size == context->stop_frame)
222
+ {
223
+ context->stop_next = 1;
224
+ context->stop_frame = 0;
225
+ }
226
+
227
+ load_frame_info(trace_point, &path, &lineno, &method_id, &defined_class,
228
+ &binding, &self);
229
+ if (debug == Qtrue)
230
+ print_debug_info("return", path, lineno, method_id, defined_class,
231
+ context->stack_size);
232
+
233
+ // rb_funcall(context_object, idAtReturn, 2, path, lineno);
234
+
235
+ pop_frame(context_object);
236
+ cleanup(context);
237
+ }
238
+
239
+ static void
240
+ process_call_event(VALUE trace_point, void *data)
241
+ {
242
+ VALUE path, lineno, method_id, defined_class, binding, self;
243
+ VALUE context_object;
244
+ VALUE breakpoint;
245
+ debug_context_t *context;
246
+
247
+ context_object = Byebug_current_context(mByebug);
248
+ Data_Get_Struct(context_object, debug_context_t, context);
249
+ if (!check_start_processing(context, rb_thread_current())) return;
250
+
251
+ load_frame_info(trace_point, &path, &lineno, &method_id, &defined_class,
252
+ &binding, &self);
253
+ if (debug == Qtrue)
254
+ print_debug_info("call", path, lineno, method_id, defined_class,
255
+ context->stack_size);
256
+
257
+ push_frame(context_object, RSTRING_PTR(path), FIX2INT(lineno), method_id,
258
+ defined_class, binding, self);
259
+
260
+ breakpoint = find_breakpoint_by_method(breakpoints, defined_class,
261
+ SYM2ID(method_id),
262
+ binding, self);
263
+ if (breakpoint != Qnil) {
264
+ context->stop_reason = CTX_STOP_BREAKPOINT;
265
+ rb_funcall(context_object, idAtBreakpoint, 1, breakpoint);
266
+ call_at_line(context, RSTRING_PTR(path), FIX2INT(lineno), context_object,
267
+ path, lineno);
268
+ }
269
+
270
+ cleanup(context);
271
+ }
272
+
273
+ static void
274
+ process_raise_event(VALUE trace_point, void *data)
275
+ {
276
+ VALUE path, lineno, method_id, defined_class, binding, self;
277
+ VALUE context_object;
278
+ VALUE hit_count;
279
+ VALUE exception_name;
280
+ debug_context_t *context;
281
+ int c_hit_count;
282
+
283
+ context_object = Byebug_current_context(mByebug);
284
+ Data_Get_Struct(context_object, debug_context_t, context);
285
+ if (!check_start_processing(context, rb_thread_current())) return;
286
+
287
+ load_frame_info(trace_point, &path, &lineno, &method_id, &defined_class,
288
+ &binding, &self);
289
+ update_frame(context_object, RSTRING_PTR(path), FIX2INT(lineno), method_id,
290
+ defined_class, binding, self);
291
+
292
+ if (catchpoint_hit_count(catchpoints, rb_errinfo(), &exception_name) != Qnil) {
293
+ /* On 64-bit systems with gcc and -O2 there seems to be
294
+ an optimization bug in running INT2FIX(FIX2INT...)..)
295
+ So we do this in two steps.
296
+ */
297
+ c_hit_count = FIX2INT(rb_hash_aref(catchpoints, exception_name)) + 1;
298
+ hit_count = INT2FIX(c_hit_count);
299
+ rb_hash_aset(catchpoints, exception_name, hit_count);
300
+ context->stop_reason = CTX_STOP_CATCHPOINT;
301
+ rb_funcall(context_object, idAtCatchpoint, 1, rb_errinfo());
302
+ call_at_line(context, RSTRING_PTR(path), FIX2INT(lineno), context_object,
303
+ path, lineno);
304
+ }
305
+
306
+ cleanup(context);
307
+ }
308
+
309
+
310
+ static VALUE
311
+ Byebug_setup_tracepoints(VALUE self)
312
+ {
313
+ if (catchpoints != Qnil) return Qnil;
314
+ contexts = rb_hash_new();
315
+ breakpoints = rb_ary_new();
316
+ catchpoints = rb_hash_new();
317
+
318
+ tpLine = rb_tracepoint_new(Qnil,
319
+ RUBY_EVENT_LINE,
320
+ process_line_event, NULL);
321
+ rb_tracepoint_enable(tpLine);
322
+
323
+ tpReturn = rb_tracepoint_new(Qnil,
324
+ RUBY_EVENT_RETURN | RUBY_EVENT_C_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_CLASS | RUBY_EVENT_END,
325
+ process_return_event, NULL);
326
+ rb_tracepoint_enable(tpReturn);
327
+
328
+ tpCall = rb_tracepoint_new(Qnil,
329
+ RUBY_EVENT_CALL | RUBY_EVENT_C_CALL | RUBY_EVENT_B_CALL,
330
+ process_call_event, NULL);
331
+ rb_tracepoint_enable(tpCall);
332
+
333
+ tpRaise = rb_tracepoint_new(Qnil,
334
+ RUBY_EVENT_RAISE, process_raise_event, NULL);
335
+ rb_tracepoint_enable(tpRaise);
336
+
337
+ return Qnil;
338
+ }
339
+
340
+ static VALUE
341
+ Byebug_remove_tracepoints(VALUE self)
342
+ {
343
+ contexts = Qnil;
344
+ breakpoints = Qnil;
345
+ catchpoints = Qnil;
346
+
347
+ if (tpLine != Qnil) rb_tracepoint_disable(tpLine);
348
+ tpLine = Qnil;
349
+ if (tpReturn != Qnil) rb_tracepoint_disable(tpReturn);
350
+ tpReturn = Qnil;
351
+ if (tpCall != Qnil) rb_tracepoint_disable(tpCall);
352
+ tpCall = Qnil;
353
+ if (tpRaise != Qnil) rb_tracepoint_disable(tpRaise);
354
+ tpRaise = Qnil;
355
+ return Qnil;
356
+ }
357
+
358
+ static int
359
+ values_i(VALUE key, VALUE value, VALUE ary)
360
+ {
361
+ rb_ary_push(ary, value);
362
+ return ST_CONTINUE;
363
+ }
364
+
365
+ static VALUE
366
+ Byebug_started(VALUE self)
367
+ {
368
+ return catchpoints != Qnil ? Qtrue : Qfalse;
369
+ }
370
+
371
+ static VALUE
372
+ Byebug_stop(VALUE self)
373
+ {
374
+ if (Byebug_started(self))
375
+ {
376
+ Byebug_remove_tracepoints(self);
377
+ return Qfalse;
378
+ }
379
+ return Qtrue;
380
+ }
381
+
382
+ static VALUE
383
+ Byebug_start(VALUE self)
384
+ {
385
+ VALUE result;
386
+
387
+ if (Byebug_started(self))
388
+ result = Qfalse;
389
+ else
390
+ {
391
+ Byebug_setup_tracepoints(self);
392
+ result = Qtrue;
393
+ }
394
+
395
+ if (rb_block_given_p())
396
+ rb_ensure(rb_yield, self, Byebug_stop, self);
397
+
398
+ return result;
399
+ }
400
+
401
+ static VALUE
402
+ Byebug_load(int argc, VALUE *argv, VALUE self)
403
+ {
404
+ VALUE file, stop, context_object;
405
+ debug_context_t *context;
406
+ int state = 0;
407
+
408
+ if (rb_scan_args(argc, argv, "11", &file, &stop) == 1)
409
+ {
410
+ stop = Qfalse;
411
+ }
412
+
413
+ Byebug_start(self);
414
+
415
+ context_object = Byebug_current_context(self);
416
+ Data_Get_Struct(context_object, debug_context_t, context);
417
+ context->stack_size = 0;
418
+ if (RTEST(stop)) context->stop_next = 1;
419
+
420
+ /* Initializing $0 to the script's path */
421
+ ruby_script(RSTRING_PTR(file));
422
+ rb_load_protect(file, 0, &state);
423
+ if (0 != state)
424
+ {
425
+ VALUE errinfo = rb_errinfo();
426
+ //debug_suspend(self);
427
+ reset_stepping_stop_points(context);
428
+ rb_set_errinfo(Qnil);
429
+ return errinfo;
430
+ }
431
+
432
+ /* We should run all at_exit handler's in order to provide,
433
+ * for instance, a chance to run all defined test cases */
434
+ rb_exec_end_proc();
435
+
436
+ return Qnil;
437
+ }
438
+
439
+
440
+
441
+ static VALUE
442
+ Byebug_contexts(VALUE self)
443
+ {
444
+ VALUE ary;
445
+
446
+ ary = rb_ary_new();
447
+
448
+ /* check that all contexts point to alive threads */
449
+ rb_hash_foreach(contexts, remove_dead_threads, 0);
450
+
451
+ rb_hash_foreach(contexts, values_i, ary);
452
+
453
+ return ary;
454
+ }
455
+
456
+ static VALUE
457
+ Byebug_breakpoints(VALUE self)
458
+ {
459
+ return breakpoints;
460
+ }
461
+
462
+ static VALUE
463
+ Byebug_catchpoints(VALUE self)
464
+ {
465
+ if (catchpoints == Qnil)
466
+ rb_raise(rb_eRuntimeError, "Byebug.start is not called yet.");
467
+ return catchpoints;
468
+ }
469
+
470
+ /*
471
+ * Document-class: Byebug
472
+ *
473
+ * == Summary
474
+ *
475
+ * This is a singleton class allows controlling the byebug. Use it to start/stop
476
+ * byebug, set/remove breakpoints, etc.
477
+ */
478
+ void
479
+ Init_byebug()
480
+ {
481
+ mByebug = rb_define_module("Byebug");
482
+ rb_define_module_function(mByebug, "setup_tracepoints", Byebug_setup_tracepoints, 0);
483
+ rb_define_module_function(mByebug, "remove_tracepoints", Byebug_remove_tracepoints, 0);
484
+ rb_define_module_function(mByebug, "current_context", Byebug_current_context, 0);
485
+ rb_define_module_function(mByebug, "contexts", Byebug_contexts, 0);
486
+ rb_define_module_function(mByebug, "breakpoints", Byebug_breakpoints, 0);
487
+ rb_define_module_function(mByebug, "catchpoints", Byebug_catchpoints, 0);
488
+ rb_define_module_function(mByebug, "_start", Byebug_start, 0);
489
+ rb_define_module_function(mByebug, "stop", Byebug_stop, 0);
490
+ rb_define_module_function(mByebug, "started?", Byebug_started, 0);
491
+ rb_define_module_function(mByebug, "debug_load", Byebug_load, -1);
492
+
493
+ idAlive = rb_intern("alive?");
494
+ idAtBreakpoint = rb_intern("at_breakpoint");
495
+ idAtCatchpoint = rb_intern("at_catchpoint");
496
+ idAtTracing = rb_intern("at_tracing");
497
+ idAtLine = rb_intern("at_line");
498
+
499
+ cContext = Init_context(mByebug);
500
+
501
+ Init_breakpoint(mByebug);
502
+
503
+ cDebugThread = rb_define_class_under(mByebug, "DebugThread", rb_cThread);
504
+ contexts = Qnil;
505
+ catchpoints = Qnil;
506
+ breakpoints = Qnil;
507
+
508
+ rb_global_variable(&locker);
509
+ rb_global_variable(&breakpoints);
510
+ rb_global_variable(&catchpoints);
511
+ rb_global_variable(&contexts);
512
+ }