byebug 1.3.1 → 1.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 497f9606e8de41c51c02441cdbda3092f7131ec3
4
- data.tar.gz: 12a94e7916cc107fb392af1a7abc0cd8515ce696
3
+ metadata.gz: d18d944520a45aaad538b12d098effea86da264b
4
+ data.tar.gz: a9a224673d713f67bd67c13e5e1f1a88b08d90c5
5
5
  SHA512:
6
- metadata.gz: 7ffdf9b6cf8fc471af1b57efacabaa9e3159c115e59d718417792e6a70a7686070a7537a1d2c10da741988fb1416bf61cb95d71420718f89219d434d3c318b7f
7
- data.tar.gz: f1ddc5b71c708a81de661402d52a2b758913cdd09d2b4827cf850643467ef857b50dc64fa0f98ed3ba774de0dc34f1dc6b69c6d3b68d4226f3a5ac835fb8ef7d
6
+ metadata.gz: 29d6e1b0b24f742210043e44e5a6cc767982e5d95bb22fe7e72e42841b2c8d8c347c94431d59d72f0b1138336a6e2b5c52a3b2cae52e1838cab2f73560ee0f9b
7
+ data.tar.gz: bbc117ad67be478a69e5116a335539be57ebb007f101e4f4de4fab4fac8a793c155a948a287f95af670718513aee946622ef1fcac23913471700ed207959409a
@@ -1,3 +1,9 @@
1
+ ## 1.4.0
2
+
3
+ * Byebug now uses the Debug Inspector API: faster and nicer!
4
+ * Fixes bug that prevents some random crashes
5
+
6
+
1
7
  ## 1.3.1
2
8
 
3
9
  * Byebug now works with Rails debugging flag
data/README.md CHANGED
@@ -6,8 +6,9 @@
6
6
  _Debugging in Ruby 2.0_
7
7
 
8
8
  Byebug is a simple to use, feature rich debugger for Ruby 2.0. It uses the new
9
- TracePoint API, so it doesn't depend on internal core sources. It's developed as
10
- a C extension, so it's fast. And it has a full test suite so it's (I hope)
9
+ TracePoint API for execution control and the new Debug Inspector API for call
10
+ stack navigation, so it doesn't depend on internal core sources. It's developed
11
+ as a C extension, so it's fast. And it has a full test suite so it's (I hope)
11
12
  reliable.
12
13
 
13
14
  It allows you to see what is going on _inside_ a Ruby program while it executes
data/bin/byebug CHANGED
@@ -206,6 +206,7 @@ opts = process_options(options)
206
206
  begin
207
207
  Byebug::ARGV = ARGV.clone if not defined? Byebug::ARGV
208
208
  Byebug::BYEBUG_SCRIPT = File.expand_path(__FILE__)
209
+ Byebug::IGNORED_FILES << Byebug::BYEBUG_SCRIPT
209
210
  Byebug::INITIAL_DIR = Dir.pwd
210
211
  opts.parse! ARGV
211
212
  rescue StandardError => e
@@ -10,10 +10,11 @@ Gem::Specification.new do |s|
10
10
  s.homepage = "http://github.com/deivid-rodriguez/byebug"
11
11
  s.summary = %q{Ruby 2.0 fast debugger - base + cli}
12
12
  s.description = %q{Byebug is a Ruby 2.0 debugger. It's implemented using the
13
- Ruby 2.0 TracePoint C API. The C extension was forked from debase whereas
14
- the rest of the gem was forked from debugger. The core component provides
15
- support that front-ends can build on. It provides breakpoint handling,
16
- bindings for stack frames among other things.}
13
+ Ruby 2.0 TracePoint C API for execution control and the Debug Inspector C
14
+ API for call stack navigation. The core component provides support that
15
+ front-ends can build on. It provides breakpoint handling and bindings for
16
+ stack frames among other things and it comes with an easy to use command
17
+ line interface.}
17
18
 
18
19
  s.required_ruby_version = '>= 2.0.0'
19
20
  s.required_rubygems_version = ">= 2.0.3"
@@ -28,7 +29,7 @@ Gem::Specification.new do |s|
28
29
  s.add_development_dependency 'rake', '~> 10.0.4'
29
30
  s.add_development_dependency 'rake-compiler', '~> 0.8.3'
30
31
  s.add_development_dependency 'mocha', '~> 0.14.0'
31
- s.add_development_dependency 'minitest', '~> 5.0.2'
32
+ s.add_development_dependency 'minitest', '~> 5.0.3'
32
33
 
33
34
  s.license = "BSD"
34
35
  end
@@ -100,10 +100,9 @@ Breakpoint_mark(breakpoint_t *breakpoint)
100
100
  static VALUE
101
101
  Breakpoint_create(VALUE klass)
102
102
  {
103
- breakpoint_t *breakpoint;
103
+ breakpoint_t *breakpoint = ALLOC(breakpoint_t);
104
104
 
105
- breakpoint = ALLOC(breakpoint_t);
106
- return Data_Wrap_Struct(klass, Breakpoint_mark, xfree, breakpoint);
105
+ return Data_Wrap_Struct(klass, Breakpoint_mark, xfree, breakpoint);
107
106
  }
108
107
 
109
108
  static VALUE
@@ -179,10 +178,10 @@ Breakpoint_pos(VALUE self)
179
178
  breakpoint_t *breakpoint;
180
179
 
181
180
  Data_Get_Struct(self, breakpoint_t, breakpoint);
182
- if(breakpoint->type == BP_METHOD_TYPE)
183
- return rb_str_new2(rb_id2name(breakpoint->pos.mid));
181
+ if (breakpoint->type == BP_METHOD_TYPE)
182
+ return rb_str_new2(rb_id2name(breakpoint->pos.mid));
184
183
  else
185
- return INT2FIX(breakpoint->pos.line);
184
+ return INT2FIX(breakpoint->pos.line);
186
185
  }
187
186
 
188
187
 
@@ -198,11 +197,11 @@ Breakpoint_expr(VALUE self)
198
197
  static VALUE
199
198
  Breakpoint_set_expr(VALUE self, VALUE expr)
200
199
  {
201
- breakpoint_t *breakpoint;
200
+ breakpoint_t *breakpoint;
202
201
 
203
- Data_Get_Struct(self, breakpoint_t, breakpoint);
204
- breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
205
- return expr;
202
+ Data_Get_Struct(self, breakpoint_t, breakpoint);
203
+ breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
204
+ return expr;
206
205
  }
207
206
 
208
207
  static VALUE
@@ -318,19 +317,19 @@ check_breakpoint_by_hit_condition(VALUE breakpoint_object)
318
317
  static int
319
318
  check_breakpoint_by_pos(VALUE breakpoint_object, char *file, int line)
320
319
  {
321
- breakpoint_t *breakpoint;
320
+ breakpoint_t *breakpoint;
322
321
 
323
- if (breakpoint_object == Qnil)
324
- return 0;
322
+ if (breakpoint_object == Qnil)
323
+ return 0;
325
324
 
326
- Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
325
+ Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
327
326
 
328
- if ( (Qtrue != breakpoint->enabled) ||
329
- (breakpoint->type != BP_POS_TYPE) ||
330
- (breakpoint->pos.line != line) )
331
- return 0;
327
+ if ( (Qtrue != breakpoint->enabled) ||
328
+ (breakpoint->type != BP_POS_TYPE) ||
329
+ (breakpoint->pos.line != line) )
330
+ return 0;
332
331
 
333
- return filename_cmp(breakpoint->source, file);
332
+ return filename_cmp(breakpoint->source, file);
334
333
  }
335
334
 
336
335
  static int
@@ -362,7 +361,7 @@ check_breakpoint_by_expr(VALUE breakpoint_object, VALUE binding)
362
361
  breakpoint_t *breakpoint;
363
362
  VALUE args, expr_result;
364
363
 
365
- if (breakpoint_object == Qnil)
364
+ if (NIL_P(breakpoint_object))
366
365
  return 0;
367
366
 
368
367
  Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
@@ -390,12 +389,12 @@ find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos,
390
389
 
391
390
  file = RSTRING_PTR(source);
392
391
  line = FIX2INT(pos);
393
- for(i = 0; i < RARRAY_LEN(breakpoints); i++)
392
+ for (i = 0; i < RARRAY_LEN(breakpoints); i++)
394
393
  {
395
394
  breakpoint_object = rb_ary_entry(breakpoints, i);
396
- if ( check_breakpoint_by_pos(breakpoint_object, file, line) &&
397
- check_breakpoint_by_expr(breakpoint_object, binding) &&
398
- check_breakpoint_by_hit_condition(breakpoint_object) )
395
+ if (check_breakpoint_by_pos(breakpoint_object, file, line) &&
396
+ check_breakpoint_by_expr(breakpoint_object, binding) &&
397
+ check_breakpoint_by_hit_condition(breakpoint_object))
399
398
  {
400
399
  return breakpoint_object;
401
400
  }
@@ -410,13 +409,15 @@ find_breakpoint_by_method(VALUE breakpoints, VALUE klass, ID mid, VALUE binding,
410
409
  VALUE breakpoint_object;
411
410
  int i;
412
411
 
413
- for(i = 0; i < RARRAY_LEN(breakpoints); i++)
412
+ for (i = 0; i < RARRAY_LEN(breakpoints); i++)
414
413
  {
415
414
  breakpoint_object = rb_ary_entry(breakpoints, i);
416
- if ( check_breakpoint_by_method(breakpoint_object, klass, mid, self) &&
417
- check_breakpoint_by_expr(breakpoint_object, binding) &&
418
- check_breakpoint_by_hit_condition(breakpoint_object) )
415
+ if (check_breakpoint_by_method(breakpoint_object, klass, mid, self) &&
416
+ check_breakpoint_by_expr(breakpoint_object, binding) &&
417
+ check_breakpoint_by_hit_condition(breakpoint_object))
418
+ {
419
419
  return breakpoint_object;
420
+ }
420
421
  }
421
422
  return Qnil;
422
423
  }
@@ -7,20 +7,19 @@ static VALUE tracing = Qfalse;
7
7
  static VALUE post_mortem = Qfalse;
8
8
  static VALUE debug = Qfalse;
9
9
 
10
- static VALUE context;
11
- static VALUE catchpoints;
12
- static VALUE breakpoints;
10
+ static VALUE context = Qnil;
11
+ static VALUE catchpoints = Qnil;
12
+ static VALUE breakpoints = Qnil;
13
13
 
14
- static VALUE tpLine;
15
- static VALUE tpCall;
16
- static VALUE tpCCall;
17
- static VALUE tpReturn;
18
- static VALUE tpCReturn;
19
- static VALUE tpRaise;
14
+ static VALUE tpLine = Qnil;
15
+ static VALUE tpCall = Qnil;
16
+ static VALUE tpCCall = Qnil;
17
+ static VALUE tpReturn = Qnil;
18
+ static VALUE tpCReturn = Qnil;
19
+ static VALUE tpRaise = Qnil;
20
20
 
21
21
  static VALUE
22
- tp_inspect(VALUE trace_point) {
23
- rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(trace_point);
22
+ tp_inspect(rb_trace_arg_t *trace_arg) {
24
23
  if (trace_arg) {
25
24
  VALUE event = rb_tracearg_event(trace_arg);
26
25
  if (ID2SYM(rb_intern("line")) == event ||
@@ -55,216 +54,265 @@ static VALUE
55
54
  Byebug_context(VALUE self)
56
55
  {
57
56
  if (context == Qnil) {
58
- context = Context_create();
57
+ context = context_create();
59
58
  }
60
59
  return context;
61
60
  }
62
61
 
63
62
  static void
64
- cleanup(debug_context_t *context)
63
+ cleanup(debug_context_t *dc)
65
64
  {
66
- context->stop_reason = CTX_STOP_NONE;
65
+ dc->stop_reason = CTX_STOP_NONE;
67
66
  }
68
67
 
69
- static int
70
- check_start_processing(debug_context_t *context)
68
+ static void
69
+ save_current_position(debug_context_t *dc, VALUE file, VALUE line)
71
70
  {
72
- /* ignore a skipped section of code */
73
- if(CTX_FL_TEST(context, CTX_FL_SKIPPED)) {
74
- cleanup(context);
75
- return 0;
76
- }
77
- return 1;
71
+ dc->last_file = file;
72
+ dc->last_line = line;
73
+ CTX_FL_UNSET(dc, CTX_FL_ENABLE_BKPT);
74
+ CTX_FL_UNSET(dc, CTX_FL_FORCE_MOVE);
75
+ }
76
+
77
+ static VALUE
78
+ call_at(VALUE context_obj, debug_context_t *dc, ID mid, int argc, VALUE a0,
79
+ VALUE a1)
80
+ {
81
+ struct call_with_inspection_data cwi;
82
+ VALUE argv[2];
83
+
84
+ argv[0] = a0;
85
+ argv[1] = a1;
86
+
87
+ cwi.dc = dc;
88
+ cwi.context_obj = context_obj;
89
+ cwi.id = mid;
90
+ cwi.argc = argc;
91
+ cwi.argv = &argv[0];
92
+
93
+ return call_with_debug_inspector(&cwi);
94
+ }
95
+
96
+ static VALUE
97
+ call_at_line(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line)
98
+ {
99
+ save_current_position(dc, file, line);
100
+ return call_at(context_obj, dc, rb_intern("at_line"), 2, file, line);
78
101
  }
79
102
 
80
- static inline void
81
- load_frame_info(VALUE trace_point, VALUE *path, VALUE *lineno, VALUE *method_id,
82
- VALUE *defined_class, VALUE *binding,
83
- VALUE *self)
103
+ static VALUE
104
+ call_at_tracing(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line)
84
105
  {
85
- rb_trace_point_t *tp;
106
+ return call_at(context_obj, dc, rb_intern("at_tracing"), 2, file, line);
107
+ }
86
108
 
87
- tp = rb_tracearg_from_tracepoint(trace_point);
109
+ static VALUE
110
+ call_at_breakpoint(VALUE context_obj, debug_context_t *dc, VALUE breakpoint)
111
+ {
112
+ dc->stop_reason = CTX_STOP_BREAKPOINT;
113
+ return call_at(context_obj, dc, rb_intern("at_breakpoint"), 1, breakpoint, 0);
114
+ }
88
115
 
89
- *path = rb_tracearg_path(tp);
90
- *lineno = rb_tracearg_lineno(tp);
91
- *binding = rb_tracearg_binding(tp);
92
- *self = rb_tracearg_self(tp);
93
- *method_id = rb_tracearg_method_id(tp);
94
- *defined_class = rb_tracearg_defined_class(tp);
116
+ static VALUE
117
+ call_at_catchpoint(VALUE context_obj, debug_context_t *dc, VALUE exp)
118
+ {
119
+ dc->stop_reason = CTX_STOP_CATCHPOINT;
120
+ return call_at(context_obj, dc, rb_intern("at_catchpoint"), 1, exp, 0);
95
121
  }
96
122
 
97
123
  static void
98
- call_at_line(debug_context_t *context, VALUE context_obj,
99
- VALUE path, VALUE lineno)
100
- {
101
- CTX_FL_UNSET(context, CTX_FL_ENABLE_BKPT);
102
- CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
103
- context->last_file = RSTRING_PTR(path);
104
- context->last_line = FIX2INT(lineno);
105
- rb_funcall(context_obj, rb_intern("at_line"), 2, path, lineno);
106
- }
107
-
108
- #define EVENT_SETUP \
109
- VALUE path, lineno, method_id, defined_class, binding, self; \
110
- VALUE context_obj; \
111
- debug_context_t *context; \
112
- context_obj = Byebug_context(mByebug); \
113
- Data_Get_Struct(context_obj, debug_context_t, context); \
114
- if (!check_start_processing(context)) return; \
115
- load_frame_info(trace_point, &path, &lineno, &method_id, &defined_class, \
116
- &binding, &self); \
117
- if (debug == Qtrue) \
118
- printf("%s (stack_size: %d)\n", \
119
- RSTRING_PTR(tp_inspect(trace_point)), context->stack_size); \
124
+ call_at_line_check(VALUE context_obj, debug_context_t *dc,
125
+ VALUE breakpoint, VALUE file, VALUE line)
126
+ {
127
+ dc->stop_reason = CTX_STOP_STEP;
128
+
129
+ if (breakpoint != Qnil)
130
+ call_at_breakpoint(context_obj, dc, breakpoint);
131
+
132
+ reset_stepping_stop_points(dc);
133
+ call_at_line(context_obj, dc, file, line);
134
+ }
135
+
136
+ #define EVENT_SETUP \
137
+ rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(trace_point); \
138
+ VALUE context_obj; \
139
+ debug_context_t *dc; \
140
+ context_obj = Byebug_context(mByebug); \
141
+ Data_Get_Struct(context_obj, debug_context_t, dc); \
142
+ if (debug == Qtrue) \
143
+ printf("%s (stack_size: %d)\n", \
144
+ RSTRING_PTR(tp_inspect(trace_arg)), dc->stack_size); \
145
+
146
+ #define EVENT_COMMON() \
147
+ if (trace_common(trace_arg, dc) == 0) { return; }
148
+
149
+ static int
150
+ trace_common(rb_trace_arg_t *trace_arg, debug_context_t *dc)
151
+ {
152
+ /* ignore a skipped section of code */
153
+ if (CTX_FL_TEST(dc, CTX_FL_SKIPPED))
154
+ {
155
+ cleanup(dc);
156
+ return 0;
157
+ }
158
+
159
+ /* Many events per line, but only *one* breakpoint */
160
+ if (dc->last_line != rb_tracearg_lineno(trace_arg) ||
161
+ dc->last_file != rb_tracearg_path(trace_arg))
162
+ {
163
+ CTX_FL_SET(dc, CTX_FL_ENABLE_BKPT);
164
+ }
165
+
166
+ return 1;
167
+ }
120
168
 
121
169
  static void
122
170
  process_line_event(VALUE trace_point, void *data)
123
171
  {
124
172
  EVENT_SETUP;
125
- VALUE breakpoint;
173
+ VALUE breakpoint = Qnil;
174
+ VALUE file = rb_tracearg_path(trace_arg);
175
+ VALUE line = rb_tracearg_lineno(trace_arg);
176
+ VALUE binding = rb_tracearg_binding(trace_arg);
126
177
  int moved = 0;
127
178
 
128
- if (context->stack_size == 0)
129
- push_frame(context, RSTRING_PTR(path), FIX2INT(lineno), method_id,
130
- defined_class, binding, self);
131
- else
132
- update_frame(context->stack, RSTRING_PTR(path), FIX2INT(lineno), method_id,
133
- defined_class, binding, self);
179
+ EVENT_COMMON();
134
180
 
135
- if (context->last_line != FIX2INT(lineno) || context->last_file == NULL ||
136
- strcmp(context->last_file, RSTRING_PTR(path)))
181
+ if (dc->stack_size == 0) dc->stack_size++;
182
+
183
+ if (dc->last_line != rb_tracearg_lineno(trace_arg) ||
184
+ dc->last_file != rb_tracearg_path(trace_arg))
137
185
  {
138
- CTX_FL_SET(context, CTX_FL_ENABLE_BKPT);
139
186
  moved = 1;
140
187
  }
141
188
 
142
189
  if (RTEST(tracing))
143
- rb_funcall(context_obj, rb_intern("at_tracing"), 2, path, lineno);
190
+ call_at_tracing(context_obj, dc, file, line);
144
191
 
145
- if (context->dest_frame == -1 || context->stack_size == context->dest_frame)
192
+ if (moved || !CTX_FL_TEST(dc, CTX_FL_FORCE_MOVE))
146
193
  {
147
- if (moved || !CTX_FL_TEST(context, CTX_FL_FORCE_MOVE))
194
+ dc->steps = dc->steps <= 0 ? -1 : dc->steps - 1;
195
+ if (dc->stack_size <= dc->dest_frame)
148
196
  {
149
- context->steps = context->steps <= 0 ? -1 : context->steps - 1;
150
- context->lines = context->lines <= 0 ? -1 : context->lines - 1;
197
+ dc->lines = dc->lines <= 0 ? -1 : dc->lines - 1;
198
+ dc->dest_frame = dc->stack_size;
151
199
  }
152
200
  }
153
- else if (context->stack_size < context->dest_frame)
154
- {
155
- context->steps = 0;
156
- }
157
201
 
158
- if (context->steps == 0 || context->lines == 0)
159
- {
160
- context->stop_reason = CTX_STOP_STEP;
161
- reset_stepping_stop_points(context);
162
- call_at_line(context, context_obj, path, lineno);
163
- }
164
- else if (CTX_FL_TEST(context, CTX_FL_ENABLE_BKPT))
202
+ if (dc->steps == 0 || dc->lines == 0 ||
203
+ (CTX_FL_TEST(dc, CTX_FL_ENABLE_BKPT) &&
204
+ (!NIL_P(
205
+ breakpoint = find_breakpoint_by_pos(breakpoints, file, line, binding)))))
165
206
  {
166
- breakpoint = find_breakpoint_by_pos(breakpoints, path, lineno, binding);
167
- if (breakpoint != Qnil)
168
- {
169
- context->stop_reason = CTX_STOP_BREAKPOINT;
170
- reset_stepping_stop_points(context);
171
- rb_funcall(context_obj, rb_intern("at_breakpoint"), 1, breakpoint);
172
- call_at_line(context, context_obj, path, lineno);
173
- }
207
+ call_at_line_check(context_obj, dc, breakpoint, file, line);
174
208
  }
175
209
 
176
- cleanup(context);
210
+ cleanup(dc);
177
211
  }
178
212
 
179
213
  static void
180
214
  process_c_return_event(VALUE trace_point, void *data)
181
215
  {
182
216
  EVENT_SETUP;
217
+ if (dc->stack_size > 0) dc->stack_size--;
218
+ EVENT_COMMON();
183
219
 
184
- pop_frame(context);
185
-
186
- cleanup(context);
220
+ cleanup(dc);
187
221
  }
188
222
 
189
223
  static void
190
224
  process_return_event(VALUE trace_point, void *data)
191
225
  {
192
226
  EVENT_SETUP;
227
+ if (dc->stack_size > 0) dc->stack_size--;
228
+ EVENT_COMMON();
193
229
 
194
- if (context->stack_size == context->stop_frame)
230
+ if (dc->stack_size + 1 == dc->stop_frame)
195
231
  {
196
- context->steps = 1;
197
- context->stop_frame = -1;
232
+ dc->steps = 1;
233
+ dc->stop_frame = -1;
198
234
  }
199
- pop_frame(context);
200
235
 
201
- cleanup(context);
236
+ cleanup(dc);
202
237
  }
203
238
 
204
239
  static void
205
240
  process_c_call_event(VALUE trace_point, void *data)
206
241
  {
207
242
  EVENT_SETUP;
243
+ dc->stack_size++;
244
+ EVENT_COMMON();
208
245
 
209
- push_frame(context, RSTRING_PTR(path), FIX2INT(lineno), method_id,
210
- defined_class, binding, self);
211
- cleanup(context);
246
+ cleanup(dc);
212
247
  }
213
248
 
214
249
  static void
215
250
  process_call_event(VALUE trace_point, void *data)
216
251
  {
217
252
  EVENT_SETUP;
218
- VALUE breakpoint;
219
-
220
- push_frame(context, RSTRING_PTR(path), FIX2INT(lineno), method_id,
221
- defined_class, binding, self);
222
-
223
- breakpoint = find_breakpoint_by_method(breakpoints, defined_class,
224
- SYM2ID(method_id),
225
- binding, self);
253
+ dc->stack_size++;
254
+ EVENT_COMMON();
255
+
256
+ VALUE breakpoint = Qnil;
257
+ VALUE klass = rb_tracearg_defined_class(trace_arg);
258
+ VALUE mid = SYM2ID(rb_tracearg_method_id(trace_arg));
259
+ VALUE binding = rb_tracearg_binding(trace_arg);
260
+ VALUE self = rb_tracearg_self(trace_arg);
261
+ VALUE file = rb_tracearg_path(trace_arg);
262
+ VALUE line = rb_tracearg_lineno(trace_arg);
263
+
264
+ breakpoint =
265
+ find_breakpoint_by_method(breakpoints, klass, mid, binding, self);
226
266
  if (breakpoint != Qnil)
227
267
  {
228
- context->stop_reason = CTX_STOP_BREAKPOINT;
229
- rb_funcall(context_obj, rb_intern("at_breakpoint"), 1, breakpoint);
230
- call_at_line(context, context_obj, path, lineno);
268
+ call_at_breakpoint(context_obj, dc, breakpoint);
269
+ call_at_line(context_obj, dc, file, line);
231
270
  }
232
271
 
233
- cleanup(context);
272
+ cleanup(dc);
234
273
  }
235
274
 
236
275
  static void
237
276
  process_raise_event(VALUE trace_point, void *data)
238
277
  {
239
- EVENT_SETUP;
278
+ EVENT_SETUP
240
279
  VALUE expn_class, aclass;
241
280
  VALUE err = rb_errinfo();
242
281
  VALUE ancestors;
243
282
  int i;
283
+ debug_context_t *new_dc;
284
+
285
+ EVENT_COMMON();
244
286
 
245
- update_frame(context->stack, RSTRING_PTR(path), FIX2INT(lineno), method_id,
246
- defined_class, binding, self);
287
+ VALUE binding = rb_tracearg_binding(trace_arg);
288
+ VALUE path = rb_tracearg_path(trace_arg);
289
+ VALUE lineno = rb_tracearg_lineno(trace_arg);
247
290
 
248
- if (post_mortem == Qtrue && self)
291
+ if (post_mortem == Qtrue)
249
292
  {
250
- VALUE binding = rb_binding_new();
251
- rb_ivar_set(rb_errinfo(), rb_intern("@__debug_file"), path);
252
- rb_ivar_set(rb_errinfo(), rb_intern("@__debug_line"), lineno);
253
- rb_ivar_set(rb_errinfo(), rb_intern("@__debug_binding"), binding);
254
- rb_ivar_set(rb_errinfo(), rb_intern("@__debug_context"), Context_dup(context));
293
+ context = context_dup(dc);
294
+ rb_ivar_set(err, rb_intern("@__debug_file") , path);
295
+ rb_ivar_set(err, rb_intern("@__debug_line") , lineno);
296
+ rb_ivar_set(err, rb_intern("@__debug_binding"), binding);
297
+ rb_ivar_set(err, rb_intern("@__debug_context"), context);
298
+
299
+ Data_Get_Struct(context, debug_context_t, new_dc);
300
+ rb_debug_inspector_open(context_backtrace_set, (void *)new_dc);
255
301
  }
256
302
 
257
303
  expn_class = rb_obj_class(err);
258
304
 
259
- if (catchpoints == Qnil || context->stack_size == 0 ||
260
- CTX_FL_TEST(context, CTX_FL_CATCHING) ||
261
- RHASH_TBL(catchpoints)->num_entries == 0) {
262
- cleanup(context);
305
+ if (catchpoints == Qnil || dc->stack_size == 0 ||
306
+ CTX_FL_TEST(dc, CTX_FL_CATCHING) ||
307
+ RHASH_TBL(catchpoints)->num_entries == 0)
308
+ {
309
+ cleanup(dc);
263
310
  return;
264
311
  }
265
312
 
266
313
  ancestors = rb_mod_ancestors(expn_class);
267
- for (i = 0; i < RARRAY_LEN(ancestors); i++) {
314
+ for (i = 0; i < RARRAY_LEN(ancestors); i++)
315
+ {
268
316
  VALUE mod_name;
269
317
  VALUE hit_count;
270
318
 
@@ -272,17 +320,17 @@ process_raise_event(VALUE trace_point, void *data)
272
320
  mod_name = rb_mod_name(aclass);
273
321
  hit_count = rb_hash_aref(catchpoints, mod_name);
274
322
 
275
- if (hit_count != Qnil) {
276
- /* increment exception */
323
+ /* increment exception */
324
+ if (hit_count != Qnil)
325
+ {
277
326
  rb_hash_aset(catchpoints, mod_name, INT2FIX(FIX2INT(hit_count) + 1));
278
- context->stop_reason = CTX_STOP_CATCHPOINT;
279
- rb_funcall(context_obj, rb_intern("at_catchpoint"), 1, rb_errinfo());
280
- call_at_line(context, context_obj, path, lineno);
327
+ call_at_catchpoint(context_obj, dc, err);
328
+ call_at_line(context_obj, dc, path, lineno);
281
329
  break;
282
330
  }
283
331
  }
284
332
 
285
- cleanup(context);
333
+ cleanup(dc);
286
334
  }
287
335
 
288
336
  static VALUE
@@ -330,34 +378,17 @@ Byebug_setup_tracepoints(VALUE self)
330
378
  static VALUE
331
379
  Byebug_remove_tracepoints(VALUE self)
332
380
  {
381
+ rb_tracepoint_disable(tpRaise);
382
+ rb_tracepoint_disable(tpCReturn);
383
+ rb_tracepoint_disable(tpReturn);
384
+ rb_tracepoint_disable(tpCCall);
385
+ rb_tracepoint_disable(tpCall);
386
+ rb_tracepoint_disable(tpLine);
387
+
333
388
  context = Qnil;
334
389
  breakpoints = Qnil;
335
390
  catchpoints = Qnil;
336
391
 
337
- if (tpLine != Qnil) {
338
- rb_tracepoint_disable(tpLine);
339
- tpLine = Qnil;
340
- }
341
- if (tpCall != Qnil) {
342
- rb_tracepoint_disable(tpCall);
343
- tpCall = Qnil;
344
- }
345
- if (tpCCall != Qnil) {
346
- rb_tracepoint_disable(tpCCall);
347
- tpCCall = Qnil;
348
- }
349
- if (tpReturn != Qnil) {
350
- rb_tracepoint_disable(tpReturn);
351
- tpReturn = Qnil;
352
- }
353
- if (tpCReturn != Qnil) {
354
- rb_tracepoint_disable(tpCReturn);
355
- tpCReturn = Qnil;
356
- }
357
- if (tpRaise != Qnil) {
358
- rb_tracepoint_disable(tpRaise);
359
- tpRaise = Qnil;
360
- }
361
392
  return Qnil;
362
393
  }
363
394
 
@@ -371,45 +402,45 @@ Byebug_started(VALUE self)
371
402
  static VALUE
372
403
  Byebug_stop(VALUE self)
373
404
  {
374
- if (BYEBUG_STARTED)
375
- {
376
- Byebug_remove_tracepoints(self);
377
- return Qfalse;
378
- }
379
- return Qtrue;
405
+ if (BYEBUG_STARTED)
406
+ {
407
+ Byebug_remove_tracepoints(self);
408
+ return Qfalse;
409
+ }
410
+ return Qtrue;
380
411
  }
381
412
 
382
413
  static VALUE
383
414
  Byebug_start(VALUE self)
384
415
  {
385
- VALUE result;
416
+ VALUE result;
386
417
 
387
- if (BYEBUG_STARTED)
388
- result = Qfalse;
389
- else
390
- {
391
- Byebug_setup_tracepoints(self);
392
- result = Qtrue;
393
- }
418
+ if (BYEBUG_STARTED)
419
+ result = Qfalse;
420
+ else
421
+ {
422
+ Byebug_setup_tracepoints(self);
423
+ result = Qtrue;
424
+ }
394
425
 
395
- if (rb_block_given_p())
396
- rb_ensure(rb_yield, self, Byebug_stop, self);
426
+ if (rb_block_given_p())
427
+ rb_ensure(rb_yield, self, Byebug_stop, self);
397
428
 
398
- return result;
429
+ return result;
399
430
  }
400
431
 
401
432
  static VALUE
402
433
  set_current_skipped_status(VALUE status)
403
434
  {
404
435
  VALUE context_obj;
405
- debug_context_t *context;
436
+ debug_context_t *dc;
406
437
 
407
438
  context_obj = Byebug_context(mByebug);
408
- Data_Get_Struct(context_obj, debug_context_t, context);
439
+ Data_Get_Struct(context_obj, debug_context_t, dc);
409
440
  if (status)
410
- CTX_FL_SET(context, CTX_FL_SKIPPED);
441
+ CTX_FL_SET(dc, CTX_FL_SKIPPED);
411
442
  else
412
- CTX_FL_UNSET(context, CTX_FL_SKIPPED);
443
+ CTX_FL_UNSET(dc, CTX_FL_SKIPPED);
413
444
  return Qnil;
414
445
  }
415
446
 
@@ -417,7 +448,7 @@ static VALUE
417
448
  Byebug_load(int argc, VALUE *argv, VALUE self)
418
449
  {
419
450
  VALUE file, stop, context_obj;
420
- debug_context_t *context;
451
+ debug_context_t *dc;
421
452
  int state = 0;
422
453
 
423
454
  if (rb_scan_args(argc, argv, "11", &file, &stop) == 1)
@@ -428,9 +459,11 @@ Byebug_load(int argc, VALUE *argv, VALUE self)
428
459
  Byebug_start(self);
429
460
 
430
461
  context_obj = Byebug_context(self);
431
- Data_Get_Struct(context_obj, debug_context_t, context);
432
- context->stack_size = 0;
433
- if (RTEST(stop)) context->steps = 1;
462
+ Data_Get_Struct(context_obj, debug_context_t, dc);
463
+ if (RTEST(stop)) dc->steps = 1;
464
+
465
+ /* Resetting stack size */
466
+ dc->stack_size = 0;
434
467
 
435
468
  /* Initializing $0 to the script's path */
436
469
  ruby_script(RSTRING_PTR(file));
@@ -438,7 +471,7 @@ Byebug_load(int argc, VALUE *argv, VALUE self)
438
471
  if (0 != state)
439
472
  {
440
473
  VALUE errinfo = rb_errinfo();
441
- reset_stepping_stop_points(context);
474
+ reset_stepping_stop_points(dc);
442
475
  rb_set_errinfo(Qnil);
443
476
  return errinfo;
444
477
  }