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