debase 0.0.4 → 0.0.5
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/debase.gemspec +1 -0
- data/ext/breakpoint.c +4 -4
- data/ext/context.c +48 -56
- data/ext/debase_internals.c +75 -45
- data/ext/debase_internals.h +13 -5
- data/ext/extconf.rb +28 -2
- data/ext/hacks.h +13 -0
- data/lib/debase/version.rb +1 -1
- data/test/test_breakpoints.rb +3 -3
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e574bbfc504b8d62038134dea6ce7b66b203ceb
|
4
|
+
data.tar.gz: 9c9e4107a0c41852088b5c784df64e6bcf54e7ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ebac22a6499d081f01e4e541da1cf4df495a20b114ced85ff2b567cdd6a9274848aa6b5911e747a8d7aa9eccb516c072d920b2a2f378735f1e82054ad4b26a0
|
7
|
+
data.tar.gz: 4bb67a7e5d3101942f93bea8731c2ac223eae44d50fb466a92f6df66459b5fe77fef90766b1d63b23526e13d7822dd88d38103b1b9c639db8ea9ddf2c75009a0
|
data/debase.gemspec
CHANGED
data/ext/breakpoint.c
CHANGED
@@ -192,13 +192,13 @@ check_breakpoint_by_pos(VALUE breakpoint_object, char *file, int line)
|
|
192
192
|
}
|
193
193
|
|
194
194
|
static VALUE
|
195
|
-
Breakpoint_find(VALUE self, VALUE breakpoints, VALUE source, VALUE pos
|
195
|
+
Breakpoint_find(VALUE self, VALUE breakpoints, VALUE source, VALUE pos)
|
196
196
|
{
|
197
|
-
return breakpoint_find(breakpoints, source, pos
|
197
|
+
return breakpoint_find(breakpoints, source, pos);
|
198
198
|
}
|
199
199
|
|
200
200
|
extern VALUE
|
201
|
-
breakpoint_find(VALUE breakpoints, VALUE source, VALUE pos
|
201
|
+
breakpoint_find(VALUE breakpoints, VALUE source, VALUE pos)
|
202
202
|
{
|
203
203
|
VALUE breakpoint_object;
|
204
204
|
char *file;
|
@@ -223,7 +223,7 @@ Init_breakpoint(VALUE mDebase)
|
|
223
223
|
{
|
224
224
|
breakpoint_max = 0;
|
225
225
|
cBreakpoint = rb_define_class_under(mDebase, "Breakpoint", rb_cObject);
|
226
|
-
rb_define_singleton_method(cBreakpoint, "find", Breakpoint_find,
|
226
|
+
rb_define_singleton_method(cBreakpoint, "find", Breakpoint_find, 3);
|
227
227
|
rb_define_singleton_method(cBreakpoint, "remove", Breakpoint_remove, 2);
|
228
228
|
rb_define_method(cBreakpoint, "initialize", Breakpoint_initialize, 3);
|
229
229
|
rb_define_method(cBreakpoint, "id", Breakpoint_id, 0);
|
data/ext/context.c
CHANGED
@@ -23,17 +23,6 @@ Context_thnum(VALUE self) {
|
|
23
23
|
return INT2FIX(context->thnum);
|
24
24
|
}
|
25
25
|
|
26
|
-
static inline void
|
27
|
-
delete_frame(debug_context_t *context)
|
28
|
-
{
|
29
|
-
debug_frame_t *frame;
|
30
|
-
|
31
|
-
frame = context->stack;
|
32
|
-
context->stack = frame->prev;
|
33
|
-
context->stack_size--;
|
34
|
-
xfree(frame);
|
35
|
-
}
|
36
|
-
|
37
26
|
static inline void
|
38
27
|
fill_frame(debug_frame_t *frame, char* file, int line, VALUE binding, VALUE self)
|
39
28
|
{
|
@@ -43,6 +32,49 @@ fill_frame(debug_frame_t *frame, char* file, int line, VALUE binding, VALUE self
|
|
43
32
|
frame->self = self;
|
44
33
|
}
|
45
34
|
|
35
|
+
extern void
|
36
|
+
fill_stack(debug_context_t *context, const rb_debug_inspector_t *inspector) {
|
37
|
+
debug_frame_t *frame;
|
38
|
+
VALUE locations;
|
39
|
+
VALUE location;
|
40
|
+
VALUE path;
|
41
|
+
VALUE lineno;
|
42
|
+
char *file;
|
43
|
+
int line;
|
44
|
+
int stack_size;
|
45
|
+
int i;
|
46
|
+
|
47
|
+
locations = rb_debug_inspector_backtrace_locations(inspector);
|
48
|
+
stack_size = (int)RARRAY_LEN(locations);
|
49
|
+
|
50
|
+
for (i = 0; i < stack_size; i++) {
|
51
|
+
frame = ALLOC(debug_frame_t);
|
52
|
+
location = rb_ary_entry(locations, i);
|
53
|
+
path = rb_funcall(location, rb_intern("path"), 0);
|
54
|
+
lineno = rb_funcall(location, rb_intern("lineno"), 0);
|
55
|
+
file = RSTRING_PTR(path);
|
56
|
+
line = FIX2INT(lineno);
|
57
|
+
fill_frame(frame, file, line, rb_debug_inspector_frame_binding_get(inspector, i), rb_debug_inspector_frame_self_get(inspector, i));
|
58
|
+
frame->prev = context->stack;
|
59
|
+
context->stack = frame;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
extern void
|
64
|
+
clear_stack(debug_context_t *context)
|
65
|
+
{
|
66
|
+
debug_frame_t *frame;
|
67
|
+
debug_frame_t *prev;
|
68
|
+
|
69
|
+
frame = context->stack;
|
70
|
+
while(frame != NULL) {
|
71
|
+
prev = frame->prev;
|
72
|
+
xfree(frame);
|
73
|
+
frame = prev;
|
74
|
+
}
|
75
|
+
context->stack = NULL;
|
76
|
+
}
|
77
|
+
|
46
78
|
static inline VALUE
|
47
79
|
Context_stack_size(VALUE self)
|
48
80
|
{
|
@@ -77,44 +109,6 @@ Context_ignored(VALUE self)
|
|
77
109
|
return CTX_FL_TEST(context, CTX_FL_IGNORE) ? Qtrue : Qfalse;
|
78
110
|
}
|
79
111
|
|
80
|
-
extern void
|
81
|
-
push_frame(VALUE context_object, char* file, int line, VALUE binding, VALUE self)
|
82
|
-
{
|
83
|
-
debug_context_t *context;
|
84
|
-
debug_frame_t *frame;
|
85
|
-
Data_Get_Struct(context_object, debug_context_t, context);
|
86
|
-
|
87
|
-
frame = ALLOC(debug_frame_t);
|
88
|
-
fill_frame(frame, file, line, binding, self);
|
89
|
-
frame->prev = context->stack;
|
90
|
-
context->stack = frame;
|
91
|
-
context->stack_size++;
|
92
|
-
}
|
93
|
-
|
94
|
-
extern void
|
95
|
-
pop_frame(VALUE context_object)
|
96
|
-
{
|
97
|
-
debug_context_t *context;
|
98
|
-
Data_Get_Struct(context_object, debug_context_t, context);
|
99
|
-
|
100
|
-
if (context->stack_size > 0) {
|
101
|
-
delete_frame(context);
|
102
|
-
}
|
103
|
-
}
|
104
|
-
|
105
|
-
extern void
|
106
|
-
update_frame(VALUE context_object, char* file, int line, VALUE binding, VALUE self)
|
107
|
-
{
|
108
|
-
debug_context_t *context;
|
109
|
-
Data_Get_Struct(context_object, debug_context_t, context);
|
110
|
-
|
111
|
-
if (context->stack_size == 0) {
|
112
|
-
push_frame(context_object, file, line, binding, self);
|
113
|
-
return;
|
114
|
-
}
|
115
|
-
fill_frame(context->stack, file, line, binding, self);
|
116
|
-
}
|
117
|
-
|
118
112
|
static void
|
119
113
|
Context_mark(debug_context_t *context)
|
120
114
|
{
|
@@ -122,7 +116,8 @@ Context_mark(debug_context_t *context)
|
|
122
116
|
|
123
117
|
rb_gc_mark(context->thread);
|
124
118
|
frame = context->stack;
|
125
|
-
while
|
119
|
+
while(frame != NULL)
|
120
|
+
{
|
126
121
|
rb_gc_mark(frame->self);
|
127
122
|
rb_gc_mark(frame->binding);
|
128
123
|
frame = frame->prev;
|
@@ -131,9 +126,6 @@ Context_mark(debug_context_t *context)
|
|
131
126
|
|
132
127
|
static void
|
133
128
|
Context_free(debug_context_t *context) {
|
134
|
-
while(context->stack_size > 0) {
|
135
|
-
delete_frame(context);
|
136
|
-
}
|
137
129
|
xfree(context);
|
138
130
|
}
|
139
131
|
|
@@ -165,14 +157,14 @@ check_frame_number_valid(debug_context_t *context, int frame_no)
|
|
165
157
|
}
|
166
158
|
|
167
159
|
static debug_frame_t*
|
168
|
-
get_frame_no(debug_context_t *context, int
|
160
|
+
get_frame_no(debug_context_t *context, int frame_no)
|
169
161
|
{
|
170
162
|
debug_frame_t *frame;
|
171
163
|
int i;
|
172
164
|
|
173
|
-
check_frame_number_valid(context,
|
165
|
+
check_frame_number_valid(context, frame_no);
|
174
166
|
frame = context->stack;
|
175
|
-
for (i = 0; i <
|
167
|
+
for (i = 0; i < context->stack_size - frame_no - 1; i++) {
|
176
168
|
frame = frame->prev;
|
177
169
|
}
|
178
170
|
return frame;
|
data/ext/debase_internals.c
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#include <debase_internals.h>
|
2
|
+
#include <hacks.h>
|
2
3
|
|
3
4
|
static VALUE mDebase; /* Ruby Debase Module object */
|
4
5
|
static VALUE cContext;
|
@@ -52,6 +53,8 @@ cleanup(debug_context_t *context)
|
|
52
53
|
|
53
54
|
context->stop_reason = CTX_STOP_NONE;
|
54
55
|
|
56
|
+
clear_stack(context);
|
57
|
+
|
55
58
|
/* release a lock */
|
56
59
|
locker = Qnil;
|
57
60
|
|
@@ -104,26 +107,61 @@ check_start_processing(debug_context_t *context, VALUE thread)
|
|
104
107
|
}
|
105
108
|
|
106
109
|
static inline void
|
107
|
-
|
110
|
+
print_event(rb_trace_point_t *tp, debug_context_t *context)
|
111
|
+
{
|
112
|
+
VALUE locations;
|
113
|
+
VALUE path;
|
114
|
+
VALUE line;
|
115
|
+
VALUE event;
|
116
|
+
VALUE mid;
|
117
|
+
|
118
|
+
if (debug == Qtrue) {
|
119
|
+
path = rb_tracearg_path(tp);
|
120
|
+
line = rb_tracearg_lineno(tp);
|
121
|
+
event = rb_tracearg_event(tp);
|
122
|
+
mid = rb_tracearg_method_id(tp);
|
123
|
+
fprintf(stderr, "%s: file=%s, line=%d, mid=%s\n", rb_id2name(SYM2ID(event)), RSTRING_PTR(path), FIX2INT(line), rb_id2name(SYM2ID(mid)));
|
124
|
+
locations = rb_funcall(context->thread, rb_intern("backtrace_locations"), 1, INT2FIX(1));
|
125
|
+
fprintf(stderr, " stack_size=%d, thread=%d, real_stack_size=%d\n", context->stack_size, context->thnum, (int)RARRAY_LEN(locations));
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
static VALUE
|
130
|
+
fill_stack_and_invoke(const rb_debug_inspector_t *inspector, void *data)
|
108
131
|
{
|
109
|
-
|
132
|
+
debug_context_t *context;
|
133
|
+
VALUE context_object;
|
110
134
|
|
111
|
-
|
135
|
+
context_object = *(VALUE *)data;
|
136
|
+
Data_Get_Struct(context_object, debug_context_t, context);
|
137
|
+
fill_stack(context, inspector);
|
112
138
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
139
|
+
return Qnil;
|
140
|
+
}
|
141
|
+
|
142
|
+
static VALUE
|
143
|
+
start_inspector(VALUE data)
|
144
|
+
{
|
145
|
+
debug_context_t *context;
|
146
|
+
|
147
|
+
Data_Get_Struct(data, debug_context_t, context);
|
148
|
+
return rb_debug_inspector_open(fill_stack_and_invoke, &data);
|
149
|
+
}
|
150
|
+
|
151
|
+
static VALUE
|
152
|
+
stop_inspector(VALUE data)
|
153
|
+
{
|
154
|
+
return Qnil;
|
117
155
|
}
|
118
156
|
|
119
157
|
static void
|
120
|
-
call_at_line(debug_context_t *context, char *file, int line, VALUE context_object
|
158
|
+
call_at_line(debug_context_t *context, char *file, int line, VALUE context_object)
|
121
159
|
{
|
122
160
|
CTX_FL_UNSET(context, CTX_FL_STEPPED);
|
123
161
|
CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
|
124
162
|
context->last_file = file;
|
125
163
|
context->last_line = line;
|
126
|
-
rb_funcall(context_object, idAtLine, 2,
|
164
|
+
rb_funcall(context_object, idAtLine, 2, rb_str_new2(file), INT2FIX(line));
|
127
165
|
}
|
128
166
|
|
129
167
|
static void
|
@@ -131,11 +169,10 @@ process_line_event(VALUE trace_point, void *data)
|
|
131
169
|
{
|
132
170
|
VALUE path;
|
133
171
|
VALUE lineno;
|
134
|
-
VALUE binding;
|
135
|
-
VALUE self;
|
136
172
|
VALUE context_object;
|
137
173
|
VALUE breakpoint;
|
138
174
|
debug_context_t *context;
|
175
|
+
rb_trace_point_t *tp;
|
139
176
|
char *file;
|
140
177
|
int line;
|
141
178
|
int moved;
|
@@ -144,13 +181,14 @@ process_line_event(VALUE trace_point, void *data)
|
|
144
181
|
Data_Get_Struct(context_object, debug_context_t, context);
|
145
182
|
if (!check_start_processing(context, rb_thread_current())) return;
|
146
183
|
|
147
|
-
|
184
|
+
tp = TRACE_POINT;
|
185
|
+
path = rb_tracearg_path(tp);
|
186
|
+
lineno = rb_tracearg_lineno(tp);
|
148
187
|
file = RSTRING_PTR(path);
|
149
188
|
line = FIX2INT(lineno);
|
150
|
-
update_frame(context_object, file, line, binding, self);
|
151
189
|
|
152
|
-
|
153
|
-
|
190
|
+
update_stack_size(context);
|
191
|
+
print_event(tp, context);
|
154
192
|
|
155
193
|
moved = context->last_line != line || context->last_file == NULL ||
|
156
194
|
strcmp(context->last_file, file) != 0;
|
@@ -172,15 +210,16 @@ process_line_event(VALUE trace_point, void *data)
|
|
172
210
|
context->stop_next = 0;
|
173
211
|
}
|
174
212
|
|
175
|
-
breakpoint = breakpoint_find(breakpoints, path, lineno
|
213
|
+
breakpoint = breakpoint_find(breakpoints, path, lineno);
|
176
214
|
if(context->stop_next == 0 || context->stop_line == 0 || breakpoint != Qnil) {
|
215
|
+
rb_ensure(start_inspector, context_object, stop_inspector, Qnil);
|
177
216
|
context->stop_reason = CTX_STOP_STEP;
|
178
217
|
if (breakpoint != Qnil) {
|
179
218
|
context->stop_reason = CTX_STOP_BREAKPOINT;
|
180
219
|
rb_funcall(context_object, idAtBreakpoint, 1, breakpoint);
|
181
220
|
}
|
182
221
|
reset_stepping_stop_points(context);
|
183
|
-
call_at_line(context, file, line, context_object
|
222
|
+
call_at_line(context, file, line, context_object);
|
184
223
|
}
|
185
224
|
cleanup(context);
|
186
225
|
}
|
@@ -188,10 +227,6 @@ process_line_event(VALUE trace_point, void *data)
|
|
188
227
|
static void
|
189
228
|
process_return_event(VALUE trace_point, void *data)
|
190
229
|
{
|
191
|
-
VALUE path;
|
192
|
-
VALUE lineno;
|
193
|
-
VALUE binding;
|
194
|
-
VALUE self;
|
195
230
|
VALUE context_object;
|
196
231
|
debug_context_t *context;
|
197
232
|
|
@@ -199,38 +234,30 @@ process_return_event(VALUE trace_point, void *data)
|
|
199
234
|
Data_Get_Struct(context_object, debug_context_t, context);
|
200
235
|
if (!check_start_processing(context, rb_thread_current())) return;
|
201
236
|
|
237
|
+
update_stack_size(context);
|
202
238
|
if(context->stack_size == context->stop_frame)
|
203
239
|
{
|
204
240
|
context->stop_next = 1;
|
205
241
|
context->stop_frame = 0;
|
206
242
|
}
|
207
243
|
|
208
|
-
|
209
|
-
|
210
|
-
fprintf(stderr, "return: file=%s, line=%d, stack_size=%d\n", RSTRING_PTR(path), FIX2INT(lineno), context->stack_size);
|
211
|
-
// rb_funcall(context_object, idAtReturn, 2, path, lineno);
|
212
|
-
pop_frame(context_object);
|
244
|
+
|
245
|
+
print_event(TRACE_POINT, context);
|
213
246
|
cleanup(context);
|
214
247
|
}
|
215
248
|
|
216
249
|
static void
|
217
250
|
process_call_event(VALUE trace_point, void *data)
|
218
251
|
{
|
219
|
-
VALUE path;
|
220
|
-
VALUE lineno;
|
221
|
-
VALUE binding;
|
222
|
-
VALUE self;
|
223
252
|
VALUE context_object;
|
224
253
|
debug_context_t *context;
|
225
254
|
|
226
255
|
context_object = Debase_current_context(mDebase);
|
227
256
|
Data_Get_Struct(context_object, debug_context_t, context);
|
228
257
|
if (!check_start_processing(context, rb_thread_current())) return;
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
fprintf(stderr, "call: file=%s, line=%d, stack_size=%d\n", RSTRING_PTR(path), FIX2INT(lineno), context->stack_size);
|
233
|
-
push_frame(context_object, RSTRING_PTR(path), FIX2INT(lineno), binding, self);
|
258
|
+
|
259
|
+
update_stack_size(context);
|
260
|
+
print_event(TRACE_POINT, context);
|
234
261
|
cleanup(context);
|
235
262
|
}
|
236
263
|
|
@@ -239,12 +266,11 @@ process_raise_event(VALUE trace_point, void *data)
|
|
239
266
|
{
|
240
267
|
VALUE path;
|
241
268
|
VALUE lineno;
|
242
|
-
VALUE binding;
|
243
|
-
VALUE self;
|
244
269
|
VALUE context_object;
|
245
270
|
VALUE hit_count;
|
246
271
|
VALUE exception_name;
|
247
272
|
debug_context_t *context;
|
273
|
+
rb_trace_point_t *tp;
|
248
274
|
char *file;
|
249
275
|
int line;
|
250
276
|
int c_hit_count;
|
@@ -253,12 +279,13 @@ process_raise_event(VALUE trace_point, void *data)
|
|
253
279
|
Data_Get_Struct(context_object, debug_context_t, context);
|
254
280
|
if (!check_start_processing(context, rb_thread_current())) return;
|
255
281
|
|
256
|
-
load_frame_info(trace_point, &path, &lineno, &binding, &self);
|
257
|
-
file = RSTRING_PTR(path);
|
258
|
-
line = FIX2INT(lineno);
|
259
|
-
update_frame(context_object, file, line, binding, self);
|
260
|
-
|
261
282
|
if (catchpoint_hit_count(catchpoints, rb_errinfo(), &exception_name) != Qnil) {
|
283
|
+
tp = TRACE_POINT;
|
284
|
+
path = rb_tracearg_path(tp);
|
285
|
+
lineno = rb_tracearg_lineno(tp);
|
286
|
+
file = RSTRING_PTR(path);
|
287
|
+
line = FIX2INT(lineno);
|
288
|
+
|
262
289
|
/* On 64-bit systems with gcc and -O2 there seems to be
|
263
290
|
an optimization bug in running INT2FIX(FIX2INT...)..)
|
264
291
|
So we do this in two steps.
|
@@ -268,7 +295,7 @@ process_raise_event(VALUE trace_point, void *data)
|
|
268
295
|
rb_hash_aset(catchpoints, exception_name, hit_count);
|
269
296
|
context->stop_reason = CTX_STOP_CATCHPOINT;
|
270
297
|
rb_funcall(context_object, idAtCatchpoint, 1, rb_errinfo());
|
271
|
-
call_at_line(context, file, line, context_object
|
298
|
+
call_at_line(context, file, line, context_object);
|
272
299
|
}
|
273
300
|
|
274
301
|
cleanup(context);
|
@@ -284,14 +311,16 @@ Debase_setup_tracepoints(VALUE self)
|
|
284
311
|
|
285
312
|
tpLine = rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, process_line_event, NULL);
|
286
313
|
rb_tracepoint_enable(tpLine);
|
287
|
-
tpReturn = rb_tracepoint_new(Qnil, RUBY_EVENT_RETURN |
|
314
|
+
tpReturn = rb_tracepoint_new(Qnil, RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_C_RETURN | RUBY_EVENT_END,
|
288
315
|
process_return_event, NULL);
|
289
316
|
rb_tracepoint_enable(tpReturn);
|
290
|
-
tpCall = rb_tracepoint_new(Qnil, RUBY_EVENT_CALL | RUBY_EVENT_C_CALL |
|
317
|
+
tpCall = rb_tracepoint_new(Qnil, RUBY_EVENT_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_C_CALL | RUBY_EVENT_CLASS,
|
291
318
|
process_call_event, NULL);
|
292
319
|
rb_tracepoint_enable(tpCall);
|
293
320
|
tpRaise = rb_tracepoint_new(Qnil, RUBY_EVENT_RAISE, process_raise_event, NULL);
|
294
321
|
rb_tracepoint_enable(tpRaise);
|
322
|
+
Debase_current_context(self);
|
323
|
+
|
295
324
|
return Qnil;
|
296
325
|
}
|
297
326
|
|
@@ -310,6 +339,7 @@ Debase_remove_tracepoints(VALUE self)
|
|
310
339
|
tpCall = Qnil;
|
311
340
|
if (tpRaise != Qnil) rb_tracepoint_disable(tpRaise);
|
312
341
|
tpRaise = Qnil;
|
342
|
+
|
313
343
|
return Qnil;
|
314
344
|
}
|
315
345
|
|
data/ext/debase_internals.h
CHANGED
@@ -25,6 +25,7 @@ typedef struct rb_trace_arg_struct rb_trace_point_t;
|
|
25
25
|
#define CTX_FL_UNSET(c,f) do { (c)->flags &= ~(f); } while (0)
|
26
26
|
|
27
27
|
#define IS_THREAD_ALIVE(t) (rb_funcall((t), idAlive, 0) == Qtrue)
|
28
|
+
#define TRACE_POINT (rb_tracearg_from_tracepoint(trace_point))
|
28
29
|
|
29
30
|
/* types */
|
30
31
|
typedef enum {CTX_STOP_NONE, CTX_STOP_STEP, CTX_STOP_BREAKPOINT, CTX_STOP_CATCHPOINT} ctx_stop_reason;
|
@@ -38,7 +39,7 @@ typedef struct debug_frame_t
|
|
38
39
|
VALUE self;
|
39
40
|
} debug_frame_t;
|
40
41
|
|
41
|
-
typedef struct {
|
42
|
+
typedef struct debug_context {
|
42
43
|
debug_frame_t *stack;
|
43
44
|
int stack_size;
|
44
45
|
|
@@ -56,14 +57,21 @@ typedef struct {
|
|
56
57
|
int last_line;
|
57
58
|
} debug_context_t;
|
58
59
|
|
60
|
+
typedef struct
|
61
|
+
{
|
62
|
+
debug_context_t *context;
|
63
|
+
VALUE context_object;
|
64
|
+
VALUE path;
|
65
|
+
VALUE lineno;
|
66
|
+
} inspector_data_t;
|
67
|
+
|
59
68
|
/* functions */
|
60
69
|
extern VALUE Init_context(VALUE mDebase);
|
61
70
|
extern VALUE context_create(VALUE thread, VALUE cDebugThread);
|
62
71
|
extern void reset_stepping_stop_points(debug_context_t *context);
|
63
72
|
extern VALUE Context_ignored(VALUE self);
|
64
|
-
extern void
|
65
|
-
extern void
|
66
|
-
extern void update_frame(VALUE context_object, char* file, int line, VALUE binding, VALUE self);
|
73
|
+
extern void fill_stack(debug_context_t *context, const rb_debug_inspector_t *inspector);
|
74
|
+
extern void clear_stack(debug_context_t *context);
|
67
75
|
|
68
76
|
/* locked threads container */
|
69
77
|
/* types */
|
@@ -89,6 +97,6 @@ typedef struct
|
|
89
97
|
} breakpoint_t;
|
90
98
|
|
91
99
|
extern VALUE catchpoint_hit_count(VALUE catchpoints, VALUE exception, VALUE *exception_name);
|
92
|
-
extern VALUE breakpoint_find(VALUE breakpoints, VALUE source, VALUE pos
|
100
|
+
extern VALUE breakpoint_find(VALUE breakpoints, VALUE source, VALUE pos);
|
93
101
|
extern void Init_breakpoint(VALUE mDebase);
|
94
102
|
#endif
|
data/ext/extconf.rb
CHANGED
@@ -1,4 +1,23 @@
|
|
1
|
+
# autodetect ruby headers
|
2
|
+
unless ARGV.any? {|arg| arg.include?('--with-ruby-include') }
|
3
|
+
require 'rbconfig'
|
4
|
+
bindir = RbConfig::CONFIG['bindir']
|
5
|
+
if bindir =~ %r{(^.*/\.rbenv/versions)/([^/]+)/bin$}
|
6
|
+
ruby_include = "#{$1}/#{$2}/include/ruby-1.9.1/ruby-#{$2}"
|
7
|
+
ARGV << "--with-ruby-include=#{ruby_include}"
|
8
|
+
elsif bindir =~ %r{(^.*/\.rvm/rubies)/([^/]+)/bin$}
|
9
|
+
ruby_include = "#{$1}/#{$2}/include/ruby-1.9.1/#{$2}"
|
10
|
+
ruby_include = "#{ENV['rvm_path']}/src/#{$2}" unless File.exist?(ruby_include)
|
11
|
+
ARGV << "--with-ruby-include=#{ruby_include}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
1
15
|
require "mkmf"
|
16
|
+
require "debugger/ruby_core_source"
|
17
|
+
|
18
|
+
hdrs = proc {
|
19
|
+
have_header("vm_core.h")
|
20
|
+
}
|
2
21
|
|
3
22
|
# Allow use customization of compile options. For example, the
|
4
23
|
# following lines could be put in config_options to to turn off
|
@@ -7,8 +26,15 @@ require "mkmf"
|
|
7
26
|
config_file = File.join(File.dirname(__FILE__), 'config_options.rb')
|
8
27
|
load config_file if File.exist?(config_file)
|
9
28
|
|
10
|
-
$CFLAGS
|
29
|
+
$CFLAGS+=' -Wall -Werror'
|
11
30
|
$CFLAGS+=' -g3' if ENV['debug']
|
12
31
|
|
13
32
|
dir_config("ruby")
|
14
|
-
|
33
|
+
if !Debugger::RubyCoreSource.create_makefile_with_core(hdrs, "debase_internals")
|
34
|
+
STDERR.print("Makefile creation failed\n")
|
35
|
+
STDERR.print("*************************************************************\n\n")
|
36
|
+
STDERR.print(" NOTE: If your headers were not found, try passing\n")
|
37
|
+
STDERR.print(" --with-ruby-include=PATH_TO_HEADERS \n\n")
|
38
|
+
STDERR.print("*************************************************************\n\n")
|
39
|
+
exit(1)
|
40
|
+
end
|
data/ext/hacks.h
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#include <vm_core.h>
|
2
|
+
|
3
|
+
#define ruby_current_thread ((rb_thread_t *)RTYPEDDATA_DATA(rb_thread_current()))
|
4
|
+
|
5
|
+
extern void
|
6
|
+
update_stack_size(debug_context_t *context)
|
7
|
+
{
|
8
|
+
rb_thread_t *thread;
|
9
|
+
|
10
|
+
thread = ruby_current_thread;
|
11
|
+
/* see backtrace_each in vm_backtrace.c */
|
12
|
+
context->stack_size = (int)(RUBY_VM_END_CONTROL_FRAME(thread) - thread->cfp - 1);
|
13
|
+
}
|
data/lib/debase/version.rb
CHANGED
data/test/test_breakpoints.rb
CHANGED
@@ -6,9 +6,9 @@ class TestBreakpoints < Test::Unit::TestCase
|
|
6
6
|
def test_find
|
7
7
|
Debugger.start
|
8
8
|
Debugger.add_breakpoint("foo.rb", 11, nil)
|
9
|
-
assert_not_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "foo.rb", 11
|
10
|
-
assert_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "bar.rb", 11
|
11
|
-
assert_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "foo.rb", 10
|
9
|
+
assert_not_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "foo.rb", 11))
|
10
|
+
assert_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "bar.rb", 11))
|
11
|
+
assert_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "foo.rb", 10))
|
12
12
|
Debugger.stop
|
13
13
|
end
|
14
14
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: debase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dennis Ushakov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: debugger-ruby_core_source
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: test-unit
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -63,6 +77,7 @@ files:
|
|
63
77
|
- ext/debase_internals.c
|
64
78
|
- ext/debase_internals.h
|
65
79
|
- ext/extconf.rb
|
80
|
+
- ext/hacks.h
|
66
81
|
- ext/locker.c
|
67
82
|
- lib/debase.rb
|
68
83
|
- lib/debase/context.rb
|