byebug 3.5.1 → 4.0.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 +4 -4
- data/.gitignore +4 -1
- data/.rubocop.yml +18 -1
- data/.travis.yml +21 -1
- data/CHANGELOG.md +356 -308
- data/CONTRIBUTING.md +31 -15
- data/GUIDE.md +859 -475
- data/Gemfile +8 -10
- data/LICENSE +1 -1
- data/README.md +41 -45
- data/Rakefile +30 -28
- data/byebug.gemspec +18 -18
- data/ext/byebug/breakpoint.c +88 -75
- data/ext/byebug/byebug.c +253 -252
- data/ext/byebug/byebug.h +53 -53
- data/ext/byebug/context.c +188 -159
- data/ext/byebug/extconf.rb +9 -6
- data/ext/byebug/locker.c +53 -11
- data/ext/byebug/threads.c +137 -39
- data/lib/byebug/attacher.rb +7 -2
- data/lib/byebug/breakpoint.rb +30 -0
- data/lib/byebug/command.rb +36 -32
- data/lib/byebug/commands/break.rb +49 -48
- data/lib/byebug/commands/catch.rb +64 -0
- data/lib/byebug/commands/condition.rb +13 -9
- data/lib/byebug/commands/continue.rb +8 -4
- data/lib/byebug/commands/delete.rb +10 -4
- data/lib/byebug/commands/display.rb +33 -25
- data/lib/byebug/commands/edit.rb +18 -13
- data/lib/byebug/commands/enable_disable.rb +26 -24
- data/lib/byebug/commands/eval.rb +77 -35
- data/lib/byebug/commands/finish.rb +9 -5
- data/lib/byebug/commands/frame.rb +66 -125
- data/lib/byebug/commands/help.rb +14 -21
- data/lib/byebug/commands/history.rb +5 -1
- data/lib/byebug/commands/info.rb +41 -106
- data/lib/byebug/commands/interrupt.rb +6 -2
- data/lib/byebug/commands/irb.rb +5 -2
- data/lib/byebug/commands/kill.rb +6 -2
- data/lib/byebug/commands/list.rb +21 -14
- data/lib/byebug/commands/method.rb +17 -9
- data/lib/byebug/commands/pry.rb +13 -3
- data/lib/byebug/commands/quit.rb +10 -5
- data/lib/byebug/commands/restart.rb +12 -19
- data/lib/byebug/commands/save.rb +10 -6
- data/lib/byebug/commands/set.rb +15 -14
- data/lib/byebug/commands/show.rb +8 -8
- data/lib/byebug/commands/source.rb +14 -8
- data/lib/byebug/commands/stepping.rb +15 -29
- data/lib/byebug/commands/threads.rb +73 -49
- data/lib/byebug/commands/tracevar.rb +56 -0
- data/lib/byebug/commands/undisplay.rb +8 -4
- data/lib/byebug/commands/untracevar.rb +38 -0
- data/lib/byebug/commands/var.rb +107 -0
- data/lib/byebug/context.rb +78 -42
- data/lib/byebug/core.rb +78 -40
- data/lib/byebug/helper.rb +58 -42
- data/lib/byebug/history.rb +12 -1
- data/lib/byebug/interface.rb +91 -11
- data/lib/byebug/interfaces/local_interface.rb +12 -19
- data/lib/byebug/interfaces/remote_interface.rb +12 -15
- data/lib/byebug/interfaces/script_interface.rb +14 -18
- data/lib/byebug/interfaces/test_interface.rb +54 -0
- data/lib/byebug/printers/base.rb +64 -0
- data/lib/byebug/printers/plain.rb +53 -0
- data/lib/byebug/processor.rb +20 -1
- data/lib/byebug/processors/command_processor.rb +57 -172
- data/lib/byebug/processors/control_command_processor.rb +16 -43
- data/lib/byebug/remote.rb +13 -7
- data/lib/byebug/runner.rb +102 -54
- data/lib/byebug/setting.rb +45 -68
- data/lib/byebug/settings/autoeval.rb +2 -0
- data/lib/byebug/settings/autoirb.rb +3 -0
- data/lib/byebug/settings/autolist.rb +3 -0
- data/lib/byebug/settings/autosave.rb +2 -0
- data/lib/byebug/settings/basename.rb +2 -0
- data/lib/byebug/settings/callstyle.rb +2 -0
- data/lib/byebug/settings/fullpath.rb +2 -0
- data/lib/byebug/settings/histfile.rb +2 -0
- data/lib/byebug/settings/histsize.rb +2 -0
- data/lib/byebug/settings/linetrace.rb +2 -0
- data/lib/byebug/settings/listsize.rb +2 -0
- data/lib/byebug/settings/post_mortem.rb +7 -2
- data/lib/byebug/settings/stack_on_error.rb +2 -0
- data/lib/byebug/settings/verbose.rb +2 -0
- data/lib/byebug/settings/width.rb +2 -0
- data/lib/byebug/state.rb +12 -0
- data/lib/byebug/states/control_state.rb +26 -0
- data/lib/byebug/states/regular_state.rb +178 -0
- data/lib/byebug/version.rb +1 -1
- metadata +24 -109
- data/lib/byebug/commands/catchpoint.rb +0 -53
- data/lib/byebug/commands/reload.rb +0 -29
- data/lib/byebug/commands/trace.rb +0 -50
- data/lib/byebug/commands/variables.rb +0 -206
- data/lib/byebug/options.rb +0 -46
- data/lib/byebug/settings/autoreload.rb +0 -12
- data/lib/byebug/settings/forcestep.rb +0 -14
- data/lib/byebug/settings/testing.rb +0 -12
- data/lib/byebug/settings/tracing_plus.rb +0 -11
- data/test/commands/break_test.rb +0 -364
- data/test/commands/condition_test.rb +0 -85
- data/test/commands/continue_test.rb +0 -47
- data/test/commands/delete_test.rb +0 -26
- data/test/commands/display_test.rb +0 -37
- data/test/commands/edit_test.rb +0 -52
- data/test/commands/eval_test.rb +0 -89
- data/test/commands/finish_test.rb +0 -74
- data/test/commands/frame_test.rb +0 -223
- data/test/commands/help_test.rb +0 -66
- data/test/commands/history_test.rb +0 -61
- data/test/commands/info_test.rb +0 -238
- data/test/commands/interrupt_test.rb +0 -45
- data/test/commands/irb_test.rb +0 -28
- data/test/commands/kill_test.rb +0 -50
- data/test/commands/list_test.rb +0 -174
- data/test/commands/method_test.rb +0 -52
- data/test/commands/post_mortem_test.rb +0 -71
- data/test/commands/pry_test.rb +0 -26
- data/test/commands/quit_test.rb +0 -53
- data/test/commands/reload_test.rb +0 -39
- data/test/commands/restart_test.rb +0 -46
- data/test/commands/save_test.rb +0 -67
- data/test/commands/set_test.rb +0 -140
- data/test/commands/show_test.rb +0 -76
- data/test/commands/source_test.rb +0 -46
- data/test/commands/stepping_test.rb +0 -192
- data/test/commands/thread_test.rb +0 -164
- data/test/commands/trace_test.rb +0 -71
- data/test/commands/undisplay_test.rb +0 -75
- data/test/commands/variables_test.rb +0 -105
- data/test/debugger_alias_test.rb +0 -7
- data/test/runner_test.rb +0 -150
- data/test/support/matchers.rb +0 -65
- data/test/support/test_interface.rb +0 -59
- data/test/support/utils.rb +0 -122
- data/test/test_helper.rb +0 -58
data/ext/byebug/byebug.h
CHANGED
@@ -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
|
10
|
-
#define
|
11
|
-
#define
|
12
|
-
#define
|
13
|
-
#define
|
14
|
-
#define
|
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)
|
19
|
-
#define CTX_FL_SET(c,f)
|
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
|
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
|
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
|
-
|
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,
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
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
|
data/ext/byebug/context.c
CHANGED
@@ -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
|
13
|
-
context->lines
|
14
|
-
context->steps
|
15
|
-
context->steps_out
|
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
|
-
|
49
|
+
dc_stack_size(debug_context_t * context)
|
42
50
|
{
|
43
|
-
|
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->
|
52
|
-
context->
|
53
|
-
context->
|
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
|
59
|
-
|
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)
|
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
|
-
|
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
|
-
|
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
|
-
|
331
|
+
debug_context_t *context;
|
327
332
|
|
328
|
-
|
333
|
+
Data_Get_Struct(self, debug_context_t, context);
|
329
334
|
|
330
|
-
|
331
|
-
|
335
|
+
if (!CTX_FL_TEST(context, CTX_FL_SUSPEND))
|
336
|
+
return Qnil;
|
332
337
|
|
333
|
-
|
338
|
+
CTX_FL_UNSET(context, CTX_FL_SUSPEND);
|
334
339
|
|
335
|
-
|
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.
|
348
|
+
* context.backtrace-> int
|
341
349
|
*
|
342
|
-
* Returns the
|
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
|
-
|
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
|
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
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
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,
|
393
|
+
* context.step_into(steps, frame = 0)
|
387
394
|
*
|
388
|
-
* Stops the current context after a number of +steps+ are made
|
389
|
-
* +
|
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,
|
401
|
+
VALUE steps, v_frame;
|
402
|
+
int n_args, from_frame;
|
396
403
|
debug_context_t *context;
|
397
404
|
|
398
|
-
|
399
|
-
|
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
|
-
|
403
|
-
context->steps = FIX2INT(steps);
|
415
|
+
from_frame = n_args == 1 ? 0 : FIX2INT(v_frame);
|
404
416
|
|
405
|
-
if (
|
406
|
-
|
407
|
-
|
408
|
-
|
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
|
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
|
466
|
+
* context.step_over(lines, frame = 0)
|
451
467
|
*
|
452
|
-
* Steps over +lines+ lines
|
453
|
-
*
|
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
|
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, "
|
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
|
-
|
489
|
-
|
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
|
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.
|
526
|
+
* context.switch -> nil
|
506
527
|
*
|
507
|
-
*
|
528
|
+
* Switches execution to this context.
|
508
529
|
*/
|
509
530
|
static VALUE
|
510
|
-
|
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
|
-
|
516
|
-
|
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
|
-
|
621
|
+
CTX_FL_SET(context, CTX_FL_TRACING);
|
594
622
|
else
|
595
|
-
|
623
|
+
CTX_FL_UNSET(context, CTX_FL_TRACING);
|
596
624
|
return value;
|
597
625
|
}
|
598
626
|
|
599
627
|
/* :nodoc: */
|
600
628
|
static VALUE
|
601
|
-
|
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, "
|
621
|
-
rb_define_method(cContext, "
|
622
|
-
rb_define_method(cContext, "
|
623
|
-
rb_define_method(cContext, "
|
624
|
-
rb_define_method(cContext, "
|
625
|
-
rb_define_method(cContext, "
|
626
|
-
rb_define_method(cContext, "
|
627
|
-
rb_define_method(cContext, "
|
628
|
-
rb_define_method(cContext, "
|
629
|
-
rb_define_method(cContext, "
|
630
|
-
rb_define_method(cContext, "step_into"
|
631
|
-
rb_define_method(cContext, "step_out"
|
632
|
-
rb_define_method(cContext, "step_over"
|
633
|
-
rb_define_method(cContext, "stop_reason"
|
634
|
-
rb_define_method(cContext, "suspend"
|
635
|
-
rb_define_method(cContext, "suspended?"
|
636
|
-
rb_define_method(cContext, "
|
637
|
-
rb_define_method(cContext, "
|
638
|
-
rb_define_method(cContext, "
|
639
|
-
rb_define_method(cContext, "tracing
|
640
|
-
|
641
|
-
|
642
|
-
|
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
|
}
|