byebug 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }