micro-lite-gem 0.0.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.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/byebug-13.0.0/CHANGELOG.md +980 -0
  3. data/byebug-13.0.0/CONTRIBUTING.md +58 -0
  4. data/byebug-13.0.0/GUIDE.md +1806 -0
  5. data/byebug-13.0.0/LICENSE +23 -0
  6. data/byebug-13.0.0/README.md +197 -0
  7. data/byebug-13.0.0/exe/byebug +6 -0
  8. data/byebug-13.0.0/ext/byebug/breakpoint.c +522 -0
  9. data/byebug-13.0.0/ext/byebug/byebug.c +906 -0
  10. data/byebug-13.0.0/ext/byebug/byebug.h +147 -0
  11. data/byebug-13.0.0/ext/byebug/context.c +682 -0
  12. data/byebug-13.0.0/ext/byebug/extconf.rb +12 -0
  13. data/byebug-13.0.0/ext/byebug/locker.c +96 -0
  14. data/byebug-13.0.0/ext/byebug/threads.c +254 -0
  15. data/byebug-13.0.0/lib/byebug/attacher.rb +48 -0
  16. data/byebug-13.0.0/lib/byebug/breakpoint.rb +94 -0
  17. data/byebug-13.0.0/lib/byebug/command.rb +111 -0
  18. data/byebug-13.0.0/lib/byebug/command_list.rb +34 -0
  19. data/byebug-13.0.0/lib/byebug/commands/break.rb +114 -0
  20. data/byebug-13.0.0/lib/byebug/commands/catch.rb +78 -0
  21. data/byebug-13.0.0/lib/byebug/commands/condition.rb +55 -0
  22. data/byebug-13.0.0/lib/byebug/commands/continue.rb +68 -0
  23. data/byebug-13.0.0/lib/byebug/commands/debug.rb +38 -0
  24. data/byebug-13.0.0/lib/byebug/commands/delete.rb +55 -0
  25. data/byebug-13.0.0/lib/byebug/commands/disable/breakpoints.rb +42 -0
  26. data/byebug-13.0.0/lib/byebug/commands/disable/display.rb +43 -0
  27. data/byebug-13.0.0/lib/byebug/commands/disable.rb +33 -0
  28. data/byebug-13.0.0/lib/byebug/commands/display.rb +66 -0
  29. data/byebug-13.0.0/lib/byebug/commands/down.rb +45 -0
  30. data/byebug-13.0.0/lib/byebug/commands/edit.rb +69 -0
  31. data/byebug-13.0.0/lib/byebug/commands/enable/breakpoints.rb +42 -0
  32. data/byebug-13.0.0/lib/byebug/commands/enable/display.rb +43 -0
  33. data/byebug-13.0.0/lib/byebug/commands/enable.rb +33 -0
  34. data/byebug-13.0.0/lib/byebug/commands/finish.rb +57 -0
  35. data/byebug-13.0.0/lib/byebug/commands/frame.rb +57 -0
  36. data/byebug-13.0.0/lib/byebug/commands/help.rb +64 -0
  37. data/byebug-13.0.0/lib/byebug/commands/history.rb +39 -0
  38. data/byebug-13.0.0/lib/byebug/commands/info/breakpoints.rb +65 -0
  39. data/byebug-13.0.0/lib/byebug/commands/info/display.rb +49 -0
  40. data/byebug-13.0.0/lib/byebug/commands/info/file.rb +80 -0
  41. data/byebug-13.0.0/lib/byebug/commands/info/line.rb +35 -0
  42. data/byebug-13.0.0/lib/byebug/commands/info/program.rb +49 -0
  43. data/byebug-13.0.0/lib/byebug/commands/info.rb +37 -0
  44. data/byebug-13.0.0/lib/byebug/commands/interrupt.rb +34 -0
  45. data/byebug-13.0.0/lib/byebug/commands/irb.rb +51 -0
  46. data/byebug-13.0.0/lib/byebug/commands/kill.rb +45 -0
  47. data/byebug-13.0.0/lib/byebug/commands/list.rb +159 -0
  48. data/byebug-13.0.0/lib/byebug/commands/method.rb +53 -0
  49. data/byebug-13.0.0/lib/byebug/commands/next.rb +40 -0
  50. data/byebug-13.0.0/lib/byebug/commands/pry.rb +41 -0
  51. data/byebug-13.0.0/lib/byebug/commands/quit.rb +42 -0
  52. data/byebug-13.0.0/lib/byebug/commands/restart.rb +64 -0
  53. data/byebug-13.0.0/lib/byebug/commands/save.rb +72 -0
  54. data/byebug-13.0.0/lib/byebug/commands/set.rb +79 -0
  55. data/byebug-13.0.0/lib/byebug/commands/show.rb +45 -0
  56. data/byebug-13.0.0/lib/byebug/commands/skip.rb +85 -0
  57. data/byebug-13.0.0/lib/byebug/commands/source.rb +40 -0
  58. data/byebug-13.0.0/lib/byebug/commands/step.rb +40 -0
  59. data/byebug-13.0.0/lib/byebug/commands/thread/current.rb +37 -0
  60. data/byebug-13.0.0/lib/byebug/commands/thread/list.rb +43 -0
  61. data/byebug-13.0.0/lib/byebug/commands/thread/resume.rb +45 -0
  62. data/byebug-13.0.0/lib/byebug/commands/thread/stop.rb +43 -0
  63. data/byebug-13.0.0/lib/byebug/commands/thread/switch.rb +46 -0
  64. data/byebug-13.0.0/lib/byebug/commands/thread.rb +34 -0
  65. data/byebug-13.0.0/lib/byebug/commands/tracevar.rb +54 -0
  66. data/byebug-13.0.0/lib/byebug/commands/undisplay.rb +51 -0
  67. data/byebug-13.0.0/lib/byebug/commands/untracevar.rb +36 -0
  68. data/byebug-13.0.0/lib/byebug/commands/up.rb +45 -0
  69. data/byebug-13.0.0/lib/byebug/commands/var/all.rb +41 -0
  70. data/byebug-13.0.0/lib/byebug/commands/var/args.rb +39 -0
  71. data/byebug-13.0.0/lib/byebug/commands/var/const.rb +49 -0
  72. data/byebug-13.0.0/lib/byebug/commands/var/global.rb +37 -0
  73. data/byebug-13.0.0/lib/byebug/commands/var/instance.rb +39 -0
  74. data/byebug-13.0.0/lib/byebug/commands/var/local.rb +39 -0
  75. data/byebug-13.0.0/lib/byebug/commands/var.rb +37 -0
  76. data/byebug-13.0.0/lib/byebug/commands/where.rb +64 -0
  77. data/byebug-13.0.0/lib/byebug/commands.rb +40 -0
  78. data/byebug-13.0.0/lib/byebug/context.rb +157 -0
  79. data/byebug-13.0.0/lib/byebug/core.rb +115 -0
  80. data/byebug-13.0.0/lib/byebug/errors.rb +29 -0
  81. data/byebug-13.0.0/lib/byebug/frame.rb +185 -0
  82. data/byebug-13.0.0/lib/byebug/helpers/bin.rb +47 -0
  83. data/byebug-13.0.0/lib/byebug/helpers/eval.rb +124 -0
  84. data/byebug-13.0.0/lib/byebug/helpers/file.rb +67 -0
  85. data/byebug-13.0.0/lib/byebug/helpers/frame.rb +75 -0
  86. data/byebug-13.0.0/lib/byebug/helpers/parse.rb +82 -0
  87. data/byebug-13.0.0/lib/byebug/helpers/path.rb +40 -0
  88. data/byebug-13.0.0/lib/byebug/helpers/reflection.rb +19 -0
  89. data/byebug-13.0.0/lib/byebug/helpers/string.rb +33 -0
  90. data/byebug-13.0.0/lib/byebug/helpers/thread.rb +67 -0
  91. data/byebug-13.0.0/lib/byebug/helpers/toggle.rb +62 -0
  92. data/byebug-13.0.0/lib/byebug/helpers/var.rb +70 -0
  93. data/byebug-13.0.0/lib/byebug/history.rb +120 -0
  94. data/byebug-13.0.0/lib/byebug/interface.rb +146 -0
  95. data/byebug-13.0.0/lib/byebug/interfaces/local_interface.rb +63 -0
  96. data/byebug-13.0.0/lib/byebug/interfaces/remote_interface.rb +50 -0
  97. data/byebug-13.0.0/lib/byebug/interfaces/script_interface.rb +33 -0
  98. data/byebug-13.0.0/lib/byebug/interfaces/test_interface.rb +67 -0
  99. data/byebug-13.0.0/lib/byebug/option_setter.rb +95 -0
  100. data/byebug-13.0.0/lib/byebug/printers/base.rb +68 -0
  101. data/byebug-13.0.0/lib/byebug/printers/plain.rb +44 -0
  102. data/byebug-13.0.0/lib/byebug/printers/texts/base.yml +115 -0
  103. data/byebug-13.0.0/lib/byebug/printers/texts/plain.yml +33 -0
  104. data/byebug-13.0.0/lib/byebug/processors/command_processor.rb +173 -0
  105. data/byebug-13.0.0/lib/byebug/processors/control_processor.rb +24 -0
  106. data/byebug-13.0.0/lib/byebug/processors/post_mortem_processor.rb +18 -0
  107. data/byebug-13.0.0/lib/byebug/processors/script_processor.rb +49 -0
  108. data/byebug-13.0.0/lib/byebug/remote/client.rb +57 -0
  109. data/byebug-13.0.0/lib/byebug/remote/server.rb +47 -0
  110. data/byebug-13.0.0/lib/byebug/remote.rb +85 -0
  111. data/byebug-13.0.0/lib/byebug/runner.rb +198 -0
  112. data/byebug-13.0.0/lib/byebug/setting.rb +79 -0
  113. data/byebug-13.0.0/lib/byebug/settings/autoirb.rb +29 -0
  114. data/byebug-13.0.0/lib/byebug/settings/autolist.rb +29 -0
  115. data/byebug-13.0.0/lib/byebug/settings/autopry.rb +29 -0
  116. data/byebug-13.0.0/lib/byebug/settings/autosave.rb +17 -0
  117. data/byebug-13.0.0/lib/byebug/settings/basename.rb +16 -0
  118. data/byebug-13.0.0/lib/byebug/settings/callstyle.rb +20 -0
  119. data/byebug-13.0.0/lib/byebug/settings/fullpath.rb +16 -0
  120. data/byebug-13.0.0/lib/byebug/settings/histfile.rb +20 -0
  121. data/byebug-13.0.0/lib/byebug/settings/histsize.rb +20 -0
  122. data/byebug-13.0.0/lib/byebug/settings/linetrace.rb +22 -0
  123. data/byebug-13.0.0/lib/byebug/settings/listsize.rb +21 -0
  124. data/byebug-13.0.0/lib/byebug/settings/post_mortem.rb +27 -0
  125. data/byebug-13.0.0/lib/byebug/settings/savefile.rb +20 -0
  126. data/byebug-13.0.0/lib/byebug/settings/stack_on_error.rb +15 -0
  127. data/byebug-13.0.0/lib/byebug/settings/width.rb +20 -0
  128. data/byebug-13.0.0/lib/byebug/source_file_formatter.rb +71 -0
  129. data/byebug-13.0.0/lib/byebug/subcommands.rb +54 -0
  130. data/byebug-13.0.0/lib/byebug/version.rb +8 -0
  131. data/byebug-13.0.0/lib/byebug.rb +3 -0
  132. data/micro-lite-gem.gemspec +12 -0
  133. metadata +172 -0
@@ -0,0 +1,906 @@
1
+ #include "byebug.h"
2
+
3
+ static VALUE mByebug; /* Ruby Byebug Module object */
4
+
5
+ static VALUE tracing = Qfalse;
6
+ static VALUE post_mortem = Qfalse;
7
+ static VALUE verbose = Qfalse;
8
+
9
+ static VALUE catchpoints = Qnil;
10
+ static VALUE breakpoints = Qnil;
11
+ static VALUE tracepoints = Qnil;
12
+
13
+ static VALUE raised_exception = Qnil;
14
+
15
+ static ID idPuts;
16
+ static ID idEmpty;
17
+
18
+ /* Hash table with active threads and their associated contexts */
19
+ VALUE threads = Qnil;
20
+
21
+ /*
22
+ * call-seq:
23
+ * Byebug.breakpoints -> array
24
+ *
25
+ * Returns an array of breakpoints.
26
+ */
27
+ static VALUE
28
+ Breakpoints(VALUE self)
29
+ {
30
+ UNUSED(self);
31
+
32
+ if (NIL_P(breakpoints))
33
+ breakpoints = rb_ary_new();
34
+
35
+ return breakpoints;
36
+ }
37
+
38
+ /*
39
+ * call-seq:
40
+ * Byebug.catchpoints -> hash
41
+ *
42
+ * Returns the catchpoints hash.
43
+ */
44
+ static VALUE
45
+ Catchpoints(VALUE self)
46
+ {
47
+ UNUSED(self);
48
+
49
+ return catchpoints;
50
+ }
51
+
52
+ /*
53
+ * call-seq:
54
+ * Byebug.raised_exception -> exception
55
+ *
56
+ * Returns raised exception when in post_mortem mode.
57
+ */
58
+ static VALUE
59
+ Raised_exception(VALUE self)
60
+ {
61
+ UNUSED(self);
62
+
63
+ return raised_exception;
64
+ }
65
+
66
+ #define IS_STARTED (!NIL_P(catchpoints))
67
+
68
+ static void
69
+ check_started()
70
+ {
71
+ if (!IS_STARTED)
72
+ {
73
+ rb_raise(rb_eRuntimeError, "Byebug is not started yet.");
74
+ }
75
+ }
76
+
77
+ static void
78
+ trace_print(rb_trace_arg_t *trace_arg, debug_context_t *dc,
79
+ const char *file_filter, const char *debug_msg)
80
+ {
81
+ char *fullpath = NULL;
82
+ const char *basename;
83
+ int filtered = 0;
84
+ const char *event = rb_id2name(SYM2ID(rb_tracearg_event(trace_arg)));
85
+
86
+ VALUE rb_path = rb_tracearg_path(trace_arg);
87
+ const char *path = NIL_P(rb_path) ? "" : RSTRING_PTR(rb_path);
88
+
89
+ int line = NUM2INT(rb_tracearg_lineno(trace_arg));
90
+
91
+ VALUE rb_mid = rb_tracearg_method_id(trace_arg);
92
+ const char *mid = NIL_P(rb_mid) ? "(top level)" : rb_id2name(SYM2ID(rb_mid));
93
+
94
+ VALUE rb_cl = rb_tracearg_defined_class(trace_arg);
95
+ VALUE rb_cl_name = NIL_P(rb_cl) ? rb_cl : rb_mod_name(rb_cl);
96
+ const char *defined_class = NIL_P(rb_cl_name) ? "" : RSTRING_PTR(rb_cl_name);
97
+
98
+ if (!trace_arg)
99
+ return;
100
+
101
+ if (file_filter)
102
+ {
103
+ #ifndef _WIN32
104
+ fullpath = realpath(path, NULL);
105
+ #endif
106
+ basename = fullpath ? strrchr(fullpath, '/') : path;
107
+
108
+ if (!basename || strncmp(basename + 1, file_filter, strlen(file_filter)))
109
+ filtered = 1;
110
+
111
+ #ifndef _WIN32
112
+ free(fullpath);
113
+ #endif
114
+ }
115
+
116
+ if (!filtered)
117
+ {
118
+ if (debug_msg)
119
+ rb_funcall(mByebug, idPuts, 1,
120
+ rb_sprintf("[#%d] %s\n", dc->thnum, debug_msg));
121
+ else
122
+ rb_funcall(mByebug, idPuts, 1,
123
+ rb_sprintf("%*s [#%d] %s@%s:%d %s#%s\n", dc->calced_stack_size,
124
+ "", dc->thnum, event, path, line, defined_class,
125
+ mid));
126
+ }
127
+ }
128
+
129
+ static void
130
+ cleanup(debug_context_t *dc)
131
+ {
132
+ dc->stop_reason = CTX_STOP_NONE;
133
+
134
+ release_lock();
135
+ }
136
+
137
+ #define EVENT_TEARDOWN cleanup(dc);
138
+
139
+ #define EVENT_SETUP \
140
+ debug_context_t *dc; \
141
+ VALUE context; \
142
+ rb_trace_arg_t *trace_arg; \
143
+ \
144
+ UNUSED(data); \
145
+ \
146
+ if (!is_living_thread(rb_thread_current())) \
147
+ return; \
148
+ \
149
+ thread_context_lookup(rb_thread_current(), &context); \
150
+ dc = debug_context_ptr(context); \
151
+ \
152
+ trace_arg = rb_tracearg_from_tracepoint(trace_point); \
153
+ if (verbose == Qtrue) \
154
+ trace_print(trace_arg, dc, 0, 0); \
155
+ \
156
+ if (CTX_FL_TEST(dc, CTX_FL_IGNORE)) \
157
+ return; \
158
+ \
159
+ VALUE rb_path = rb_tracearg_path(trace_arg); \
160
+ const char *path = NIL_P(rb_path) ? "" : RSTRING_PTR(rb_path); \
161
+ \
162
+ if (!strncmp(path, "<internal:", strlen("<internal:"))) \
163
+ return; \
164
+ \
165
+ acquire_lock(dc);
166
+
167
+
168
+ #define CALL_EVENT_SETUP \
169
+ dc->calced_stack_size++; \
170
+ dc->steps_out = dc->steps_out < 0 ? -1 : dc->steps_out + 1;
171
+
172
+ #define RETURN_EVENT_SETUP \
173
+ dc->calced_stack_size--; \
174
+ \
175
+ if (dc->steps_out == 1) \
176
+ dc->steps = 1;
177
+
178
+ #define RETURN_EVENT_TEARDOWN \
179
+ dc->steps_out = dc->steps_out <= 0 ? -1 : dc->steps_out - 1;
180
+
181
+
182
+ /* Functions that return control to byebug after the different events */
183
+
184
+ static VALUE
185
+ call_at(VALUE ctx, debug_context_t *dc, ID mid, int argc, VALUE arg)
186
+ {
187
+ struct call_with_inspection_data cwi;
188
+ VALUE argv[1];
189
+
190
+ argv[0] = arg;
191
+
192
+ cwi.dc = dc;
193
+ cwi.ctx = ctx;
194
+ cwi.id = mid;
195
+ cwi.argc = argc;
196
+ cwi.argv = &argv[0];
197
+
198
+ return call_with_debug_inspector(&cwi);
199
+ }
200
+
201
+ static VALUE
202
+ call_at_line(VALUE ctx, debug_context_t *dc)
203
+ {
204
+ return call_at(ctx, dc, rb_intern("at_line"), 0, Qnil);
205
+ }
206
+
207
+ static VALUE
208
+ call_at_tracing(VALUE ctx, debug_context_t *dc)
209
+ {
210
+ return call_at(ctx, dc, rb_intern("at_tracing"), 0, Qnil);
211
+ }
212
+
213
+ static VALUE
214
+ call_at_breakpoint(VALUE ctx, debug_context_t *dc, VALUE breakpoint)
215
+ {
216
+ dc->stop_reason = CTX_STOP_BREAKPOINT;
217
+
218
+ return call_at(ctx, dc, rb_intern("at_breakpoint"), 1, breakpoint);
219
+ }
220
+
221
+ static VALUE
222
+ call_at_catchpoint(VALUE ctx, debug_context_t *dc, VALUE exp)
223
+ {
224
+ dc->stop_reason = CTX_STOP_CATCHPOINT;
225
+
226
+ return call_at(ctx, dc, rb_intern("at_catchpoint"), 1, exp);
227
+ }
228
+
229
+ static VALUE
230
+ call_at_return(VALUE ctx, debug_context_t *dc, VALUE return_value)
231
+ {
232
+ dc->stop_reason = CTX_STOP_BREAKPOINT;
233
+
234
+ return call_at(ctx, dc, rb_intern("at_return"), 1, return_value);
235
+ }
236
+
237
+ static VALUE
238
+ call_at_end(VALUE ctx, debug_context_t *dc)
239
+ {
240
+ dc->stop_reason = CTX_STOP_BREAKPOINT;
241
+
242
+ return call_at(ctx, dc, rb_intern("at_end"), 0, Qnil);
243
+ }
244
+
245
+ static void
246
+ call_at_line_check(VALUE ctx, debug_context_t *dc, VALUE breakpoint)
247
+ {
248
+ dc->stop_reason = CTX_STOP_STEP;
249
+
250
+ if (!NIL_P(breakpoint))
251
+ call_at_breakpoint(ctx, dc, breakpoint);
252
+
253
+ byebug_reset_stepping_stop_points(dc);
254
+
255
+ call_at_line(ctx, dc);
256
+ }
257
+
258
+
259
+ /* TracePoint API event handlers */
260
+
261
+ static void
262
+ line_event(VALUE trace_point, void *data)
263
+ {
264
+ VALUE brkpnt, file, line, binding;
265
+
266
+ EVENT_SETUP;
267
+
268
+ file = rb_tracearg_path(trace_arg);
269
+ line = rb_tracearg_lineno(trace_arg);
270
+ binding = rb_tracearg_binding(trace_arg);
271
+
272
+ if (RTEST(tracing))
273
+ call_at_tracing(context, dc);
274
+
275
+ if (!CTX_FL_TEST(dc, CTX_FL_IGNORE_STEPS))
276
+ dc->steps = dc->steps <= 0 ? -1 : dc->steps - 1;
277
+
278
+ if (dc->calced_stack_size <= dc->dest_frame)
279
+ {
280
+ dc->dest_frame = dc->calced_stack_size;
281
+ CTX_FL_UNSET(dc, CTX_FL_IGNORE_STEPS);
282
+
283
+ dc->lines = dc->lines <= 0 ? -1 : dc->lines - 1;
284
+ }
285
+
286
+ if (dc->steps == 0 || dc->lines == 0)
287
+ call_at_line_check(context, dc, Qnil);
288
+ else
289
+ {
290
+ brkpnt = Qnil;
291
+
292
+ if (!NIL_P(breakpoints))
293
+ brkpnt = find_breakpoint_by_pos(breakpoints, file, line, binding);
294
+
295
+ if (!NIL_P(brkpnt))
296
+ call_at_line_check(context, dc, brkpnt);
297
+ }
298
+
299
+ EVENT_TEARDOWN;
300
+ }
301
+
302
+ static void
303
+ call_event(VALUE trace_point, void *data)
304
+ {
305
+ VALUE brkpnt, klass, msym, mid, binding, self;
306
+
307
+ EVENT_SETUP;
308
+
309
+ if (dc->calced_stack_size <= dc->dest_frame)
310
+ CTX_FL_UNSET(dc, CTX_FL_IGNORE_STEPS);
311
+
312
+ CALL_EVENT_SETUP;
313
+
314
+ msym = rb_tracearg_method_id(trace_arg);
315
+
316
+ mid = SYM2ID(msym);
317
+ klass = rb_tracearg_defined_class(trace_arg);
318
+ binding = rb_tracearg_binding(trace_arg);
319
+ self = rb_tracearg_self(trace_arg);
320
+
321
+ brkpnt = Qnil;
322
+
323
+ if (!NIL_P(breakpoints))
324
+ brkpnt = find_breakpoint_by_method(breakpoints, klass, mid, binding, self);
325
+
326
+ if (!NIL_P(brkpnt))
327
+ {
328
+ call_at_breakpoint(context, dc, brkpnt);
329
+ call_at_line(context, dc);
330
+ }
331
+
332
+ EVENT_TEARDOWN;
333
+ }
334
+
335
+ static void
336
+ return_event(VALUE trace_point, void *data)
337
+ {
338
+ VALUE brkpnt, file, line, binding;
339
+
340
+ EVENT_SETUP;
341
+
342
+ RETURN_EVENT_SETUP;
343
+
344
+ if ((dc->steps_out == 0) && (CTX_FL_TEST(dc, CTX_FL_STOP_ON_RET)))
345
+ {
346
+ byebug_reset_stepping_stop_points(dc);
347
+
348
+ call_at_return(context, dc, rb_tracearg_return_value(trace_arg));
349
+ }
350
+ else if (!NIL_P(breakpoints))
351
+ {
352
+ file = rb_tracearg_path(trace_arg);
353
+ /*
354
+ * @todo Sometimes the TracePoint API gives some return events without
355
+ * file:line information, so we need to guard for nil until we know what's
356
+ * going on. This happens, for example, with active_support core extensions:
357
+ *
358
+ * [#7] call@.../core_ext/numeric/conversions.rb:124 Fixnum#to_s
359
+ * [#7] b_call@.../core_ext/numeric/conversions.rb:124 BigDecimal#to_s
360
+ * [#7] line@.../core_ext/numeric/conversions.rb:125 BigDecimal#to_s
361
+ * [#7] c_call@.../core_ext/numeric/conversions.rb:125 Kernel#is_a?
362
+ * [#7] c_return@.../core_ext/numeric/conversions.rb:125 Kernel#is_a?
363
+ * [#7] line@.../core_ext/numeric/conversions.rb:131 BigDecimal#to_s
364
+ * [#7] c_call@.../core_ext/numeric/conversions.rb:131 Fixnum#to_default_s
365
+ * [#7] c_return@.../core_ext/numeric/conversions.rb:131 Fixnum#to_default_s
366
+ * [#7] b_return@/hort/core_ext/numeric/conversions.rb:133 BigDecimal#to_s
367
+ * [#7] return@:0 Fixnum#to_s # => This guy...
368
+ */
369
+ if (NIL_P(file))
370
+ rb_warn("The TracePoint API emitted a return event without file information. It might be a bug, please report this.");
371
+ else
372
+ {
373
+ line = rb_tracearg_lineno(trace_arg);
374
+ binding = rb_tracearg_binding(trace_arg);
375
+
376
+ brkpnt = find_breakpoint_by_pos(breakpoints, file, line, binding);
377
+
378
+ if (!NIL_P(brkpnt))
379
+ call_at_return(context, dc, rb_tracearg_return_value(trace_arg));
380
+ }
381
+ }
382
+
383
+ RETURN_EVENT_TEARDOWN;
384
+
385
+ EVENT_TEARDOWN;
386
+ }
387
+
388
+ static void
389
+ end_event(VALUE trace_point, void *data)
390
+ {
391
+ EVENT_SETUP;
392
+
393
+ RETURN_EVENT_SETUP;
394
+
395
+ if ((dc->steps_out == 0) && (CTX_FL_TEST(dc, CTX_FL_STOP_ON_RET)))
396
+ {
397
+ byebug_reset_stepping_stop_points(dc);
398
+
399
+ call_at_end(context, dc);
400
+ }
401
+
402
+ RETURN_EVENT_TEARDOWN;
403
+
404
+ EVENT_TEARDOWN;
405
+ }
406
+
407
+ static void
408
+ raw_call_event(VALUE trace_point, void *data)
409
+ {
410
+ EVENT_SETUP;
411
+
412
+ CALL_EVENT_SETUP;
413
+
414
+ EVENT_TEARDOWN;
415
+ }
416
+
417
+ static void
418
+ raw_return_event(VALUE trace_point, void *data)
419
+ {
420
+ EVENT_SETUP;
421
+
422
+ RETURN_EVENT_SETUP;
423
+
424
+ RETURN_EVENT_TEARDOWN;
425
+
426
+ EVENT_TEARDOWN;
427
+ }
428
+
429
+ static void
430
+ raise_event(VALUE trace_point, void *data)
431
+ {
432
+ VALUE expn_class, ancestors, pm_context;
433
+ int i;
434
+ debug_context_t *new_dc;
435
+
436
+ EVENT_SETUP;
437
+
438
+ raised_exception = rb_tracearg_raised_exception(trace_arg);
439
+
440
+ if (post_mortem == Qtrue && !rb_ivar_defined(raised_exception, rb_intern("@__bb_context")))
441
+ {
442
+ pm_context = context_dup(dc);
443
+ rb_ivar_set(raised_exception, rb_intern("@__bb_context"), pm_context);
444
+
445
+ new_dc = debug_context_ptr(pm_context);
446
+ rb_debug_inspector_open(context_backtrace_set, (void *)new_dc);
447
+ }
448
+
449
+ if (NIL_P(catchpoints) || dc->calced_stack_size == 0
450
+ || RHASH_TBL(catchpoints)->num_entries == 0)
451
+ {
452
+ EVENT_TEARDOWN;
453
+ return;
454
+ }
455
+
456
+ expn_class = rb_obj_class(raised_exception);
457
+ ancestors = rb_mod_ancestors(expn_class);
458
+ for (i = 0; i < RARRAY_LENINT(ancestors); i++)
459
+ {
460
+ VALUE ancestor_class, module_name, hit_count;
461
+
462
+ ancestor_class = rb_ary_entry(ancestors, i);
463
+ module_name = rb_mod_name(ancestor_class);
464
+ hit_count = rb_hash_aref(catchpoints, module_name);
465
+
466
+ /* increment exception */
467
+ if (!NIL_P(hit_count))
468
+ {
469
+ rb_hash_aset(catchpoints, module_name, INT2FIX(FIX2INT(hit_count) + 1));
470
+
471
+ call_at_catchpoint(context, dc, raised_exception);
472
+ call_at_line(context, dc);
473
+
474
+ break;
475
+ }
476
+ }
477
+
478
+ EVENT_TEARDOWN;
479
+ }
480
+
481
+
482
+ /* Setup TracePoint functionality */
483
+
484
+ static void
485
+ register_tracepoints(VALUE self)
486
+ {
487
+ int i;
488
+ VALUE traces = tracepoints;
489
+
490
+ UNUSED(self);
491
+
492
+ if (NIL_P(traces))
493
+ {
494
+ int line_msk = RUBY_EVENT_LINE;
495
+ int call_msk = RUBY_EVENT_CALL;
496
+ int ret_msk = RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN;
497
+ int end_msk = RUBY_EVENT_END;
498
+ int raw_call_msk = RUBY_EVENT_C_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_CLASS;
499
+ int raw_ret_msk = RUBY_EVENT_C_RETURN;
500
+ int raise_msk = RUBY_EVENT_RAISE;
501
+
502
+ VALUE tpLine = rb_tracepoint_new(Qnil, line_msk, line_event, 0);
503
+ VALUE tpCall = rb_tracepoint_new(Qnil, call_msk, call_event, 0);
504
+ VALUE tpReturn = rb_tracepoint_new(Qnil, ret_msk, return_event, 0);
505
+ VALUE tpEnd = rb_tracepoint_new(Qnil, end_msk, end_event, 0);
506
+ VALUE tpCCall = rb_tracepoint_new(Qnil, raw_call_msk, raw_call_event, 0);
507
+ VALUE tpCReturn = rb_tracepoint_new(Qnil, raw_ret_msk, raw_return_event, 0);
508
+ VALUE tpRaise = rb_tracepoint_new(Qnil, raise_msk, raise_event, 0);
509
+
510
+ traces = rb_ary_new();
511
+ rb_ary_push(traces, tpLine);
512
+ rb_ary_push(traces, tpCall);
513
+ rb_ary_push(traces, tpReturn);
514
+ rb_ary_push(traces, tpEnd);
515
+ rb_ary_push(traces, tpCCall);
516
+ rb_ary_push(traces, tpCReturn);
517
+ rb_ary_push(traces, tpRaise);
518
+
519
+ tracepoints = traces;
520
+ }
521
+
522
+ for (i = 0; i < RARRAY_LENINT(traces); i++)
523
+ rb_tracepoint_enable(rb_ary_entry(traces, i));
524
+ }
525
+
526
+ static void
527
+ clear_tracepoints(VALUE self)
528
+ {
529
+ int i;
530
+
531
+ UNUSED(self);
532
+
533
+ for (i = RARRAY_LENINT(tracepoints) - 1; i >= 0; i--)
534
+ rb_tracepoint_disable(rb_ary_entry(tracepoints, i));
535
+ }
536
+
537
+
538
+ /* Byebug's Public API */
539
+
540
+ /*
541
+ * call-seq:
542
+ * Byebug.contexts -> array
543
+ *
544
+ * Returns an array of all contexts.
545
+ */
546
+ static VALUE
547
+ Contexts(VALUE self)
548
+ {
549
+ volatile VALUE list;
550
+ volatile VALUE new_list;
551
+ VALUE context;
552
+ threads_table_t *t_tbl;
553
+ debug_context_t *dc;
554
+ int i;
555
+
556
+ UNUSED(self);
557
+
558
+ check_started();
559
+
560
+ new_list = rb_ary_new();
561
+ list = rb_funcall(rb_cThread, rb_intern("list"), 0);
562
+
563
+ for (i = 0; i < RARRAY_LENINT(list); i++)
564
+ {
565
+ VALUE thread = rb_ary_entry(list, i);
566
+
567
+ thread_context_lookup(thread, &context);
568
+ rb_ary_push(new_list, context);
569
+ }
570
+
571
+ t_tbl = threads_table_ptr(threads);
572
+ st_clear(t_tbl->tbl);
573
+
574
+ for (i = 0; i < RARRAY_LENINT(new_list); i++)
575
+ {
576
+ context = rb_ary_entry(new_list, i);
577
+ dc = debug_context_ptr(context);
578
+ st_insert(t_tbl->tbl, dc->thread, context);
579
+ }
580
+
581
+ return new_list;
582
+ }
583
+
584
+ /*
585
+ * call-seq:
586
+ * Byebug.thread_context(thread) -> context
587
+ *
588
+ * Returns context of the thread passed as an argument.
589
+ */
590
+ static VALUE
591
+ Thread_context(VALUE self, VALUE thread)
592
+ {
593
+ VALUE context;
594
+
595
+ UNUSED(self);
596
+
597
+ check_started();
598
+
599
+ thread_context_lookup(thread, &context);
600
+
601
+ return context;
602
+ }
603
+
604
+ /*
605
+ * call-seq:
606
+ * Byebug.current_context -> context
607
+ *
608
+ * Returns the current context.
609
+ * <i>Note:</i> Byebug.current_context.thread == Thread.current
610
+ */
611
+ static VALUE
612
+ Current_context(VALUE self)
613
+ {
614
+ VALUE context;
615
+
616
+ UNUSED(self);
617
+
618
+ thread_context_lookup(rb_thread_current(), &context);
619
+
620
+ return context;
621
+ }
622
+
623
+ /*
624
+ * call-seq:
625
+ * Byebug.started? -> bool
626
+ *
627
+ * Returns +true+ byebug is started.
628
+ */
629
+ static VALUE
630
+ Started(VALUE self)
631
+ {
632
+ UNUSED(self);
633
+
634
+ return IS_STARTED ? Qtrue : Qfalse;
635
+ }
636
+
637
+ /*
638
+ * call-seq:
639
+ * Byebug.stop -> bool
640
+ *
641
+ * This method disables byebug. It returns +true+ if byebug was already
642
+ * disabled, otherwise it returns +false+.
643
+ */
644
+ static VALUE
645
+ Stop(VALUE self)
646
+ {
647
+ UNUSED(self);
648
+
649
+ if (IS_STARTED)
650
+ {
651
+ clear_tracepoints(self);
652
+
653
+ breakpoints = Qnil;
654
+ catchpoints = Qnil;
655
+
656
+ return Qfalse;
657
+ }
658
+
659
+ return Qtrue;
660
+ }
661
+
662
+ static VALUE
663
+ Stoppable(VALUE self)
664
+ {
665
+ VALUE context;
666
+ debug_context_t *dc;
667
+
668
+ if (!IS_STARTED)
669
+ return Qfalse;
670
+
671
+ if (!NIL_P(breakpoints) && rb_funcall(breakpoints, idEmpty, 0) == Qfalse)
672
+ return Qfalse;
673
+
674
+ if (!NIL_P(catchpoints) && rb_funcall(catchpoints, idEmpty, 0) == Qfalse)
675
+ return Qfalse;
676
+
677
+ if (post_mortem == Qtrue)
678
+ return Qfalse;
679
+
680
+ if (RTEST(tracing))
681
+ return Qfalse;
682
+
683
+ context = Current_context(self);
684
+ if (!NIL_P(context))
685
+ {
686
+ dc = debug_context_ptr(context);
687
+
688
+ if (dc->steps > 0)
689
+ return Qfalse;
690
+ }
691
+
692
+ return Qtrue;
693
+ }
694
+
695
+ /*
696
+ * call-seq:
697
+ * Byebug.start -> bool
698
+ *
699
+ * The return value is the value of !Byebug.started? <i>before</i> issuing the
700
+ * +start+; That is, +true+ is returned, unless byebug was previously started.
701
+ */
702
+ static VALUE
703
+ Start(VALUE self)
704
+ {
705
+ if (IS_STARTED)
706
+ return Qfalse;
707
+
708
+ catchpoints = rb_hash_new();
709
+
710
+ threads = create_threads_table();
711
+
712
+ register_tracepoints(self);
713
+
714
+ return Qtrue;
715
+ }
716
+
717
+ /*
718
+ * call-seq:
719
+ * Byebug.debug_load(file, stop = false) -> nil
720
+ *
721
+ * Same as Kernel#load but resets current context's frames.
722
+ * +stop+ parameter forces byebug to stop at the first line of code in +file+
723
+ */
724
+ static VALUE
725
+ Debug_load(int argc, VALUE *argv, VALUE self)
726
+ {
727
+ VALUE file, stop, context;
728
+ debug_context_t *dc;
729
+ VALUE status = Qnil;
730
+ int state = 0;
731
+
732
+ UNUSED(self);
733
+
734
+ if (rb_scan_args(argc, argv, "11", &file, &stop) == 1)
735
+ stop = Qfalse;
736
+
737
+ Start(self);
738
+
739
+ context = Current_context(self);
740
+ dc = debug_context_ptr(context);
741
+
742
+ dc->calced_stack_size = 1;
743
+
744
+ if (RTEST(stop))
745
+ dc->steps = 1;
746
+
747
+ rb_load_protect(file, 0, &state);
748
+ if (0 != state)
749
+ {
750
+ status = rb_errinfo();
751
+ byebug_reset_stepping_stop_points(dc);
752
+ }
753
+
754
+ return status;
755
+ }
756
+
757
+ /*
758
+ * call-seq:
759
+ * Byebug.tracing? -> bool
760
+ *
761
+ * Returns +true+ if global tracing is enabled.
762
+ */
763
+ static VALUE
764
+ Tracing(VALUE self)
765
+ {
766
+ UNUSED(self);
767
+
768
+ return tracing;
769
+ }
770
+
771
+ /*
772
+ * call-seq:
773
+ * Byebug.tracing = bool
774
+ *
775
+ * Sets the global tracing flag.
776
+ */
777
+ static VALUE
778
+ Set_tracing(VALUE self, VALUE value)
779
+ {
780
+ UNUSED(self);
781
+
782
+ tracing = RTEST(value) ? Qtrue : Qfalse;
783
+ return value;
784
+ }
785
+
786
+ /*
787
+ * call-seq:
788
+ * Byebug.verbose? -> bool
789
+ *
790
+ * Returns +true+ if global verbose flag for TracePoint API events is enabled.
791
+ */
792
+ static VALUE
793
+ Verbose(VALUE self)
794
+ {
795
+ UNUSED(self);
796
+
797
+ return verbose;
798
+ }
799
+
800
+ /*
801
+ * call-seq:
802
+ * Byebug.verbose = bool
803
+ *
804
+ * Sets the global verbose flag for TracePoint API events is enabled.
805
+ */
806
+ static VALUE
807
+ Set_verbose(VALUE self, VALUE value)
808
+ {
809
+ UNUSED(self);
810
+
811
+ verbose = RTEST(value) ? Qtrue : Qfalse;
812
+ return value;
813
+ }
814
+
815
+ /*
816
+ * call-seq:
817
+ * Byebug.post_mortem? -> bool
818
+ *
819
+ * Returns +true+ if post-mortem debugging is enabled.
820
+ */
821
+ static VALUE
822
+ Post_mortem(VALUE self)
823
+ {
824
+ UNUSED(self);
825
+
826
+ return post_mortem;
827
+ }
828
+
829
+ /*
830
+ * call-seq:
831
+ * Byebug.post_mortem = bool
832
+ *
833
+ * Sets post-moterm flag.
834
+ */
835
+ static VALUE
836
+ Set_post_mortem(VALUE self, VALUE value)
837
+ {
838
+ UNUSED(self);
839
+
840
+ post_mortem = RTEST(value) ? Qtrue : Qfalse;
841
+ return value;
842
+ }
843
+
844
+ /*
845
+ * call-seq:
846
+ * Byebug.add_catchpoint(exception) -> exception
847
+ *
848
+ * Adds a new exception to the catchpoints hash.
849
+ */
850
+ static VALUE
851
+ Add_catchpoint(VALUE self, VALUE value)
852
+ {
853
+ UNUSED(self);
854
+
855
+ if (TYPE(value) != T_STRING)
856
+ rb_raise(rb_eTypeError, "value of a catchpoint must be String");
857
+
858
+ rb_hash_aset(catchpoints, rb_str_dup(value), INT2FIX(0));
859
+ return value;
860
+ }
861
+
862
+ /*
863
+ * Document-module: Byebug
864
+ *
865
+ * == Summary
866
+ *
867
+ * This is a singleton class allows controlling byebug. Use it to start/stop
868
+ * byebug, set/remove breakpoints, etc.
869
+ */
870
+ void
871
+ Init_byebug()
872
+ {
873
+ mByebug = rb_define_module("Byebug");
874
+
875
+ rb_define_module_function(mByebug, "add_catchpoint", Add_catchpoint, 1);
876
+ rb_define_module_function(mByebug, "breakpoints", Breakpoints, 0);
877
+ rb_define_module_function(mByebug, "catchpoints", Catchpoints, 0);
878
+ rb_define_module_function(mByebug, "contexts", Contexts, 0);
879
+ rb_define_module_function(mByebug, "current_context", Current_context, 0);
880
+ rb_define_module_function(mByebug, "debug_load", Debug_load, -1);
881
+ rb_define_module_function(mByebug, "post_mortem?", Post_mortem, 0);
882
+ rb_define_module_function(mByebug, "post_mortem=", Set_post_mortem, 1);
883
+ rb_define_module_function(mByebug, "raised_exception", Raised_exception, 0);
884
+ rb_define_module_function(mByebug, "start", Start, 0);
885
+ rb_define_module_function(mByebug, "started?", Started, 0);
886
+ rb_define_module_function(mByebug, "stop", Stop, 0);
887
+ rb_define_module_function(mByebug, "stoppable?", Stoppable, 0);
888
+ rb_define_module_function(mByebug, "thread_context", Thread_context, 1);
889
+ rb_define_module_function(mByebug, "tracing?", Tracing, 0);
890
+ rb_define_module_function(mByebug, "tracing=", Set_tracing, 1);
891
+ rb_define_module_function(mByebug, "verbose?", Verbose, 0);
892
+ rb_define_module_function(mByebug, "verbose=", Set_verbose, 1);
893
+
894
+ Init_threads_table(mByebug);
895
+ Init_byebug_context(mByebug);
896
+ Init_byebug_breakpoint(mByebug);
897
+
898
+ rb_global_variable(&breakpoints);
899
+ rb_global_variable(&catchpoints);
900
+ rb_global_variable(&tracepoints);
901
+ rb_global_variable(&raised_exception);
902
+ rb_global_variable(&threads);
903
+
904
+ idPuts = rb_intern("puts");
905
+ idEmpty = rb_intern("empty?");
906
+ }