readapt 0.3.5 → 0.4.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/.rspec +0 -1
- data/CHANGELOG.md +4 -0
- data/ext/readapt/breakpoints.c +88 -0
- data/ext/readapt/breakpoints.h +12 -0
- data/ext/readapt/hash_table.c +216 -0
- data/ext/readapt/hash_table.h +32 -0
- data/ext/readapt/monitor.c +55 -92
- data/ext/readapt/monitor.h +5 -0
- data/ext/readapt/normalize.c +1 -0
- data/ext/readapt/normalize.h +5 -0
- data/ext/readapt/readapt.c +2 -0
- data/ext/readapt/threads.h +5 -2
- data/lib/readapt.rb +1 -3
- data/lib/readapt/debugger.rb +1 -7
- data/lib/readapt/message/set_breakpoints.rb +7 -12
- data/lib/readapt/monitor.rb +0 -16
- data/lib/readapt/version.rb +1 -1
- metadata +6 -4
- data/lib/readapt/breakpoint.rb +0 -16
- data/lib/readapt/breakpoints.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e935059da5afc7fe4f6a68e6574ad096dcf90c2b166b81f3c0e50260e3d740ba
|
4
|
+
data.tar.gz: 26f8dce0349345c4f0fa5953f179e833c8848e5cf90f57632661f97603967d4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 979309cb99c3e4eb81768965b2a564ae14dd057f424383b28ae4e9f4a38dded3a2afc135aaca70d04207e470fd241c195ed207ae4712e98e6efbf19ae79ec6a2
|
7
|
+
data.tar.gz: a22d57be02bb01fb3535cb7c6c3047dcb33ec6a132ead776dbea44022924cfe026de4e99eb28632e6690a3a0e920f78d2131f2a7f5dac70ecb6dda939b79e4fb
|
data/.rspec
CHANGED
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,88 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "hash_table.h"
|
3
|
+
|
4
|
+
static VALUE m_Breakpoints;
|
5
|
+
ht_hash_table *ht;
|
6
|
+
|
7
|
+
void breakpoints_set(char *file, long *lines)
|
8
|
+
{
|
9
|
+
|
10
|
+
}
|
11
|
+
|
12
|
+
static VALUE breakpoints_set_s(VALUE self, VALUE file, VALUE lines)
|
13
|
+
{
|
14
|
+
long length = NUM2LONG(rb_funcall(lines, rb_intern("length"), 0));
|
15
|
+
long *ll;
|
16
|
+
long i;
|
17
|
+
|
18
|
+
ll = malloc(sizeof(long) * length);
|
19
|
+
for (i = 0; i < length; i++)
|
20
|
+
{
|
21
|
+
ll[i] = NUM2LONG(rb_ary_entry(lines, i));
|
22
|
+
}
|
23
|
+
ht_insert(ht, StringValueCStr(file), ll, length);
|
24
|
+
free(ll);
|
25
|
+
return Qnil;
|
26
|
+
}
|
27
|
+
|
28
|
+
void breakpoints_delete(char *file)
|
29
|
+
{
|
30
|
+
|
31
|
+
}
|
32
|
+
|
33
|
+
static VALUE breakpoints_delete_s(VALUE self, VALUE file)
|
34
|
+
{
|
35
|
+
return Qnil;
|
36
|
+
}
|
37
|
+
|
38
|
+
int breakpoints_match(char *file, long line)
|
39
|
+
{
|
40
|
+
ht_long_array *lines;
|
41
|
+
long i;
|
42
|
+
|
43
|
+
lines = ht_search(ht, file);
|
44
|
+
if (lines != NULL)
|
45
|
+
{
|
46
|
+
for (i = 0; i < lines->size; i++)
|
47
|
+
{
|
48
|
+
if (lines->items[i] == line)
|
49
|
+
{
|
50
|
+
return 1;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
return 0;
|
55
|
+
}
|
56
|
+
|
57
|
+
// int breakpoints_match(char *file, long line)
|
58
|
+
// {
|
59
|
+
// return breakpoints_match_id(rb_intern(file), line);
|
60
|
+
// }
|
61
|
+
|
62
|
+
static VALUE breakpoints_match_s(VALUE self, VALUE file, VALUE line)
|
63
|
+
{
|
64
|
+
return breakpoints_match(StringValueCStr(file), NUM2LONG(line)) == 0 ? Qfalse : Qtrue;
|
65
|
+
}
|
66
|
+
|
67
|
+
static VALUE breakpoints_clear_s(VALUE self)
|
68
|
+
{
|
69
|
+
ht_del_hash_table(ht);
|
70
|
+
ht = ht_new();
|
71
|
+
return Qnil;
|
72
|
+
}
|
73
|
+
|
74
|
+
long breakpoints_files()
|
75
|
+
{
|
76
|
+
return ht->size;
|
77
|
+
}
|
78
|
+
|
79
|
+
void initialize_breakpoints(VALUE m_Readapt)
|
80
|
+
{
|
81
|
+
m_Breakpoints = rb_define_module_under(m_Readapt, "Breakpoints");
|
82
|
+
rb_define_singleton_method(m_Breakpoints, "set", breakpoints_set_s, 2);
|
83
|
+
rb_define_singleton_method(m_Breakpoints, "delete", breakpoints_delete_s, 1);
|
84
|
+
rb_define_singleton_method(m_Breakpoints, "match", breakpoints_match_s, 2);
|
85
|
+
rb_define_singleton_method(m_Breakpoints, "clear", breakpoints_clear_s, 0);
|
86
|
+
|
87
|
+
ht = ht_new(); // TODO Need to free?
|
88
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#ifndef BREAKPOINTS_H_
|
2
|
+
#define BREAKPOINTS_H_
|
3
|
+
|
4
|
+
void initialize_breakpoints(VALUE m_Readapt);
|
5
|
+
|
6
|
+
void breakpoints_set(char *file, long *lines);
|
7
|
+
void breakpoints_delete(char *file);
|
8
|
+
int breakpoints_match(char *file, long line);
|
9
|
+
// int breakpoints_match_id(ht_key file, long line);
|
10
|
+
long breakpoints_files();
|
11
|
+
|
12
|
+
#endif
|
@@ -0,0 +1,216 @@
|
|
1
|
+
#include <math.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <string.h>
|
4
|
+
|
5
|
+
#include "hash_table.h"
|
6
|
+
#include "ruby.h"
|
7
|
+
|
8
|
+
static ht_long_array *copy_array(const long *value, const long size)
|
9
|
+
{
|
10
|
+
long i;
|
11
|
+
long *items = malloc(sizeof(long) * size);
|
12
|
+
ht_long_array *result;
|
13
|
+
|
14
|
+
for (i = 0; i < size; i++)
|
15
|
+
{
|
16
|
+
items[i] = value[i];
|
17
|
+
}
|
18
|
+
result = malloc(sizeof(ht_long_array));
|
19
|
+
result->items = (size ? items : NULL);
|
20
|
+
result->size = size;
|
21
|
+
return result;
|
22
|
+
}
|
23
|
+
|
24
|
+
/*
|
25
|
+
* Initialize a new item
|
26
|
+
*/
|
27
|
+
static ht_item *ht_new_item(char *key, const long *value, const long size)
|
28
|
+
{
|
29
|
+
ht_item *i = malloc(sizeof(ht_item));
|
30
|
+
i->key = malloc(sizeof(char) * (strlen(key) + 1));
|
31
|
+
strcpy(i->key, key);
|
32
|
+
i->value = copy_array(value, size);
|
33
|
+
return i;
|
34
|
+
}
|
35
|
+
|
36
|
+
/*
|
37
|
+
* Delete the ht_item
|
38
|
+
*/
|
39
|
+
static void ht_del_item(ht_item *i)
|
40
|
+
{
|
41
|
+
free(i->key);
|
42
|
+
free(i->value->items);
|
43
|
+
free(i);
|
44
|
+
}
|
45
|
+
|
46
|
+
/*
|
47
|
+
* Initialize a new empty hash table
|
48
|
+
*/
|
49
|
+
ht_hash_table *ht_new()
|
50
|
+
{
|
51
|
+
ht_hash_table *ht = malloc(sizeof(ht_hash_table));
|
52
|
+
ht->items = NULL;
|
53
|
+
ht->size = 0;
|
54
|
+
return ht;
|
55
|
+
}
|
56
|
+
|
57
|
+
/*
|
58
|
+
* Delete the hash table
|
59
|
+
*/
|
60
|
+
void ht_del_hash_table(ht_hash_table *ht)
|
61
|
+
{
|
62
|
+
int i;
|
63
|
+
ht_item *item;
|
64
|
+
|
65
|
+
// Iterate through items and delete any that are found
|
66
|
+
for (i = 0; i < ht->size; i++)
|
67
|
+
{
|
68
|
+
item = ht->items[i];
|
69
|
+
ht_del_item(item);
|
70
|
+
}
|
71
|
+
free(ht->items);
|
72
|
+
free(ht);
|
73
|
+
}
|
74
|
+
|
75
|
+
static ht_long_array *ht_search_part(ht_hash_table *ht, char *key, long cursor, long next)
|
76
|
+
{
|
77
|
+
int cmp;
|
78
|
+
|
79
|
+
if (cursor >= ht->size)
|
80
|
+
{
|
81
|
+
return NULL;
|
82
|
+
}
|
83
|
+
|
84
|
+
cmp = strcmp(ht->items[cursor]->key, key);
|
85
|
+
if (cmp == 0)
|
86
|
+
{
|
87
|
+
return ht->items[cursor]->value;
|
88
|
+
}
|
89
|
+
if (next > cursor && next < ht->size)
|
90
|
+
{
|
91
|
+
cmp = strcmp(ht->items[next]->key, key);
|
92
|
+
if (cmp == 0)
|
93
|
+
{
|
94
|
+
return ht->items[next]->value;
|
95
|
+
}
|
96
|
+
else if (cmp < 0)
|
97
|
+
{
|
98
|
+
return ht_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
|
99
|
+
}
|
100
|
+
else
|
101
|
+
{
|
102
|
+
return ht_search_part(ht, key, cursor + 1, next / 2);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
return ht_search_part(ht, key, cursor + 1, next / 2);
|
106
|
+
}
|
107
|
+
|
108
|
+
static ht_long_array *ht_search_key(ht_hash_table *ht, char *key)
|
109
|
+
{
|
110
|
+
return ht_search_part(ht, key, 0, ht->size / 2);
|
111
|
+
}
|
112
|
+
|
113
|
+
static void ht_delete_key(ht_hash_table *ht, char *key)
|
114
|
+
{
|
115
|
+
ht_long_array *found;
|
116
|
+
ht_item **tmp;
|
117
|
+
long i;
|
118
|
+
long cursor = 0;
|
119
|
+
|
120
|
+
found = ht_search_key(ht, key);
|
121
|
+
if (found)
|
122
|
+
{
|
123
|
+
tmp = malloc(sizeof(ht_item) * (ht->size - 1));
|
124
|
+
for (i = 0; i < ht->size; i++)
|
125
|
+
{
|
126
|
+
if (ht->items[i]->key == key)
|
127
|
+
{
|
128
|
+
ht_del_item(ht->items[i]);
|
129
|
+
}
|
130
|
+
else
|
131
|
+
{
|
132
|
+
tmp[cursor] = ht->items[cursor];
|
133
|
+
cursor++;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
free(ht->items);
|
137
|
+
ht->items = tmp;
|
138
|
+
ht->size--;
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
static void ht_insert_key(ht_hash_table *ht, char *key, const long *value, const long size)
|
143
|
+
{
|
144
|
+
ht_item *item;
|
145
|
+
ht_item **tmp;
|
146
|
+
long i;
|
147
|
+
long cursor = 0;
|
148
|
+
int inserted = 0;
|
149
|
+
int cmp;
|
150
|
+
|
151
|
+
ht_delete_key(ht, key);
|
152
|
+
|
153
|
+
if (size == 0)
|
154
|
+
{
|
155
|
+
return;
|
156
|
+
}
|
157
|
+
|
158
|
+
item = ht_new_item(key, value, size);
|
159
|
+
tmp = malloc(sizeof(ht_item) * (ht->size + 1));
|
160
|
+
|
161
|
+
for (i = 0; i <= ht->size; i++)
|
162
|
+
{
|
163
|
+
if (!inserted)
|
164
|
+
{
|
165
|
+
if (i == ht->size)
|
166
|
+
{
|
167
|
+
tmp[i] = item;
|
168
|
+
inserted = 1;
|
169
|
+
}
|
170
|
+
else
|
171
|
+
{
|
172
|
+
cmp = strcmp(item->key, ht->items[i]->key);
|
173
|
+
if (cmp > 0)
|
174
|
+
{
|
175
|
+
tmp[i] = item;
|
176
|
+
tmp[i + 1] = ht->items[cursor];
|
177
|
+
inserted = 1;
|
178
|
+
cursor++;
|
179
|
+
i++;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
183
|
+
else
|
184
|
+
{
|
185
|
+
tmp[i] = ht->items[cursor];
|
186
|
+
cursor++;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
free(ht->items);
|
190
|
+
ht->items = tmp;
|
191
|
+
ht->size++;
|
192
|
+
}
|
193
|
+
|
194
|
+
/*
|
195
|
+
* Add an item to the hash table
|
196
|
+
*/
|
197
|
+
void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size)
|
198
|
+
{
|
199
|
+
ht_insert_key(ht, key, value, size);
|
200
|
+
}
|
201
|
+
|
202
|
+
/*
|
203
|
+
* Get the key's value or NULL if it doesn't exist
|
204
|
+
*/
|
205
|
+
ht_long_array *ht_search(ht_hash_table *ht, char *key)
|
206
|
+
{
|
207
|
+
return ht_search_key(ht, key);
|
208
|
+
}
|
209
|
+
|
210
|
+
/*
|
211
|
+
* Delete the key's item if it exists
|
212
|
+
*/
|
213
|
+
void ht_delete(ht_hash_table *ht, char *key)
|
214
|
+
{
|
215
|
+
ht_delete_key(ht, key);
|
216
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#ifndef HASH_TABLE_H_
|
2
|
+
#define HASH_TABLE_H_
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
typedef struct ht_long_array
|
7
|
+
{
|
8
|
+
long *items;
|
9
|
+
long size;
|
10
|
+
} ht_long_array;
|
11
|
+
|
12
|
+
// ht_item is an item in the hash table
|
13
|
+
typedef struct ht_item
|
14
|
+
{
|
15
|
+
char *key;
|
16
|
+
ht_long_array *value;
|
17
|
+
} ht_item;
|
18
|
+
|
19
|
+
typedef struct ht_hash_table
|
20
|
+
{
|
21
|
+
long size;
|
22
|
+
ht_item **items;
|
23
|
+
} ht_hash_table;
|
24
|
+
|
25
|
+
ht_hash_table *ht_new();
|
26
|
+
void ht_del_hash_table(ht_hash_table *ht);
|
27
|
+
|
28
|
+
void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size);
|
29
|
+
ht_long_array *ht_search(ht_hash_table *ht, char *key);
|
30
|
+
void ht_delete(ht_hash_table *h, char *key);
|
31
|
+
|
32
|
+
#endif // HASH_TABLE_H_
|
data/ext/readapt/monitor.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#include "ruby/debug.h"
|
3
3
|
#include "threads.h"
|
4
4
|
#include "normalize.h"
|
5
|
+
#include "breakpoints.h"
|
5
6
|
|
6
7
|
static VALUE readapt;
|
7
8
|
static VALUE m_Monitor;
|
@@ -14,39 +15,16 @@ static VALUE tpReturn;
|
|
14
15
|
static VALUE tpThreadBegin;
|
15
16
|
static VALUE tpThreadEnd;
|
16
17
|
static VALUE debugProc;
|
17
|
-
static VALUE breakpoints;
|
18
|
-
static int knownBreakpoints;
|
19
18
|
static int firstLineEvent = 0;
|
19
|
+
static VALUE entryFile;
|
20
20
|
|
21
|
-
static
|
22
|
-
|
23
|
-
|
24
|
-
return 1;
|
25
|
-
}
|
26
|
-
return 0;
|
27
|
-
}
|
28
|
-
|
29
|
-
static int match_breakpoint(VALUE file, int line)
|
30
|
-
{
|
31
|
-
VALUE bps, b;
|
32
|
-
long len, i;
|
33
|
-
|
34
|
-
bps = rb_funcall(breakpoints, rb_intern("for"), 1, file);
|
35
|
-
len = rb_array_len(bps);
|
36
|
-
for (i = 0; i < len; i++)
|
37
|
-
{
|
38
|
-
b = rb_ary_entry(bps, i);
|
39
|
-
if (NUM2INT(rb_funcall(b, rb_intern("line"), 0)) == line)
|
40
|
-
{
|
41
|
-
return 1;
|
42
|
-
}
|
43
|
-
}
|
44
|
-
return 0;
|
45
|
-
}
|
21
|
+
static ID id_continue;
|
22
|
+
static ID id_pause;
|
23
|
+
static ID id_entry;
|
46
24
|
|
47
25
|
static int match_step(thread_reference_t *ptr)
|
48
26
|
{
|
49
|
-
if (ptr->control ==
|
27
|
+
if (ptr->control == id_continue)
|
50
28
|
{
|
51
29
|
return 0;
|
52
30
|
}
|
@@ -66,7 +44,7 @@ static int match_step(thread_reference_t *ptr)
|
|
66
44
|
}
|
67
45
|
|
68
46
|
static ID
|
69
|
-
monitor_debug(VALUE file,
|
47
|
+
monitor_debug(VALUE file, long line, VALUE tracepoint, thread_reference_t *ptr, ID event)
|
70
48
|
{
|
71
49
|
VALUE bind, bid, snapshot, result;
|
72
50
|
|
@@ -90,8 +68,6 @@ monitor_debug(VALUE file, int line, VALUE tracepoint, thread_reference_t *ptr, I
|
|
90
68
|
ptr->cursor = ptr->depth;
|
91
69
|
ptr->control = result;
|
92
70
|
}
|
93
|
-
ptr->prev_file = file;
|
94
|
-
ptr->prev_line = line;
|
95
71
|
return result;
|
96
72
|
}
|
97
73
|
|
@@ -99,67 +75,57 @@ static void
|
|
99
75
|
process_line_event(VALUE tracepoint, void *data)
|
100
76
|
{
|
101
77
|
VALUE ref, tp_file;
|
102
|
-
|
78
|
+
long tp_line;
|
103
79
|
thread_reference_t *ptr;
|
104
80
|
rb_trace_arg_t *tp;
|
105
81
|
int threadPaused;
|
106
|
-
ID dapEvent
|
82
|
+
ID dapEvent;
|
107
83
|
|
108
84
|
ref = thread_current_reference();
|
109
85
|
if (ref != Qnil)
|
110
86
|
{
|
111
87
|
ptr = thread_reference_pointer(ref);
|
112
|
-
if (ptr->depth > 0
|
88
|
+
if (ptr->depth > 0)
|
113
89
|
{
|
114
|
-
threadPaused = (ptr->control ==
|
115
|
-
if (
|
90
|
+
threadPaused = (ptr->control == id_pause);
|
91
|
+
if (firstLineEvent && ptr->control == id_continue && breakpoints_files() == 0)
|
116
92
|
{
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
if (!firstLineEvent)
|
123
|
-
{
|
124
|
-
dapEvent = rb_intern("initialize");
|
125
|
-
}
|
126
|
-
else if (threadPaused)
|
127
|
-
{
|
128
|
-
dapEvent = rb_intern("pause");
|
129
|
-
}
|
130
|
-
else if (match_step(ptr))
|
131
|
-
{
|
132
|
-
dapEvent = rb_intern("step");
|
133
|
-
}
|
134
|
-
else if (match_breakpoint(tp_file, tp_line))
|
135
|
-
{
|
136
|
-
dapEvent = rb_intern("breakpoint");
|
137
|
-
}
|
138
|
-
else if (ptr->control == rb_intern("entry"))
|
139
|
-
{
|
140
|
-
dapEvent = rb_intern("entry");
|
141
|
-
}
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
tp = rb_tracearg_from_tracepoint(tracepoint);
|
96
|
+
tp_file = normalize_path(rb_tracearg_path(tp));
|
97
|
+
tp_line = NUM2LONG(rb_tracearg_lineno(tp));
|
142
98
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
{
|
148
|
-
firstLineEvent = 1;
|
149
|
-
ptr->control = rb_intern("entry");
|
150
|
-
process_line_event(tracepoint, data);
|
151
|
-
}
|
152
|
-
}
|
153
|
-
else
|
99
|
+
dapEvent = id_continue;
|
100
|
+
if (!firstLineEvent)
|
101
|
+
{
|
102
|
+
if (rb_str_equal(tp_file, entryFile))
|
154
103
|
{
|
155
|
-
|
156
|
-
ptr->
|
104
|
+
firstLineEvent = 1;
|
105
|
+
ptr->control = rb_intern("entry");
|
106
|
+
process_line_event(tracepoint, data);
|
157
107
|
}
|
158
108
|
}
|
159
|
-
else
|
109
|
+
else if (threadPaused)
|
110
|
+
{
|
111
|
+
dapEvent = id_pause;
|
112
|
+
}
|
113
|
+
else if (match_step(ptr))
|
114
|
+
{
|
115
|
+
dapEvent = rb_intern("step");
|
116
|
+
}
|
117
|
+
else if (breakpoints_match(StringValueCStr(tp_file), tp_line))
|
118
|
+
{
|
119
|
+
dapEvent = rb_intern("breakpoint");
|
120
|
+
}
|
121
|
+
else if (ptr->control == id_entry)
|
122
|
+
{
|
123
|
+
dapEvent = id_entry;
|
124
|
+
}
|
125
|
+
|
126
|
+
if (dapEvent != id_continue)
|
160
127
|
{
|
161
|
-
ptr
|
162
|
-
ptr->prev_line = Qnil;
|
128
|
+
monitor_debug(tp_file, tp_line, tracepoint, ptr, dapEvent);
|
163
129
|
}
|
164
130
|
}
|
165
131
|
}
|
@@ -214,7 +180,7 @@ process_thread_begin_event(VALUE tracepoint, void *data)
|
|
214
180
|
ptr = thread_reference_pointer(ref);
|
215
181
|
monitor_debug(
|
216
182
|
rb_funcall(tracepoint, rb_intern("path"), 0),
|
217
|
-
|
183
|
+
NUM2LONG(rb_funcall(tracepoint, rb_intern("lineno"), 0)),
|
218
184
|
tracepoint,
|
219
185
|
ptr,
|
220
186
|
rb_intern("thread_begin")
|
@@ -236,13 +202,13 @@ process_thread_end_event(VALUE tracepoint, void *data)
|
|
236
202
|
if (ref != Qnil)
|
237
203
|
{
|
238
204
|
ptr = thread_reference_pointer(ref);
|
239
|
-
monitor_debug(
|
205
|
+
monitor_debug(rb_funcall(tracepoint, rb_intern("path"), 0), NUM2LONG(rb_funcall(tracepoint, rb_intern("lineno"), 0)), tracepoint, ptr, rb_intern("thread_end"));
|
240
206
|
thread_delete_reference(thr);
|
241
207
|
}
|
242
208
|
}
|
243
209
|
|
244
210
|
static VALUE
|
245
|
-
monitor_enable_s(VALUE self)
|
211
|
+
monitor_enable_s(VALUE self, VALUE file)
|
246
212
|
{
|
247
213
|
VALUE previous, ref;
|
248
214
|
thread_reference_t *ptr;
|
@@ -254,7 +220,8 @@ monitor_enable_s(VALUE self)
|
|
254
220
|
rb_raise(rb_eArgError, "must be called with a block");
|
255
221
|
}
|
256
222
|
|
257
|
-
|
223
|
+
entryFile = file;
|
224
|
+
firstLineEvent = (entryFile == Qnil ? 1 : 0);
|
258
225
|
|
259
226
|
ref = thread_add_reference(rb_thread_current());
|
260
227
|
ptr = thread_reference_pointer(ref);
|
@@ -286,7 +253,7 @@ monitor_disable_s(VALUE self)
|
|
286
253
|
rb_tracepoint_disable(tpReturn);
|
287
254
|
rb_tracepoint_disable(tpThreadBegin);
|
288
255
|
rb_tracepoint_disable(tpThreadEnd);
|
289
|
-
|
256
|
+
|
290
257
|
return previous;
|
291
258
|
}
|
292
259
|
|
@@ -302,12 +269,6 @@ monitor_pause_s(VALUE self, VALUE id)
|
|
302
269
|
ptr = thread_reference_pointer(ref);
|
303
270
|
ptr->control = rb_intern("pause");
|
304
271
|
}
|
305
|
-
}
|
306
|
-
|
307
|
-
static VALUE
|
308
|
-
monitor_know_breakpoints_s(VALUE self)
|
309
|
-
{
|
310
|
-
knownBreakpoints = (rb_funcall(breakpoints, rb_intern("empty?"), 0) == Qfalse) ? 1 : 0;
|
311
272
|
return Qnil;
|
312
273
|
}
|
313
274
|
|
@@ -319,9 +280,8 @@ void initialize_monitor(VALUE m_Readapt)
|
|
319
280
|
|
320
281
|
initialize_threads();
|
321
282
|
|
322
|
-
rb_define_singleton_method(m_Monitor, "start", monitor_enable_s,
|
283
|
+
rb_define_singleton_method(m_Monitor, "start", monitor_enable_s, 1);
|
323
284
|
rb_define_singleton_method(m_Monitor, "stop", monitor_disable_s, 0);
|
324
|
-
rb_define_singleton_method(m_Monitor, "know_breakpoints", monitor_know_breakpoints_s, 0);
|
325
285
|
rb_define_singleton_method(m_Monitor, "pause", monitor_pause_s, 1);
|
326
286
|
|
327
287
|
tpLine = rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, process_line_event, NULL);
|
@@ -330,8 +290,10 @@ void initialize_monitor(VALUE m_Readapt)
|
|
330
290
|
tpThreadBegin = rb_tracepoint_new(Qnil, RUBY_EVENT_THREAD_BEGIN, process_thread_begin_event, NULL);
|
331
291
|
tpThreadEnd = rb_tracepoint_new(Qnil, RUBY_EVENT_THREAD_END, process_thread_end_event, NULL);
|
332
292
|
debugProc = Qnil;
|
333
|
-
|
334
|
-
|
293
|
+
|
294
|
+
id_continue = rb_intern("continue");
|
295
|
+
id_pause = rb_intern("pause");
|
296
|
+
id_entry = rb_intern("entry");
|
335
297
|
|
336
298
|
// Avoid garbage collection
|
337
299
|
rb_global_variable(&tpLine);
|
@@ -339,4 +301,5 @@ void initialize_monitor(VALUE m_Readapt)
|
|
339
301
|
rb_global_variable(&tpReturn);
|
340
302
|
rb_global_variable(&tpThreadBegin);
|
341
303
|
rb_global_variable(&tpThreadEnd);
|
304
|
+
rb_global_variable(&entryFile);
|
342
305
|
}
|
data/ext/readapt/monitor.h
CHANGED
data/ext/readapt/normalize.c
CHANGED
data/ext/readapt/normalize.h
CHANGED
data/ext/readapt/readapt.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#include "ruby/debug.h"
|
3
3
|
#include "monitor.h"
|
4
4
|
#include "normalize.h"
|
5
|
+
#include "breakpoints.h"
|
5
6
|
|
6
7
|
static VALUE m_Readapt;
|
7
8
|
|
@@ -10,5 +11,6 @@ void Init_readapt()
|
|
10
11
|
m_Readapt = rb_define_module("Readapt");
|
11
12
|
|
12
13
|
initialize_normalize(m_Readapt);
|
14
|
+
initialize_breakpoints(m_Readapt);
|
13
15
|
initialize_monitor(m_Readapt);
|
14
16
|
}
|
data/ext/readapt/threads.h
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
#ifndef THREADS_H_
|
2
|
+
#define THREADS_H_
|
3
|
+
|
1
4
|
typedef struct thread_reference_struct {
|
2
5
|
long id;
|
3
6
|
int depth;
|
4
7
|
int cursor;
|
5
|
-
VALUE prev_file;
|
6
|
-
int prev_line;
|
7
8
|
ID control;
|
8
9
|
} thread_reference_t;
|
9
10
|
|
@@ -16,3 +17,5 @@ VALUE thread_delete_reference(VALUE);
|
|
16
17
|
thread_reference_t *thread_reference_pointer(VALUE);
|
17
18
|
void thread_pause();
|
18
19
|
void thread_reset();
|
20
|
+
|
21
|
+
#endif
|
data/lib/readapt.rb
CHANGED
data/lib/readapt/debugger.rb
CHANGED
@@ -67,7 +67,7 @@ module Readapt
|
|
67
67
|
send_event('process', {
|
68
68
|
name: @file
|
69
69
|
})
|
70
|
-
Monitor.start do |snapshot|
|
70
|
+
Monitor.start @file do |snapshot|
|
71
71
|
debug snapshot
|
72
72
|
end
|
73
73
|
yield if block_given?
|
@@ -123,12 +123,6 @@ module Readapt
|
|
123
123
|
threadId: snapshot.thread_id
|
124
124
|
})
|
125
125
|
snapshot.control = :continue
|
126
|
-
elsif snapshot.event == :initialize
|
127
|
-
if snapshot.file != @file
|
128
|
-
snapshot.control = :wait
|
129
|
-
else
|
130
|
-
snapshot.control = :ready
|
131
|
-
end
|
132
126
|
elsif snapshot.event == :entry
|
133
127
|
snapshot.control = :continue
|
134
128
|
else
|
@@ -5,21 +5,16 @@ module Readapt
|
|
5
5
|
class SetBreakpoints < Base
|
6
6
|
def run
|
7
7
|
path = Readapt.normalize_path(arguments['source']['path'])
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
Breakpoint.new(path, l, true)
|
12
|
-
end
|
13
|
-
Monitor.breakpoints.concat result
|
14
|
-
set_body({
|
15
|
-
breakpoints: result.map { |bp|
|
8
|
+
Breakpoints.set(path, arguments['lines'])
|
9
|
+
set_body(
|
10
|
+
breakpoints: arguments['lines'].map do |l|
|
16
11
|
{
|
17
|
-
verified:
|
12
|
+
verified: true, # @todo Verify
|
18
13
|
source: arguments['source'],
|
19
|
-
line:
|
14
|
+
line: l
|
20
15
|
}
|
21
|
-
|
22
|
-
|
16
|
+
end
|
17
|
+
)
|
23
18
|
end
|
24
19
|
end
|
25
20
|
end
|
data/lib/readapt/monitor.rb
CHANGED
@@ -11,21 +11,5 @@ module Readapt
|
|
11
11
|
# Disable tracepoints.
|
12
12
|
# @return [Boolean]
|
13
13
|
module Monitor
|
14
|
-
@@breakpoints = Breakpoints.new
|
15
|
-
|
16
|
-
# @return [Breakpoints]
|
17
|
-
def self.breakpoints
|
18
|
-
@@breakpoints
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.set_breakpoints bps
|
22
|
-
@@breakpoints = bps
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.update
|
26
|
-
know_breakpoints
|
27
|
-
end
|
28
|
-
|
29
|
-
@@breakpoints.add_observer self
|
30
14
|
end
|
31
15
|
end
|
data/lib/readapt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: readapt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|
@@ -116,7 +116,11 @@ files:
|
|
116
116
|
- bin/console
|
117
117
|
- bin/setup
|
118
118
|
- exe/readapt
|
119
|
+
- ext/readapt/breakpoints.c
|
120
|
+
- ext/readapt/breakpoints.h
|
119
121
|
- ext/readapt/extconf.rb
|
122
|
+
- ext/readapt/hash_table.c
|
123
|
+
- ext/readapt/hash_table.h
|
120
124
|
- ext/readapt/monitor.c
|
121
125
|
- ext/readapt/monitor.h
|
122
126
|
- ext/readapt/normalize.c
|
@@ -126,8 +130,6 @@ files:
|
|
126
130
|
- ext/readapt/threads.h
|
127
131
|
- lib/readapt.rb
|
128
132
|
- lib/readapt/adapter.rb
|
129
|
-
- lib/readapt/breakpoint.rb
|
130
|
-
- lib/readapt/breakpoints.rb
|
131
133
|
- lib/readapt/debugger.rb
|
132
134
|
- lib/readapt/finder.rb
|
133
135
|
- lib/readapt/frame.rb
|
data/lib/readapt/breakpoint.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
class Breakpoint < Location
|
5
|
-
attr_reader :verified
|
6
|
-
|
7
|
-
def initialize file, line, verified = true
|
8
|
-
super(file, line)
|
9
|
-
@verified = verified
|
10
|
-
end
|
11
|
-
|
12
|
-
def enabled?
|
13
|
-
@verified
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/lib/readapt/breakpoints.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'observer'
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
class Breakpoints
|
5
|
-
include Observable
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@sources = {}
|
9
|
-
@concatting = false
|
10
|
-
end
|
11
|
-
|
12
|
-
# @return [Array<String>]
|
13
|
-
def sources
|
14
|
-
@sources.keys
|
15
|
-
end
|
16
|
-
|
17
|
-
# @param breakpoint [Breakpoint]
|
18
|
-
# @return [void]
|
19
|
-
def add breakpoint
|
20
|
-
@sources[breakpoint.file] ||= []
|
21
|
-
@sources[breakpoint.file].push breakpoint
|
22
|
-
changed
|
23
|
-
notify_observers unless @concatting
|
24
|
-
end
|
25
|
-
|
26
|
-
# @param breakpoints [Array<Breakpoint>]
|
27
|
-
# @return [void]
|
28
|
-
def concat breakpoints
|
29
|
-
@concatting = true
|
30
|
-
breakpoints.each { |bp| add bp }
|
31
|
-
@concatting = false
|
32
|
-
notify_observers
|
33
|
-
end
|
34
|
-
|
35
|
-
# @param file [String]
|
36
|
-
# @return [void]
|
37
|
-
def clear file
|
38
|
-
@sources.delete file
|
39
|
-
changed
|
40
|
-
notify_observers
|
41
|
-
end
|
42
|
-
|
43
|
-
# @param file [String]
|
44
|
-
# @return [Array<Breakpoint>]
|
45
|
-
def for file
|
46
|
-
@sources[file] || []
|
47
|
-
end
|
48
|
-
|
49
|
-
# @return [Array<Breakpoint>]
|
50
|
-
def all
|
51
|
-
@sources.values.flatten
|
52
|
-
end
|
53
|
-
|
54
|
-
def empty?
|
55
|
-
@sources.empty?
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|