byebug 3.5.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.rubocop.yml +18 -1
  4. data/.travis.yml +21 -1
  5. data/CHANGELOG.md +356 -308
  6. data/CONTRIBUTING.md +31 -15
  7. data/GUIDE.md +859 -475
  8. data/Gemfile +8 -10
  9. data/LICENSE +1 -1
  10. data/README.md +41 -45
  11. data/Rakefile +30 -28
  12. data/byebug.gemspec +18 -18
  13. data/ext/byebug/breakpoint.c +88 -75
  14. data/ext/byebug/byebug.c +253 -252
  15. data/ext/byebug/byebug.h +53 -53
  16. data/ext/byebug/context.c +188 -159
  17. data/ext/byebug/extconf.rb +9 -6
  18. data/ext/byebug/locker.c +53 -11
  19. data/ext/byebug/threads.c +137 -39
  20. data/lib/byebug/attacher.rb +7 -2
  21. data/lib/byebug/breakpoint.rb +30 -0
  22. data/lib/byebug/command.rb +36 -32
  23. data/lib/byebug/commands/break.rb +49 -48
  24. data/lib/byebug/commands/catch.rb +64 -0
  25. data/lib/byebug/commands/condition.rb +13 -9
  26. data/lib/byebug/commands/continue.rb +8 -4
  27. data/lib/byebug/commands/delete.rb +10 -4
  28. data/lib/byebug/commands/display.rb +33 -25
  29. data/lib/byebug/commands/edit.rb +18 -13
  30. data/lib/byebug/commands/enable_disable.rb +26 -24
  31. data/lib/byebug/commands/eval.rb +77 -35
  32. data/lib/byebug/commands/finish.rb +9 -5
  33. data/lib/byebug/commands/frame.rb +66 -125
  34. data/lib/byebug/commands/help.rb +14 -21
  35. data/lib/byebug/commands/history.rb +5 -1
  36. data/lib/byebug/commands/info.rb +41 -106
  37. data/lib/byebug/commands/interrupt.rb +6 -2
  38. data/lib/byebug/commands/irb.rb +5 -2
  39. data/lib/byebug/commands/kill.rb +6 -2
  40. data/lib/byebug/commands/list.rb +21 -14
  41. data/lib/byebug/commands/method.rb +17 -9
  42. data/lib/byebug/commands/pry.rb +13 -3
  43. data/lib/byebug/commands/quit.rb +10 -5
  44. data/lib/byebug/commands/restart.rb +12 -19
  45. data/lib/byebug/commands/save.rb +10 -6
  46. data/lib/byebug/commands/set.rb +15 -14
  47. data/lib/byebug/commands/show.rb +8 -8
  48. data/lib/byebug/commands/source.rb +14 -8
  49. data/lib/byebug/commands/stepping.rb +15 -29
  50. data/lib/byebug/commands/threads.rb +73 -49
  51. data/lib/byebug/commands/tracevar.rb +56 -0
  52. data/lib/byebug/commands/undisplay.rb +8 -4
  53. data/lib/byebug/commands/untracevar.rb +38 -0
  54. data/lib/byebug/commands/var.rb +107 -0
  55. data/lib/byebug/context.rb +78 -42
  56. data/lib/byebug/core.rb +78 -40
  57. data/lib/byebug/helper.rb +58 -42
  58. data/lib/byebug/history.rb +12 -1
  59. data/lib/byebug/interface.rb +91 -11
  60. data/lib/byebug/interfaces/local_interface.rb +12 -19
  61. data/lib/byebug/interfaces/remote_interface.rb +12 -15
  62. data/lib/byebug/interfaces/script_interface.rb +14 -18
  63. data/lib/byebug/interfaces/test_interface.rb +54 -0
  64. data/lib/byebug/printers/base.rb +64 -0
  65. data/lib/byebug/printers/plain.rb +53 -0
  66. data/lib/byebug/processor.rb +20 -1
  67. data/lib/byebug/processors/command_processor.rb +57 -172
  68. data/lib/byebug/processors/control_command_processor.rb +16 -43
  69. data/lib/byebug/remote.rb +13 -7
  70. data/lib/byebug/runner.rb +102 -54
  71. data/lib/byebug/setting.rb +45 -68
  72. data/lib/byebug/settings/autoeval.rb +2 -0
  73. data/lib/byebug/settings/autoirb.rb +3 -0
  74. data/lib/byebug/settings/autolist.rb +3 -0
  75. data/lib/byebug/settings/autosave.rb +2 -0
  76. data/lib/byebug/settings/basename.rb +2 -0
  77. data/lib/byebug/settings/callstyle.rb +2 -0
  78. data/lib/byebug/settings/fullpath.rb +2 -0
  79. data/lib/byebug/settings/histfile.rb +2 -0
  80. data/lib/byebug/settings/histsize.rb +2 -0
  81. data/lib/byebug/settings/linetrace.rb +2 -0
  82. data/lib/byebug/settings/listsize.rb +2 -0
  83. data/lib/byebug/settings/post_mortem.rb +7 -2
  84. data/lib/byebug/settings/stack_on_error.rb +2 -0
  85. data/lib/byebug/settings/verbose.rb +2 -0
  86. data/lib/byebug/settings/width.rb +2 -0
  87. data/lib/byebug/state.rb +12 -0
  88. data/lib/byebug/states/control_state.rb +26 -0
  89. data/lib/byebug/states/regular_state.rb +178 -0
  90. data/lib/byebug/version.rb +1 -1
  91. metadata +24 -109
  92. data/lib/byebug/commands/catchpoint.rb +0 -53
  93. data/lib/byebug/commands/reload.rb +0 -29
  94. data/lib/byebug/commands/trace.rb +0 -50
  95. data/lib/byebug/commands/variables.rb +0 -206
  96. data/lib/byebug/options.rb +0 -46
  97. data/lib/byebug/settings/autoreload.rb +0 -12
  98. data/lib/byebug/settings/forcestep.rb +0 -14
  99. data/lib/byebug/settings/testing.rb +0 -12
  100. data/lib/byebug/settings/tracing_plus.rb +0 -11
  101. data/test/commands/break_test.rb +0 -364
  102. data/test/commands/condition_test.rb +0 -85
  103. data/test/commands/continue_test.rb +0 -47
  104. data/test/commands/delete_test.rb +0 -26
  105. data/test/commands/display_test.rb +0 -37
  106. data/test/commands/edit_test.rb +0 -52
  107. data/test/commands/eval_test.rb +0 -89
  108. data/test/commands/finish_test.rb +0 -74
  109. data/test/commands/frame_test.rb +0 -223
  110. data/test/commands/help_test.rb +0 -66
  111. data/test/commands/history_test.rb +0 -61
  112. data/test/commands/info_test.rb +0 -238
  113. data/test/commands/interrupt_test.rb +0 -45
  114. data/test/commands/irb_test.rb +0 -28
  115. data/test/commands/kill_test.rb +0 -50
  116. data/test/commands/list_test.rb +0 -174
  117. data/test/commands/method_test.rb +0 -52
  118. data/test/commands/post_mortem_test.rb +0 -71
  119. data/test/commands/pry_test.rb +0 -26
  120. data/test/commands/quit_test.rb +0 -53
  121. data/test/commands/reload_test.rb +0 -39
  122. data/test/commands/restart_test.rb +0 -46
  123. data/test/commands/save_test.rb +0 -67
  124. data/test/commands/set_test.rb +0 -140
  125. data/test/commands/show_test.rb +0 -76
  126. data/test/commands/source_test.rb +0 -46
  127. data/test/commands/stepping_test.rb +0 -192
  128. data/test/commands/thread_test.rb +0 -164
  129. data/test/commands/trace_test.rb +0 -71
  130. data/test/commands/undisplay_test.rb +0 -75
  131. data/test/commands/variables_test.rb +0 -105
  132. data/test/debugger_alias_test.rb +0 -7
  133. data/test/runner_test.rb +0 -150
  134. data/test/support/matchers.rb +0 -65
  135. data/test/support/test_interface.rb +0 -59
  136. data/test/support/utils.rb +0 -122
  137. data/test/test_helper.rb +0 -58
@@ -4,19 +4,21 @@
4
4
  #include <ruby.h>
5
5
  #include <ruby/debug.h>
6
6
 
7
+ /* To prevent unused parameter warnings */
8
+ #define UNUSED(x) (void)(x)
9
+
7
10
  /* flags */
8
11
  #define CTX_FL_DEAD (1<<1) /* this context belonged to a dead thread */
9
- #define CTX_FL_ENABLE_BKPT (1<<2) /* can check for breakpoints */
10
- #define CTX_FL_FORCE_MOVE (1<<3) /* don't stop unless we've changed line */
11
- #define CTX_FL_IGNORE (1<<4) /* this context belongs to ignored thread */
12
- #define CTX_FL_SUSPEND (1<<5) /* thread currently suspended */
13
- #define CTX_FL_TRACING (1<<6) /* call at_tracing method */
14
- #define CTX_FL_WAS_RUNNING (1<<7) /* thread was previously running */
15
- #define CTX_FL_STOP_ON_RET (1<<8) /* can stop on method 'end' */
12
+ #define CTX_FL_IGNORE (1<<2) /* this context belongs to ignored thread */
13
+ #define CTX_FL_SUSPEND (1<<3) /* thread currently suspended */
14
+ #define CTX_FL_TRACING (1<<4) /* call at_tracing method */
15
+ #define CTX_FL_WAS_RUNNING (1<<5) /* thread was previously running */
16
+ #define CTX_FL_STOP_ON_RET (1<<6) /* can stop on method 'end' */
17
+ #define CTX_FL_IGNORE_STEPS (1<<7) /* doesn't countdown steps to break */
16
18
 
17
19
  /* macro functions */
18
- #define CTX_FL_TEST(c,f) ((c)->flags & (f))
19
- #define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0)
20
+ #define CTX_FL_TEST(c,f) ((c)->flags & (f))
21
+ #define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0)
20
22
  #define CTX_FL_UNSET(c,f) do { (c)->flags &= ~(f); } while (0)
21
23
 
22
24
  /* types */
@@ -40,9 +42,6 @@ typedef struct {
40
42
  int steps; /* # of steps before stopping */
41
43
  int steps_out; /* # of returns before stopping */
42
44
 
43
- VALUE last_file;
44
- VALUE last_line;
45
-
46
45
  VALUE backtrace; /* [[loc, self, klass, binding], ...] */
47
46
  } debug_context_t;
48
47
 
@@ -60,23 +59,45 @@ typedef struct {
60
59
  st_table *tbl;
61
60
  } threads_table_t;
62
61
 
62
+ enum bp_type { BP_POS_TYPE, BP_METHOD_TYPE };
63
+
64
+ enum hit_condition { HIT_COND_NONE, HIT_COND_GE, HIT_COND_EQ, HIT_COND_MOD };
65
+
66
+ typedef struct {
67
+ int id;
68
+ enum bp_type type;
69
+ VALUE source;
70
+ union
71
+ {
72
+ int line;
73
+ ID mid;
74
+ } pos;
75
+ VALUE expr;
76
+ VALUE enabled;
77
+ int hit_count;
78
+ int hit_value;
79
+ enum hit_condition hit_condition;
80
+ } breakpoint_t;
81
+
63
82
  /* functions from locker.c */
64
83
  extern int is_in_locked(VALUE thread_id);
65
84
  extern void add_to_locked(VALUE thread);
66
- extern VALUE remove_from_locked();
85
+ extern VALUE pop_from_locked();
86
+ extern void remove_from_locked(VALUE thread);
67
87
 
68
88
  /* functions from threads.c */
69
89
  extern void Init_threads_table(VALUE mByebug);
70
90
  extern VALUE create_threads_table(void);
71
- extern void check_threads_table(void);
72
91
  extern void thread_context_lookup(VALUE thread, VALUE *context);
73
- extern void halt_while_other_thread_is_active(debug_context_t *dc);
92
+ extern int is_living_thread(VALUE thread);
93
+ extern void acquire_lock(debug_context_t *dc);
94
+ extern void release_lock(void);
74
95
 
75
96
  /* global variables */
76
- extern VALUE locker;
77
97
  extern VALUE threads;
98
+ extern VALUE next_thread;
78
99
 
79
- /* functions */
100
+ /* functions from context.c */
80
101
  extern void Init_context(VALUE mByebug);
81
102
  extern VALUE context_create(VALUE thread);
82
103
  extern VALUE context_dup(debug_context_t *context);
@@ -85,42 +106,21 @@ extern VALUE call_with_debug_inspector(struct call_with_inspection_data *data);
85
106
  extern VALUE context_backtrace_set(const rb_debug_inspector_t *inspector,
86
107
  void *data);
87
108
 
88
- static inline int
89
- classname_cmp(VALUE name, VALUE klass)
90
- {
91
- VALUE mod_name;
92
- VALUE class_name = (Qnil == name) ? rb_str_new2("main") : name;
93
- if (klass == Qnil) return(0);
94
- mod_name = rb_mod_name(klass);
95
- return (mod_name != Qnil && rb_str_cmp(class_name, mod_name) == 0);
96
- }
97
-
98
- /* breakpoints & catchpoints */
99
- enum bp_type { BP_POS_TYPE, BP_METHOD_TYPE };
100
-
101
- enum hit_condition { HIT_COND_NONE, HIT_COND_GE, HIT_COND_EQ, HIT_COND_MOD };
102
-
103
- typedef struct {
104
- int id;
105
- enum bp_type type;
106
- VALUE source;
107
- union
108
- {
109
- int line;
110
- ID mid;
111
- } pos;
112
- VALUE expr;
113
- VALUE enabled;
114
- int hit_count;
115
- int hit_value;
116
- enum hit_condition hit_condition;
117
- } breakpoint_t;
118
-
109
+ /* functions from breakpoint.c */
119
110
  extern void Init_breakpoint(VALUE mByebug);
120
- extern VALUE catchpoint_hit_count(VALUE catchpoints, VALUE exception, VALUE *exception_name);
121
- extern VALUE find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos,
122
- VALUE binding);
123
- extern VALUE find_breakpoint_by_method(VALUE breakpoints, VALUE klass,
124
- VALUE mid, VALUE binding, VALUE self);
111
+ extern VALUE catchpoint_hit_count(VALUE catchpoints,
112
+ VALUE exception,
113
+ VALUE *exception_name);
114
+
115
+ extern VALUE find_breakpoint_by_pos(VALUE breakpoints,
116
+ VALUE source,
117
+ VALUE pos,
118
+ VALUE bind);
119
+
120
+ extern VALUE find_breakpoint_by_method(VALUE breakpoints,
121
+ VALUE klass,
122
+ VALUE mid,
123
+ VALUE bind,
124
+ VALUE self);
125
125
 
126
126
  #endif
@@ -7,12 +7,12 @@ static int thnum_max = 0;
7
7
  /* "Step", "Next" and "Finish" do their work by saving information about where
8
8
  * to stop next. reset_stepping_stop_points removes/resets this information. */
9
9
  extern void
10
- reset_stepping_stop_points(debug_context_t *context)
10
+ reset_stepping_stop_points(debug_context_t * context)
11
11
  {
12
- context->dest_frame = -1;
13
- context->lines = -1;
14
- context->steps = -1;
15
- context->steps_out = -1;
12
+ context->dest_frame = -1;
13
+ context->lines = -1;
14
+ context->steps = -1;
15
+ context->steps_out = -1;
16
16
  }
17
17
 
18
18
  /*
@@ -26,6 +26,7 @@ static inline VALUE
26
26
  Context_dead(VALUE self)
27
27
  {
28
28
  debug_context_t *context;
29
+
29
30
  Data_Get_Struct(self, debug_context_t, context);
30
31
  return CTX_FL_TEST(context, CTX_FL_DEAD) ? Qtrue : Qfalse;
31
32
  }
@@ -33,14 +34,25 @@ Context_dead(VALUE self)
33
34
  static void
34
35
  context_mark(void *data)
35
36
  {
36
- debug_context_t *context = (debug_context_t *)data;
37
+ debug_context_t *context = (debug_context_t *) data;
38
+
37
39
  rb_gc_mark(context->backtrace);
38
40
  }
39
41
 
42
+ static VALUE
43
+ dc_backtrace(const debug_context_t * context)
44
+ {
45
+ return context->backtrace;
46
+ }
47
+
40
48
  static int
41
- real_stack_size()
49
+ dc_stack_size(debug_context_t * context)
42
50
  {
43
- return FIX2INT(rb_funcall(cContext, rb_intern("stack_size"), 0));
51
+
52
+ if (NIL_P(dc_backtrace(context)))
53
+ return 0;
54
+
55
+ return RARRAY_LENINT(dc_backtrace(context));
44
56
  }
45
57
 
46
58
  extern VALUE
@@ -48,23 +60,23 @@ context_create(VALUE thread)
48
60
  {
49
61
  debug_context_t *context = ALLOC(debug_context_t);
50
62
 
51
- context->last_file = Qnil;
52
- context->last_line = Qnil;
53
- context->flags = 0;
54
- context->calced_stack_size = real_stack_size();
55
- context->thnum = ++thnum_max;
56
- context->thread = thread;
63
+ context->flags = 0;
64
+ context->thnum = ++thnum_max;
65
+ context->thread = thread;
57
66
  reset_stepping_stop_points(context);
58
- context->stop_reason = CTX_STOP_NONE;
59
- context->backtrace = Qnil;
67
+ context->stop_reason = CTX_STOP_NONE;
68
+
69
+ rb_debug_inspector_open(context_backtrace_set, (void *)context);
70
+ context->calced_stack_size = dc_stack_size(context) + 1;
60
71
 
61
- if (rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE);
72
+ if (rb_obj_class(thread) == cDebugThread)
73
+ CTX_FL_SET(context, CTX_FL_IGNORE);
62
74
 
63
75
  return Data_Wrap_Struct(cContext, context_mark, 0, context);
64
76
  }
65
77
 
66
78
  extern VALUE
67
- context_dup(debug_context_t *context)
79
+ context_dup(debug_context_t * context)
68
80
  {
69
81
  debug_context_t *new_context = ALLOC(debug_context_t);
70
82
 
@@ -76,15 +88,10 @@ context_dup(debug_context_t *context)
76
88
  return Data_Wrap_Struct(cContext, context_mark, 0, new_context);
77
89
  }
78
90
 
79
- static VALUE
80
- dc_backtrace(const debug_context_t *context)
81
- {
82
- return context->backtrace;
83
- }
84
91
 
85
92
  static VALUE
86
- dc_frame_get(const debug_context_t *context, int frame_index,
87
- enum frame_component type)
93
+ dc_frame_get(const debug_context_t * context, int frame_index,
94
+ enum frame_component type)
88
95
  {
89
96
  VALUE frame;
90
97
 
@@ -99,39 +106,40 @@ dc_frame_get(const debug_context_t *context, int frame_index,
99
106
  }
100
107
 
101
108
  static VALUE
102
- dc_frame_location(const debug_context_t *context, int frame_index)
109
+ dc_frame_location(const debug_context_t * context, int frame_index)
103
110
  {
104
111
  return dc_frame_get(context, frame_index, LOCATION);
105
112
  }
106
113
 
107
114
  static VALUE
108
- dc_frame_self(const debug_context_t *context, int frame_index)
115
+ dc_frame_self(const debug_context_t * context, int frame_index)
109
116
  {
110
117
  return dc_frame_get(context, frame_index, SELF);
111
118
  }
112
119
 
113
120
  static VALUE
114
- dc_frame_class(const debug_context_t *context, int frame_index)
121
+ dc_frame_class(const debug_context_t * context, int frame_index)
115
122
  {
116
123
  return dc_frame_get(context, frame_index, CLASS);
117
124
  }
118
125
 
119
126
  static VALUE
120
- dc_frame_binding(const debug_context_t *context, int frame_index)
127
+ dc_frame_binding(const debug_context_t * context, int frame_index)
121
128
  {
122
129
  return dc_frame_get(context, frame_index, BINDING);
123
130
  }
124
131
 
125
132
  static VALUE
126
- load_backtrace(const rb_debug_inspector_t *inspector)
133
+ load_backtrace(const rb_debug_inspector_t * inspector)
127
134
  {
128
135
  VALUE backtrace = rb_ary_new();
129
136
  VALUE locs = rb_debug_inspector_backtrace_locations(inspector);
130
137
  int i;
131
138
 
132
- for (i=0; i<RARRAY_LENINT(locs); i++)
139
+ for (i = 0; i < RARRAY_LENINT(locs); i++)
133
140
  {
134
141
  VALUE frame = rb_ary_new();
142
+
135
143
  rb_ary_push(frame, rb_ary_entry(locs, i));
136
144
  rb_ary_push(frame, rb_debug_inspector_frame_self_get(inspector, i));
137
145
  rb_ary_push(frame, rb_debug_inspector_frame_class_get(inspector, i));
@@ -144,19 +152,21 @@ load_backtrace(const rb_debug_inspector_t *inspector)
144
152
  }
145
153
 
146
154
  extern VALUE
147
- context_backtrace_set(const rb_debug_inspector_t *inspector, void *data)
155
+ context_backtrace_set(const rb_debug_inspector_t * inspector, void *data)
148
156
  {
149
- debug_context_t *dc = (debug_context_t *)data;
157
+ debug_context_t *dc = (debug_context_t *) data;
158
+
150
159
  dc->backtrace = load_backtrace(inspector);
151
160
 
152
161
  return Qnil;
153
162
  }
154
163
 
155
164
  static VALUE
156
- open_debug_inspector_i(const rb_debug_inspector_t *inspector, void *data)
165
+ open_debug_inspector_i(const rb_debug_inspector_t * inspector, void *data)
157
166
  {
158
167
  struct call_with_inspection_data *cwi =
159
168
  (struct call_with_inspection_data *)data;
169
+
160
170
  cwi->dc->backtrace = load_backtrace(inspector);
161
171
 
162
172
  return rb_funcall2(cwi->context_obj, cwi->id, cwi->argc, cwi->argv);
@@ -178,8 +188,8 @@ close_debug_inspector(struct call_with_inspection_data *cwi)
178
188
  extern VALUE
179
189
  call_with_debug_inspector(struct call_with_inspection_data *data)
180
190
  {
181
- return rb_ensure(open_debug_inspector, (VALUE)data,
182
- close_debug_inspector, (VALUE)data);
191
+ return rb_ensure(open_debug_inspector, (VALUE) data, close_debug_inspector,
192
+ (VALUE) data);
183
193
  }
184
194
 
185
195
  #define FRAME_SETUP \
@@ -199,9 +209,9 @@ call_with_debug_inspector(struct call_with_inspection_data *data)
199
209
  * Returns frame's binding.
200
210
  */
201
211
  static VALUE
202
- Context_frame_binding(int argc, VALUE *argv, VALUE self)
212
+ Context_frame_binding(int argc, VALUE * argv, VALUE self)
203
213
  {
204
- FRAME_SETUP
214
+ FRAME_SETUP;
205
215
 
206
216
  return dc_frame_binding(context, frame_n);
207
217
  }
@@ -213,9 +223,9 @@ Context_frame_binding(int argc, VALUE *argv, VALUE self)
213
223
  * Returns frame's defined class.
214
224
  */
215
225
  static VALUE
216
- Context_frame_class(int argc, VALUE *argv, VALUE self)
226
+ Context_frame_class(int argc, VALUE * argv, VALUE self)
217
227
  {
218
- FRAME_SETUP
228
+ FRAME_SETUP;
219
229
 
220
230
  return dc_frame_class(context, frame_n);
221
231
  }
@@ -227,29 +237,34 @@ Context_frame_class(int argc, VALUE *argv, VALUE self)
227
237
  * Returns the name of the file in the frame.
228
238
  */
229
239
  static VALUE
230
- Context_frame_file(int argc, VALUE *argv, VALUE self)
240
+ Context_frame_file(int argc, VALUE * argv, VALUE self)
231
241
  {
232
- VALUE loc;
242
+ VALUE loc, absolute_path;
233
243
 
234
- FRAME_SETUP
244
+ FRAME_SETUP;
235
245
 
236
246
  loc = dc_frame_location(context, frame_n);
237
247
 
248
+ absolute_path = rb_funcall(loc, rb_intern("absolute_path"), 0);
249
+
250
+ if (!NIL_P(absolute_path))
251
+ return absolute_path;
252
+
238
253
  return rb_funcall(loc, rb_intern("path"), 0);
239
254
  }
240
255
 
241
256
  /*
242
257
  * call-seq:
243
- * context.frame_line(frame_position) -> int
258
+ * context.frame_line(frame_position = 0) -> int
244
259
  *
245
260
  * Returns the line number in the file.
246
261
  */
247
262
  static VALUE
248
- Context_frame_line(int argc, VALUE *argv, VALUE self)
263
+ Context_frame_line(int argc, VALUE * argv, VALUE self)
249
264
  {
250
265
  VALUE loc;
251
266
 
252
- FRAME_SETUP
267
+ FRAME_SETUP;
253
268
 
254
269
  loc = dc_frame_location(context, frame_n);
255
270
 
@@ -258,16 +273,16 @@ Context_frame_line(int argc, VALUE *argv, VALUE self)
258
273
 
259
274
  /*
260
275
  * call-seq:
261
- * context.frame_method(frame_position=0) -> sym
276
+ * context.frame_method(frame_position = 0) -> sym
262
277
  *
263
278
  * Returns the sym of the called method.
264
279
  */
265
280
  static VALUE
266
- Context_frame_method(int argc, VALUE *argv, VALUE self)
281
+ Context_frame_method(int argc, VALUE * argv, VALUE self)
267
282
  {
268
283
  VALUE loc;
269
284
 
270
- FRAME_SETUP
285
+ FRAME_SETUP;
271
286
 
272
287
  loc = dc_frame_location(context, frame_n);
273
288
 
@@ -276,14 +291,14 @@ Context_frame_method(int argc, VALUE *argv, VALUE self)
276
291
 
277
292
  /*
278
293
  * call-seq:
279
- * context.frame_self(frame_postion=0) -> obj
294
+ * context.frame_self(frame_postion = 0) -> obj
280
295
  *
281
296
  * Returns self object of the frame.
282
297
  */
283
298
  static VALUE
284
- Context_frame_self(int argc, VALUE *argv, VALUE self)
299
+ Context_frame_self(int argc, VALUE * argv, VALUE self)
285
300
  {
286
- FRAME_SETUP
301
+ FRAME_SETUP;
287
302
 
288
303
  return dc_frame_self(context, frame_n);
289
304
  }
@@ -299,21 +314,11 @@ static inline VALUE
299
314
  Context_ignored(VALUE self)
300
315
  {
301
316
  debug_context_t *context;
317
+
302
318
  Data_Get_Struct(self, debug_context_t, context);
303
319
  return CTX_FL_TEST(context, CTX_FL_IGNORE) ? Qtrue : Qfalse;
304
320
  }
305
321
 
306
- static void
307
- context_resume_0(debug_context_t *context)
308
- {
309
- if (!CTX_FL_TEST(context, CTX_FL_SUSPEND)) return;
310
-
311
- CTX_FL_UNSET(context, CTX_FL_SUSPEND);
312
-
313
- if (CTX_FL_TEST(context, CTX_FL_WAS_RUNNING))
314
- rb_thread_wakeup(context->thread);
315
- }
316
-
317
322
  /*
318
323
  * call-seq:
319
324
  * context.resume -> nil
@@ -323,34 +328,35 @@ context_resume_0(debug_context_t *context)
323
328
  static VALUE
324
329
  Context_resume(VALUE self)
325
330
  {
326
- debug_context_t *context;
331
+ debug_context_t *context;
327
332
 
328
- Data_Get_Struct(self, debug_context_t, context);
333
+ Data_Get_Struct(self, debug_context_t, context);
329
334
 
330
- if (!CTX_FL_TEST(context, CTX_FL_SUSPEND))
331
- rb_raise(rb_eRuntimeError, "Thread is not suspended.");
335
+ if (!CTX_FL_TEST(context, CTX_FL_SUSPEND))
336
+ return Qnil;
332
337
 
333
- context_resume_0(context);
338
+ CTX_FL_UNSET(context, CTX_FL_SUSPEND);
334
339
 
335
- return Qnil;
340
+ if (CTX_FL_TEST(context, CTX_FL_WAS_RUNNING))
341
+ rb_thread_wakeup(context->thread);
342
+
343
+ return Qnil;
336
344
  }
337
345
 
338
346
  /*
339
347
  * call-seq:
340
- * context.calced_stack_size-> int
348
+ * context.backtrace-> int
341
349
  *
342
- * Returns the calculated size of the context stack.
343
- *
344
- * NOTE: it shouldn't be necessary to expose this, this is only done to ease
345
- * the detection of TracePoint API bugs.
350
+ * Returns the frame stack of a context.
346
351
  */
347
352
  static inline VALUE
348
- Context_calced_stack_size(VALUE self)
353
+ Context_backtrace(VALUE self)
349
354
  {
350
355
  debug_context_t *context;
356
+
351
357
  Data_Get_Struct(self, debug_context_t, context);
352
358
 
353
- return INT2FIX(context->calced_stack_size);
359
+ return dc_backtrace(context);
354
360
  }
355
361
 
356
362
  static VALUE
@@ -363,49 +369,59 @@ Context_stop_reason(VALUE self)
363
369
 
364
370
  if (CTX_FL_TEST(context, CTX_FL_DEAD))
365
371
  symbol = "post-mortem";
366
- else switch (context->stop_reason)
367
- {
368
- case CTX_STOP_STEP:
369
- symbol = "step";
370
- break;
371
- case CTX_STOP_BREAKPOINT:
372
- symbol = "breakpoint";
373
- break;
374
- case CTX_STOP_CATCHPOINT:
375
- symbol = "catchpoint";
376
- break;
377
- case CTX_STOP_NONE:
378
- default:
379
- symbol = "none";
380
- }
372
+ else
373
+ switch (context->stop_reason)
374
+ {
375
+ case CTX_STOP_STEP:
376
+ symbol = "step";
377
+ break;
378
+ case CTX_STOP_BREAKPOINT:
379
+ symbol = "breakpoint";
380
+ break;
381
+ case CTX_STOP_CATCHPOINT:
382
+ symbol = "catchpoint";
383
+ break;
384
+ case CTX_STOP_NONE:
385
+ default:
386
+ symbol = "none";
387
+ }
381
388
  return ID2SYM(rb_intern(symbol));
382
389
  }
383
390
 
384
391
  /*
385
392
  * call-seq:
386
- * context.step_into(steps, force = false)
393
+ * context.step_into(steps, frame = 0)
387
394
  *
388
- * Stops the current context after a number of +steps+ are made.
389
- * +force+ parameter (if true) ensures that the cursor moves away from the
390
- * current line.
395
+ * Stops the current context after a number of +steps+ are made from frame
396
+ * +frame+ (by default the newest one).
391
397
  */
392
398
  static VALUE
393
- Context_step_into(int argc, VALUE *argv, VALUE self)
399
+ Context_step_into(int argc, VALUE * argv, VALUE self)
394
400
  {
395
- VALUE steps, force;
401
+ VALUE steps, v_frame;
402
+ int n_args, from_frame;
396
403
  debug_context_t *context;
397
404
 
398
- rb_scan_args(argc, argv, "11", &steps, &force);
399
- if (FIX2INT(steps) < 0)
405
+ Data_Get_Struct(self, debug_context_t, context);
406
+
407
+ if (context->calced_stack_size == 0)
408
+ rb_raise(rb_eRuntimeError, "No frames collected.");
409
+
410
+ n_args = rb_scan_args(argc, argv, "11", &steps, &v_frame);
411
+
412
+ if (FIX2INT(steps) <= 0)
400
413
  rb_raise(rb_eRuntimeError, "Steps argument can't be negative.");
401
414
 
402
- Data_Get_Struct(self, debug_context_t, context);
403
- context->steps = FIX2INT(steps);
415
+ from_frame = n_args == 1 ? 0 : FIX2INT(v_frame);
404
416
 
405
- if (RTEST(force))
406
- CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
407
- else
408
- CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
417
+ if (from_frame < 0 || from_frame >= context->calced_stack_size)
418
+ rb_raise(rb_eRuntimeError, "Destination frame (%d) is out of range (%d)",
419
+ from_frame, context->calced_stack_size);
420
+ else if (from_frame > 0)
421
+ CTX_FL_SET(context, CTX_FL_IGNORE_STEPS);
422
+
423
+ context->steps = FIX2INT(steps);
424
+ context->dest_frame = context->calced_stack_size - from_frame;
409
425
 
410
426
  return steps;
411
427
  }
@@ -420,7 +436,7 @@ Context_step_into(int argc, VALUE *argv, VALUE self)
420
436
  * event for that frame is triggered.
421
437
  */
422
438
  static VALUE
423
- Context_step_out(int argc, VALUE *argv, VALUE self)
439
+ Context_step_out(int argc, VALUE * argv, VALUE self)
424
440
  {
425
441
  int n_args, n_frames;
426
442
  VALUE v_frames, force;
@@ -433,7 +449,7 @@ Context_step_out(int argc, VALUE *argv, VALUE self)
433
449
 
434
450
  if (n_frames < 0 || n_frames > context->calced_stack_size)
435
451
  rb_raise(rb_eRuntimeError,
436
- "You wan't to finish %d frames, but stack size is only %d",
452
+ "You want to finish %d frames, but stack size is only %d",
437
453
  n_frames, context->calced_stack_size);
438
454
 
439
455
  context->steps_out = n_frames;
@@ -447,18 +463,16 @@ Context_step_out(int argc, VALUE *argv, VALUE self)
447
463
 
448
464
  /*
449
465
  * call-seq:
450
- * context.step_over(lines, frame = 0, force = false)
466
+ * context.step_over(lines, frame = 0)
451
467
  *
452
- * Steps over +lines+ lines.
453
- * Make step over operation on +frame+, by default the newest frame.
454
- * +force+ parameter (if true) ensures that the cursor moves away from the
455
- * current line.
468
+ * Steps over +lines+ lines in frame +frame+ (by default the newest one) or
469
+ * higher (if frame +frame+ finishes).
456
470
  */
457
471
  static VALUE
458
- Context_step_over(int argc, VALUE *argv, VALUE self)
472
+ Context_step_over(int argc, VALUE * argv, VALUE self)
459
473
  {
460
474
  int n_args, frame;
461
- VALUE lines, v_frame, force;
475
+ VALUE lines, v_frame;
462
476
  debug_context_t *context;
463
477
 
464
478
  Data_Get_Struct(self, debug_context_t, context);
@@ -466,56 +480,66 @@ Context_step_over(int argc, VALUE *argv, VALUE self)
466
480
  if (context->calced_stack_size == 0)
467
481
  rb_raise(rb_eRuntimeError, "No frames collected.");
468
482
 
469
- n_args = rb_scan_args(argc, argv, "12", &lines, &v_frame, &force);
483
+ n_args = rb_scan_args(argc, argv, "11", &lines, &v_frame);
470
484
  frame = n_args == 1 ? 0 : FIX2INT(v_frame);
471
485
 
472
486
  if (frame < 0 || frame >= context->calced_stack_size)
473
- rb_raise(rb_eRuntimeError,
474
- "Destination frame (%d) is out of range (%d)",
487
+ rb_raise(rb_eRuntimeError, "Destination frame (%d) is out of range (%d)",
475
488
  frame, context->calced_stack_size);
476
489
 
477
490
  context->lines = FIX2INT(lines);
478
491
  context->dest_frame = context->calced_stack_size - frame;
479
492
 
480
- if (n_args == 3 && RTEST(force))
481
- CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
482
- else
483
- CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
484
-
485
493
  return Qnil;
486
494
  }
487
495
 
488
- static void
489
- context_suspend_0(debug_context_t *context)
496
+ /*
497
+ * call-seq:
498
+ * context.suspend -> nil
499
+ *
500
+ * Suspends the thread when it is running.
501
+ */
502
+ static VALUE
503
+ Context_suspend(VALUE self)
490
504
  {
491
- VALUE status = rb_funcall(context->thread, rb_intern("status"), 0);
505
+ VALUE status;
506
+ debug_context_t *context;
507
+
508
+ Data_Get_Struct(self, debug_context_t, context);
509
+
510
+ status = rb_funcall(context->thread, rb_intern("status"), 0);
492
511
 
493
512
  if (rb_str_cmp(status, rb_str_new2("run")) == 0)
494
513
  CTX_FL_SET(context, CTX_FL_WAS_RUNNING);
495
514
  else if (rb_str_cmp(status, rb_str_new2("sleep")) == 0)
496
515
  CTX_FL_UNSET(context, CTX_FL_WAS_RUNNING);
497
516
  else
498
- return;
517
+ return Qnil;
499
518
 
500
519
  CTX_FL_SET(context, CTX_FL_SUSPEND);
520
+
521
+ return Qnil;
501
522
  }
502
523
 
503
524
  /*
504
525
  * call-seq:
505
- * context.suspend -> nil
526
+ * context.switch -> nil
506
527
  *
507
- * Suspends the thread when it is running.
528
+ * Switches execution to this context.
508
529
  */
509
530
  static VALUE
510
- Context_suspend(VALUE self)
531
+ Context_switch(VALUE self)
511
532
  {
512
533
  debug_context_t *context;
534
+
513
535
  Data_Get_Struct(self, debug_context_t, context);
514
536
 
515
- if (CTX_FL_TEST(context, CTX_FL_SUSPEND))
516
- rb_raise(rb_eRuntimeError, "Already suspended.");
537
+ next_thread = context->thread;
538
+
539
+ context->steps = 1;
540
+ context->steps_out = 0;
541
+ CTX_FL_SET(context, CTX_FL_STOP_ON_RET);
517
542
 
518
- context_suspend_0(context);
519
543
  return Qnil;
520
544
  }
521
545
 
@@ -529,6 +553,7 @@ static VALUE
529
553
  Context_is_suspended(VALUE self)
530
554
  {
531
555
  debug_context_t *context;
556
+
532
557
  Data_Get_Struct(self, debug_context_t, context);
533
558
 
534
559
  return CTX_FL_TEST(context, CTX_FL_SUSPEND) ? Qtrue : Qfalse;
@@ -541,8 +566,10 @@ Context_is_suspended(VALUE self)
541
566
  * Returns the context's number.
542
567
  */
543
568
  static inline VALUE
544
- Context_thnum(VALUE self) {
569
+ Context_thnum(VALUE self)
570
+ {
545
571
  debug_context_t *context;
572
+
546
573
  Data_Get_Struct(self, debug_context_t, context);
547
574
  return INT2FIX(context->thnum);
548
575
  }
@@ -557,6 +584,7 @@ static inline VALUE
557
584
  Context_thread(VALUE self)
558
585
  {
559
586
  debug_context_t *context;
587
+
560
588
  Data_Get_Struct(self, debug_context_t, context);
561
589
  return context->thread;
562
590
  }
@@ -590,15 +618,15 @@ Context_set_tracing(VALUE self, VALUE value)
590
618
  Data_Get_Struct(self, debug_context_t, context);
591
619
 
592
620
  if (RTEST(value))
593
- CTX_FL_SET(context, CTX_FL_TRACING);
621
+ CTX_FL_SET(context, CTX_FL_TRACING);
594
622
  else
595
- CTX_FL_UNSET(context, CTX_FL_TRACING);
623
+ CTX_FL_UNSET(context, CTX_FL_TRACING);
596
624
  return value;
597
625
  }
598
626
 
599
627
  /* :nodoc: */
600
628
  static VALUE
601
- DebugThread_inherited(VALUE klass)
629
+ dt_inherited(VALUE klass)
602
630
  {
603
631
  rb_raise(rb_eRuntimeError, "Can't inherit Byebug::DebugThread class");
604
632
 
@@ -617,27 +645,28 @@ Init_context(VALUE mByebug)
617
645
  {
618
646
  cContext = rb_define_class_under(mByebug, "Context", rb_cObject);
619
647
 
620
- rb_define_method(cContext, "dead?" , Context_dead , 0);
621
- rb_define_method(cContext, "frame_binding" , Context_frame_binding , -1);
622
- rb_define_method(cContext, "frame_class" , Context_frame_class , -1);
623
- rb_define_method(cContext, "frame_file" , Context_frame_file , -1);
624
- rb_define_method(cContext, "frame_line" , Context_frame_line , -1);
625
- rb_define_method(cContext, "frame_method" , Context_frame_method , -1);
626
- rb_define_method(cContext, "frame_self" , Context_frame_self , -1);
627
- rb_define_method(cContext, "ignored?" , Context_ignored , 0);
628
- rb_define_method(cContext, "resume" , Context_resume , 0);
629
- rb_define_method(cContext, "calced_stack_size", Context_calced_stack_size, 0);
630
- rb_define_method(cContext, "step_into" , Context_step_into , -1);
631
- rb_define_method(cContext, "step_out" , Context_step_out , -1);
632
- rb_define_method(cContext, "step_over" , Context_step_over , -1);
633
- rb_define_method(cContext, "stop_reason" , Context_stop_reason , 0);
634
- rb_define_method(cContext, "suspend" , Context_suspend , 0);
635
- rb_define_method(cContext, "suspended?" , Context_is_suspended , 0);
636
- rb_define_method(cContext, "thnum" , Context_thnum , 0);
637
- rb_define_method(cContext, "thread" , Context_thread , 0);
638
- rb_define_method(cContext, "tracing" , Context_tracing , 0);
639
- rb_define_method(cContext, "tracing=" , Context_set_tracing , 1);
640
-
641
- cDebugThread = rb_define_class_under(mByebug, "DebugThread", rb_cThread);
642
- rb_define_singleton_method(cDebugThread, "inherited", DebugThread_inherited, 1);
648
+ rb_define_method(cContext, "backtrace", Context_backtrace, 0);
649
+ rb_define_method(cContext, "dead?", Context_dead, 0);
650
+ rb_define_method(cContext, "frame_binding", Context_frame_binding, -1);
651
+ rb_define_method(cContext, "frame_class", Context_frame_class, -1);
652
+ rb_define_method(cContext, "frame_file", Context_frame_file, -1);
653
+ rb_define_method(cContext, "frame_line", Context_frame_line, -1);
654
+ rb_define_method(cContext, "frame_method", Context_frame_method, -1);
655
+ rb_define_method(cContext, "frame_self", Context_frame_self, -1);
656
+ rb_define_method(cContext, "ignored?", Context_ignored, 0);
657
+ rb_define_method(cContext, "resume", Context_resume, 0);
658
+ rb_define_method(cContext, "step_into", Context_step_into, -1);
659
+ rb_define_method(cContext, "step_out", Context_step_out, -1);
660
+ rb_define_method(cContext, "step_over", Context_step_over, -1);
661
+ rb_define_method(cContext, "stop_reason", Context_stop_reason, 0);
662
+ rb_define_method(cContext, "suspend", Context_suspend, 0);
663
+ rb_define_method(cContext, "suspended?", Context_is_suspended, 0);
664
+ rb_define_method(cContext, "switch", Context_switch, 0);
665
+ rb_define_method(cContext, "thnum", Context_thnum, 0);
666
+ rb_define_method(cContext, "thread", Context_thread, 0);
667
+ rb_define_method(cContext, "tracing", Context_tracing, 0);
668
+ rb_define_method(cContext, "tracing=", Context_set_tracing, 1);
669
+
670
+ cDebugThread = rb_define_class_under(mByebug, "DebugThread", rb_cThread);
671
+ rb_define_singleton_method(cDebugThread, "inherited", dt_inherited, 1);
643
672
  }