readapt 1.1.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/CHANGELOG.md +19 -0
- data/ext/readapt/breakpoints.c +8 -8
- data/ext/readapt/{hash_table.c → lookup_table.c} +40 -40
- data/ext/readapt/lookup_table.h +30 -0
- data/ext/readapt/monitor.c +41 -4
- data/ext/readapt/threads.c +13 -2
- data/ext/readapt/threads.h +2 -1
- data/lib/readapt/breakpoint.rb +1 -0
- data/lib/readapt/debugger.rb +10 -3
- data/lib/readapt/finder.rb +14 -0
- data/lib/readapt/frame.rb +1 -1
- data/lib/readapt/message/initialize.rb +9 -1
- data/lib/readapt/message/set_exception_breakpoints.rb +3 -0
- data/lib/readapt/message/variables.rb +1 -9
- data/lib/readapt/output.rb +1 -1
- data/lib/readapt/thread.rb +4 -7
- data/lib/readapt/version.rb +1 -1
- data/readapt.gemspec +2 -2
- metadata +9 -9
- data/ext/readapt/hash_table.h +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 450c74c32434e471b61235c9dd00a6e7bcbe08b16c246af30c2a4bb99aa03376
|
4
|
+
data.tar.gz: 93929a65369b6effde74000165ffa2e65081bf136da35baa5e427bc0b1058eb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e980de040f9cef44e82bceba51d3679a123b4a840ec5b5e04b3aa5e14af410ce9e226e074ea543f90c7734c07b20790e90e60215a40120a54b7d133d7a3374e7
|
7
|
+
data.tar.gz: d688ab5daf6c98ccb5269f2dd09dc5e06498644c616f4d592b24be73576aa380e7704349226ee1fcf79ac76f92318e819d98e13de9a053328b8a75e5adb413ab
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
# 1.4.1 - July 8, 2021
|
2
|
+
- Thread object handling
|
3
|
+
- Rescue StandardError instead of Exception
|
4
|
+
|
5
|
+
# 1.4.0 - June 14, 2021
|
6
|
+
- Configurable exception breakpoints
|
7
|
+
- Update backport gem
|
8
|
+
|
9
|
+
# 1.3.0 - June 3, 2021
|
10
|
+
- Variables message reads class/instance variables
|
11
|
+
|
12
|
+
# 1.2.0 - February 24, 2021
|
13
|
+
- Pause on exceptions
|
14
|
+
- Refactored lookup tables
|
15
|
+
|
16
|
+
# 1.1.1 - December 15, 2020
|
17
|
+
- Update rake
|
18
|
+
- Fix Encoding::UndefinedConversionError (#8)
|
19
|
+
|
1
20
|
# 1.1.0 - September 13, 2020
|
2
21
|
- Use 32-bit integers for variable and thread references (#6)
|
3
22
|
|
data/ext/readapt/breakpoints.c
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#include "ruby.h"
|
2
|
-
#include "
|
2
|
+
#include "lookup_table.h"
|
3
3
|
|
4
4
|
static VALUE m_Breakpoints;
|
5
|
-
|
5
|
+
lt_lookup_table *ht;
|
6
6
|
|
7
7
|
void breakpoints_set(char *file, long *lines)
|
8
8
|
{
|
@@ -20,7 +20,7 @@ static VALUE breakpoints_set_s(VALUE self, VALUE file, VALUE lines)
|
|
20
20
|
{
|
21
21
|
ll[i] = NUM2LONG(rb_ary_entry(lines, i));
|
22
22
|
}
|
23
|
-
|
23
|
+
lt_insert(ht, StringValueCStr(file), ll, length);
|
24
24
|
free(ll);
|
25
25
|
return Qnil;
|
26
26
|
}
|
@@ -37,10 +37,10 @@ static VALUE breakpoints_delete_s(VALUE self, VALUE file)
|
|
37
37
|
|
38
38
|
int breakpoints_match(char *file, long line)
|
39
39
|
{
|
40
|
-
|
40
|
+
lt_long_array *lines;
|
41
41
|
long i;
|
42
42
|
|
43
|
-
lines =
|
43
|
+
lines = lt_search(ht, file);
|
44
44
|
if (lines != NULL)
|
45
45
|
{
|
46
46
|
for (i = 0; i < lines->size; i++)
|
@@ -61,8 +61,8 @@ static VALUE breakpoints_match_s(VALUE self, VALUE file, VALUE line)
|
|
61
61
|
|
62
62
|
static VALUE breakpoints_clear_s(VALUE self)
|
63
63
|
{
|
64
|
-
|
65
|
-
ht =
|
64
|
+
lt_del_lookup_table(ht);
|
65
|
+
ht = lt_new();
|
66
66
|
return Qnil;
|
67
67
|
}
|
68
68
|
|
@@ -79,5 +79,5 @@ void initialize_breakpoints(VALUE m_Readapt)
|
|
79
79
|
rb_define_singleton_method(m_Breakpoints, "match", breakpoints_match_s, 2);
|
80
80
|
rb_define_singleton_method(m_Breakpoints, "clear", breakpoints_clear_s, 0);
|
81
81
|
|
82
|
-
ht =
|
82
|
+
ht = lt_new(); // TODO Need to free?
|
83
83
|
}
|
@@ -2,19 +2,19 @@
|
|
2
2
|
#include <stdlib.h>
|
3
3
|
#include <string.h>
|
4
4
|
|
5
|
-
#include "
|
5
|
+
#include "lookup_table.h"
|
6
6
|
|
7
|
-
static
|
7
|
+
static lt_long_array *copy_array(const long *value, const long size)
|
8
8
|
{
|
9
9
|
long i;
|
10
10
|
long *items = malloc(sizeof(long) * size);
|
11
|
-
|
11
|
+
lt_long_array *result;
|
12
12
|
|
13
13
|
for (i = 0; i < size; i++)
|
14
14
|
{
|
15
15
|
items[i] = value[i];
|
16
16
|
}
|
17
|
-
result = malloc(sizeof(
|
17
|
+
result = malloc(sizeof(lt_long_array));
|
18
18
|
result->items = (size ? items : NULL);
|
19
19
|
result->size = size;
|
20
20
|
return result;
|
@@ -23,9 +23,9 @@ static ht_long_array *copy_array(const long *value, const long size)
|
|
23
23
|
/*
|
24
24
|
* Initialize a new item
|
25
25
|
*/
|
26
|
-
static
|
26
|
+
static lt_item *lt_new_item(char *key, const long *value, const long size)
|
27
27
|
{
|
28
|
-
|
28
|
+
lt_item *i = malloc(sizeof(lt_item));
|
29
29
|
i->key = malloc(sizeof(char) * (strlen(key) + 1));
|
30
30
|
strcpy(i->key, key);
|
31
31
|
i->value = copy_array(value, size);
|
@@ -33,9 +33,9 @@ static ht_item *ht_new_item(char *key, const long *value, const long size)
|
|
33
33
|
}
|
34
34
|
|
35
35
|
/*
|
36
|
-
* Delete the
|
36
|
+
* Delete the lt_item
|
37
37
|
*/
|
38
|
-
static void
|
38
|
+
static void lt_del_item(lt_item *i)
|
39
39
|
{
|
40
40
|
free(i->key);
|
41
41
|
free(i->value->items);
|
@@ -43,35 +43,35 @@ static void ht_del_item(ht_item *i)
|
|
43
43
|
}
|
44
44
|
|
45
45
|
/*
|
46
|
-
* Initialize a new empty
|
46
|
+
* Initialize a new empty lookup table
|
47
47
|
*/
|
48
|
-
|
48
|
+
lt_lookup_table *lt_new()
|
49
49
|
{
|
50
|
-
|
50
|
+
lt_lookup_table *ht = malloc(sizeof(lt_lookup_table));
|
51
51
|
ht->items = NULL;
|
52
52
|
ht->size = 0;
|
53
53
|
return ht;
|
54
54
|
}
|
55
55
|
|
56
56
|
/*
|
57
|
-
* Delete the
|
57
|
+
* Delete the lookup table
|
58
58
|
*/
|
59
|
-
void
|
59
|
+
void lt_del_lookup_table(lt_lookup_table *ht)
|
60
60
|
{
|
61
61
|
int i;
|
62
|
-
|
62
|
+
lt_item *item;
|
63
63
|
|
64
64
|
// Iterate through items and delete any that are found
|
65
65
|
for (i = 0; i < ht->size; i++)
|
66
66
|
{
|
67
67
|
item = ht->items[i];
|
68
|
-
|
68
|
+
lt_del_item(item);
|
69
69
|
}
|
70
70
|
free(ht->items);
|
71
71
|
free(ht);
|
72
72
|
}
|
73
73
|
|
74
|
-
static
|
74
|
+
static lt_long_array *lt_search_part(lt_lookup_table *ht, char *key, long cursor, long next)
|
75
75
|
{
|
76
76
|
int cmp;
|
77
77
|
|
@@ -94,37 +94,37 @@ static ht_long_array *ht_search_part(ht_hash_table *ht, char *key, long cursor,
|
|
94
94
|
}
|
95
95
|
else if (cmp < 0)
|
96
96
|
{
|
97
|
-
return
|
97
|
+
return lt_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
|
98
98
|
}
|
99
99
|
else
|
100
100
|
{
|
101
|
-
return
|
101
|
+
return lt_search_part(ht, key, cursor + 1, next / 2);
|
102
102
|
}
|
103
103
|
}
|
104
|
-
return
|
104
|
+
return lt_search_part(ht, key, cursor + 1, next / 2);
|
105
105
|
}
|
106
106
|
|
107
|
-
static
|
107
|
+
static lt_long_array *lt_search_key(lt_lookup_table *ht, char *key)
|
108
108
|
{
|
109
|
-
return
|
109
|
+
return lt_search_part(ht, key, 0, ht->size / 2);
|
110
110
|
}
|
111
111
|
|
112
|
-
static void
|
112
|
+
static void lt_delete_key(lt_lookup_table *ht, char *key)
|
113
113
|
{
|
114
|
-
|
115
|
-
|
114
|
+
lt_long_array *found;
|
115
|
+
lt_item **tmp;
|
116
116
|
long i;
|
117
117
|
long cursor = 0;
|
118
118
|
|
119
|
-
found =
|
119
|
+
found = lt_search_key(ht, key);
|
120
120
|
if (found)
|
121
121
|
{
|
122
|
-
tmp = malloc(sizeof(
|
122
|
+
tmp = malloc(sizeof(lt_item) * (ht->size - 1));
|
123
123
|
for (i = 0; i < ht->size; i++)
|
124
124
|
{
|
125
125
|
if (ht->items[i]->key == key)
|
126
126
|
{
|
127
|
-
|
127
|
+
lt_del_item(ht->items[i]);
|
128
128
|
}
|
129
129
|
else
|
130
130
|
{
|
@@ -138,24 +138,24 @@ static void ht_delete_key(ht_hash_table *ht, char *key)
|
|
138
138
|
}
|
139
139
|
}
|
140
140
|
|
141
|
-
static void
|
141
|
+
static void lt_insert_key(lt_lookup_table *ht, char *key, const long *value, const long size)
|
142
142
|
{
|
143
|
-
|
144
|
-
|
143
|
+
lt_item *item;
|
144
|
+
lt_item **tmp;
|
145
145
|
long i;
|
146
146
|
long cursor = 0;
|
147
147
|
int inserted = 0;
|
148
148
|
int cmp;
|
149
149
|
|
150
|
-
|
150
|
+
lt_delete_key(ht, key);
|
151
151
|
|
152
152
|
if (size == 0)
|
153
153
|
{
|
154
154
|
return;
|
155
155
|
}
|
156
156
|
|
157
|
-
item =
|
158
|
-
tmp = malloc(sizeof(
|
157
|
+
item = lt_new_item(key, value, size);
|
158
|
+
tmp = malloc(sizeof(lt_item) * (ht->size + 1));
|
159
159
|
|
160
160
|
for (i = 0; i < ht->size; i++)
|
161
161
|
{
|
@@ -187,25 +187,25 @@ static void ht_insert_key(ht_hash_table *ht, char *key, const long *value, const
|
|
187
187
|
}
|
188
188
|
|
189
189
|
/*
|
190
|
-
* Add an item to the
|
190
|
+
* Add an item to the lookup table
|
191
191
|
*/
|
192
|
-
void
|
192
|
+
void lt_insert(lt_lookup_table *ht, char *key, const long *value, const long size)
|
193
193
|
{
|
194
|
-
|
194
|
+
lt_insert_key(ht, key, value, size);
|
195
195
|
}
|
196
196
|
|
197
197
|
/*
|
198
198
|
* Get the key's value or NULL if it doesn't exist
|
199
199
|
*/
|
200
|
-
|
200
|
+
lt_long_array *lt_search(lt_lookup_table *ht, char *key)
|
201
201
|
{
|
202
|
-
return
|
202
|
+
return lt_search_key(ht, key);
|
203
203
|
}
|
204
204
|
|
205
205
|
/*
|
206
206
|
* Delete the key's item if it exists
|
207
207
|
*/
|
208
|
-
void
|
208
|
+
void lt_delete(lt_lookup_table *ht, char *key)
|
209
209
|
{
|
210
|
-
|
210
|
+
lt_delete_key(ht, key);
|
211
211
|
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#ifndef LOOKUP_TABLE_H_
|
2
|
+
#define LOOKUP_TABLE_H_
|
3
|
+
|
4
|
+
typedef struct lt_long_array
|
5
|
+
{
|
6
|
+
long *items;
|
7
|
+
long size;
|
8
|
+
} lt_long_array;
|
9
|
+
|
10
|
+
// lt_item is an item in the lookup table
|
11
|
+
typedef struct lt_item
|
12
|
+
{
|
13
|
+
char *key;
|
14
|
+
lt_long_array *value;
|
15
|
+
} lt_item;
|
16
|
+
|
17
|
+
typedef struct lt_lookup_table
|
18
|
+
{
|
19
|
+
long size;
|
20
|
+
lt_item **items;
|
21
|
+
} lt_lookup_table;
|
22
|
+
|
23
|
+
lt_lookup_table *lt_new();
|
24
|
+
void lt_del_lookup_table(lt_lookup_table *ht);
|
25
|
+
|
26
|
+
void lt_insert(lt_lookup_table *ht, char *key, const long *value, const long size);
|
27
|
+
lt_long_array *lt_search(lt_lookup_table *ht, char *key);
|
28
|
+
void lt_delete(lt_lookup_table *h, char *key);
|
29
|
+
|
30
|
+
#endif // LOOKUP_TABLE_H_
|
data/ext/readapt/monitor.c
CHANGED
@@ -14,6 +14,7 @@ static VALUE tpCall;
|
|
14
14
|
static VALUE tpReturn;
|
15
15
|
static VALUE tpThreadBegin;
|
16
16
|
static VALUE tpThreadEnd;
|
17
|
+
static VALUE tpRaise;
|
17
18
|
static VALUE debugProc;
|
18
19
|
static int firstLineEvent = 0;
|
19
20
|
static char *entryFile;
|
@@ -99,7 +100,6 @@ process_line_event(VALUE tracepoint, void *data)
|
|
99
100
|
|
100
101
|
arg = rb_tracearg_from_tracepoint(tracepoint);
|
101
102
|
tmp = rb_tracearg_path(arg);
|
102
|
-
// tp_file = normalize_path_new_cstr(StringValueCStr(tmp));
|
103
103
|
tp_file = StringValueCStr(tmp);
|
104
104
|
normalize_path(tp_file);
|
105
105
|
tmp = rb_tracearg_lineno(arg);
|
@@ -136,8 +136,6 @@ process_line_event(VALUE tracepoint, void *data)
|
|
136
136
|
{
|
137
137
|
monitor_debug(tp_file, tp_line, tracepoint, ptr, dapEvent);
|
138
138
|
}
|
139
|
-
|
140
|
-
// free(tp_file);
|
141
139
|
}
|
142
140
|
}
|
143
141
|
|
@@ -210,6 +208,40 @@ process_thread_end_event(VALUE tracepoint, void *data)
|
|
210
208
|
}
|
211
209
|
}
|
212
210
|
|
211
|
+
static void
|
212
|
+
process_raise_event(VALUE tracepoint, void *data)
|
213
|
+
{
|
214
|
+
rb_trace_arg_t *arg;
|
215
|
+
VALUE exception;
|
216
|
+
VALUE ref;
|
217
|
+
thread_reference_t *ptr;
|
218
|
+
VALUE tmp;
|
219
|
+
char *tp_file;
|
220
|
+
long tp_line;
|
221
|
+
|
222
|
+
ref = thread_current_reference();
|
223
|
+
if (ref != Qnil)
|
224
|
+
{
|
225
|
+
arg = rb_tracearg_from_tracepoint(tracepoint);
|
226
|
+
exception = rb_tracearg_raised_exception(arg);
|
227
|
+
if (rb_class_inherited_p(rb_obj_class(exception), rb_eStandardError)) {
|
228
|
+
ptr = thread_reference_pointer(ref);
|
229
|
+
tmp = rb_tracearg_path(arg);
|
230
|
+
tp_file = StringValueCStr(tmp);
|
231
|
+
normalize_path(tp_file);
|
232
|
+
tmp = rb_tracearg_lineno(arg);
|
233
|
+
tp_line = NUM2INT(tmp);
|
234
|
+
monitor_debug(
|
235
|
+
tp_file,
|
236
|
+
tp_line,
|
237
|
+
tracepoint,
|
238
|
+
ptr,
|
239
|
+
rb_intern("raise")
|
240
|
+
);
|
241
|
+
}
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
213
245
|
static VALUE
|
214
246
|
monitor_enable_s(VALUE self, VALUE file)
|
215
247
|
{
|
@@ -218,7 +250,6 @@ monitor_enable_s(VALUE self, VALUE file)
|
|
218
250
|
|
219
251
|
if (rb_block_given_p()) {
|
220
252
|
debugProc = rb_block_proc();
|
221
|
-
rb_global_variable(&debugProc);
|
222
253
|
} else {
|
223
254
|
rb_raise(rb_eArgError, "must be called with a block");
|
224
255
|
}
|
@@ -250,6 +281,7 @@ monitor_enable_s(VALUE self, VALUE file)
|
|
250
281
|
rb_tracepoint_enable(tpReturn);
|
251
282
|
rb_tracepoint_enable(tpThreadBegin);
|
252
283
|
rb_tracepoint_enable(tpThreadEnd);
|
284
|
+
rb_tracepoint_enable(tpRaise);
|
253
285
|
return previous;
|
254
286
|
}
|
255
287
|
|
@@ -264,6 +296,7 @@ monitor_disable_s(VALUE self)
|
|
264
296
|
rb_tracepoint_disable(tpReturn);
|
265
297
|
rb_tracepoint_disable(tpThreadBegin);
|
266
298
|
rb_tracepoint_disable(tpThreadEnd);
|
299
|
+
rb_tracepoint_disable(tpRaise);
|
267
300
|
|
268
301
|
free(entryFile);
|
269
302
|
entryFile = NULL;
|
@@ -304,6 +337,7 @@ void initialize_monitor(VALUE m_Readapt)
|
|
304
337
|
tpReturn = rb_tracepoint_new(Qnil, RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_END | RUBY_EVENT_C_RETURN, process_return_event, NULL);
|
305
338
|
tpThreadBegin = rb_tracepoint_new(Qnil, RUBY_EVENT_THREAD_BEGIN, process_thread_begin_event, NULL);
|
306
339
|
tpThreadEnd = rb_tracepoint_new(Qnil, RUBY_EVENT_THREAD_END, process_thread_end_event, NULL);
|
340
|
+
tpRaise = rb_tracepoint_new(Qnil, RUBY_EVENT_RAISE, process_raise_event, NULL);
|
307
341
|
debugProc = Qnil;
|
308
342
|
|
309
343
|
id_continue = rb_intern("continue");
|
@@ -316,4 +350,7 @@ void initialize_monitor(VALUE m_Readapt)
|
|
316
350
|
rb_global_variable(&tpReturn);
|
317
351
|
rb_global_variable(&tpThreadBegin);
|
318
352
|
rb_global_variable(&tpThreadEnd);
|
353
|
+
rb_global_variable(&tpRaise);
|
354
|
+
|
355
|
+
rb_global_variable(&debugProc);
|
319
356
|
}
|
data/ext/readapt/threads.c
CHANGED
@@ -43,7 +43,8 @@ static VALUE thread_reference_new(VALUE thr)
|
|
43
43
|
data->depth = 0;
|
44
44
|
data->control = rb_intern("continue");
|
45
45
|
data->frames = stack_alloc(sizeof(frame_t), frame_free);
|
46
|
-
|
46
|
+
data->thread_object_id = NUM2LONG(rb_obj_id(thr));
|
47
|
+
next_id++;
|
47
48
|
return obj;
|
48
49
|
}
|
49
50
|
|
@@ -165,6 +166,15 @@ static VALUE frames_m(VALUE self)
|
|
165
166
|
return ary;
|
166
167
|
}
|
167
168
|
|
169
|
+
static VALUE thread_object_id_m(VALUE self)
|
170
|
+
{
|
171
|
+
thread_reference_t *data;
|
172
|
+
|
173
|
+
data = thread_reference_pointer(self);
|
174
|
+
return LONG2NUM(data->thread_object_id);
|
175
|
+
// return rb_hash_aref(ids, INT2NUM(data->id))->object_id;
|
176
|
+
}
|
177
|
+
|
168
178
|
void thread_reference_build_frames(thread_reference_t *ptr)
|
169
179
|
{
|
170
180
|
inspector_inspect(ptr);
|
@@ -184,7 +194,8 @@ void initialize_threads(VALUE m_Readapt)
|
|
184
194
|
rb_define_alloc_func(c_Thread, thread_allocate_s);
|
185
195
|
rb_define_method(c_Thread, "id", thread_id_m, 0);
|
186
196
|
rb_define_method(c_Thread, "frames", frames_m, 0);
|
187
|
-
|
197
|
+
rb_define_method(c_Thread, "thread_object_id", thread_object_id_m, 0);
|
198
|
+
rb_define_singleton_method(c_Thread, "all", thread_all_s, 0);
|
188
199
|
rb_define_singleton_method(c_Thread, "find", thread_find_s, 1);
|
189
200
|
rb_define_singleton_method(c_Thread, "include?", thread_include_s, 1);
|
190
201
|
|
data/ext/readapt/threads.h
CHANGED
data/lib/readapt/breakpoint.rb
CHANGED
data/lib/readapt/debugger.rb
CHANGED
@@ -13,6 +13,8 @@ module Readapt
|
|
13
13
|
|
14
14
|
attr_reader :file
|
15
15
|
|
16
|
+
attr_writer :pause_on_raise
|
17
|
+
|
16
18
|
def initialize
|
17
19
|
@stack = []
|
18
20
|
@frames = {}
|
@@ -33,6 +35,10 @@ module Readapt
|
|
33
35
|
STDERR.puts e.message
|
34
36
|
end
|
35
37
|
|
38
|
+
def pause_on_raise?
|
39
|
+
@pause_on_raise ||= false
|
40
|
+
end
|
41
|
+
|
36
42
|
# @return [Readapt::Thread]
|
37
43
|
def thread id
|
38
44
|
Thread.find(id)
|
@@ -119,7 +125,6 @@ module Readapt
|
|
119
125
|
# @param [Snapshot]
|
120
126
|
# return [void]
|
121
127
|
def debug snapshot
|
122
|
-
sleep 0.001 # @todo Trying to let thread data sync
|
123
128
|
References.clear
|
124
129
|
if snapshot.event == :thread_begin || snapshot.event == :entry
|
125
130
|
thr = Thread.find(snapshot.thread_id)
|
@@ -149,7 +154,7 @@ module Readapt
|
|
149
154
|
unless bnd.eval(bp.condition)
|
150
155
|
confirmed_pause = false
|
151
156
|
end
|
152
|
-
rescue
|
157
|
+
rescue StandardError => e
|
153
158
|
STDERR.puts "Breakpoint condition raised an error"
|
154
159
|
STDERR.puts "#{snapshot.file}:#{snapshot.line} - `#{bp.condition}`"
|
155
160
|
STDERR.puts "[#{e.class}] #{e.message}"
|
@@ -166,13 +171,15 @@ module Readapt
|
|
166
171
|
else
|
167
172
|
confirmed_pause = false
|
168
173
|
end
|
169
|
-
rescue
|
174
|
+
rescue StandardError => e
|
170
175
|
STDERR.puts "Breakpoint condition raised an error"
|
171
176
|
STDERR.puts "#{snapshot.file}:#{snapshot.line} - `#{bp.condition}`"
|
172
177
|
STDERR.puts "[#{e.class}] #{e.message}"
|
173
178
|
confirmed_pause = false
|
174
179
|
end
|
175
180
|
end
|
181
|
+
elsif snapshot.event == :raise && !pause_on_raise?
|
182
|
+
confirmed_pause = false
|
176
183
|
end
|
177
184
|
if confirmed_pause
|
178
185
|
changed
|
data/lib/readapt/finder.rb
CHANGED
@@ -1,14 +1,28 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
|
3
3
|
module Readapt
|
4
|
+
# Methods to find a program in the current directory or one of the
|
5
|
+
# environment paths.
|
6
|
+
#
|
4
7
|
module Finder
|
5
8
|
module_function
|
6
9
|
|
10
|
+
# Get the program's fully qualified path. Search first in the current
|
11
|
+
# directory, then the environment paths.
|
12
|
+
#
|
13
|
+
# @raise [LoadError] if the program was not found
|
14
|
+
#
|
15
|
+
# @param program [String] The name of the program
|
16
|
+
# @return [String] The fully qualified path
|
7
17
|
def find program
|
8
18
|
return program if File.exist?(program)
|
9
19
|
which(program) || raise(LoadError, "#{program} is not a valid Ruby file or program")
|
10
20
|
end
|
11
21
|
|
22
|
+
# Search the environment paths for the given program.
|
23
|
+
#
|
24
|
+
# @param program [String] The name of the program
|
25
|
+
# @return [String] The fully qualified path, or nil if it was not found
|
12
26
|
def which program
|
13
27
|
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
14
28
|
exe = File.join(path, program)
|
data/lib/readapt/frame.rb
CHANGED
@@ -5,7 +5,15 @@ module Readapt
|
|
5
5
|
class Initialize < Base
|
6
6
|
def run
|
7
7
|
set_body({
|
8
|
-
supportsConfigurationDoneRequest: true
|
8
|
+
supportsConfigurationDoneRequest: true,
|
9
|
+
exceptionBreakpointFilters: [
|
10
|
+
{
|
11
|
+
filter: 'raise',
|
12
|
+
label: 'Break on raised exceptions',
|
13
|
+
description: 'The debugger will break when an exception is raised, regardless of whether it is subsequently rescued.',
|
14
|
+
default: false
|
15
|
+
}
|
16
|
+
]
|
9
17
|
})
|
10
18
|
end
|
11
19
|
end
|
@@ -16,7 +16,7 @@ module Readapt
|
|
16
16
|
if frame != Frame::NULL_FRAME && !frame.nil?
|
17
17
|
frame.locals
|
18
18
|
else
|
19
|
-
obj =
|
19
|
+
obj = References.get(ref)
|
20
20
|
result = []
|
21
21
|
if obj.is_a?(Array)
|
22
22
|
obj.each_with_index do |itm, idx|
|
@@ -48,14 +48,6 @@ module Readapt
|
|
48
48
|
end
|
49
49
|
})
|
50
50
|
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def object_reference
|
55
|
-
ObjectSpace._id2ref(arguments['variablesReference'])
|
56
|
-
rescue RangeError
|
57
|
-
nil
|
58
|
-
end
|
59
51
|
end
|
60
52
|
end
|
61
53
|
end
|
data/lib/readapt/output.rb
CHANGED
data/lib/readapt/thread.rb
CHANGED
@@ -4,20 +4,17 @@ require 'ostruct'
|
|
4
4
|
|
5
5
|
module Readapt
|
6
6
|
class Thread
|
7
|
-
@@next_id = 0
|
8
|
-
|
9
7
|
# @return [Symbol]
|
10
8
|
attr_accessor :control
|
11
9
|
|
10
|
+
# @return [String]
|
12
11
|
def name
|
13
|
-
@name ||=
|
14
|
-
@@next_id += 1
|
15
|
-
"Thread #{@@next_id}"
|
16
|
-
end
|
12
|
+
@name ||= "Thread #{id}"
|
17
13
|
end
|
18
14
|
|
15
|
+
# # @return [Object]
|
19
16
|
def object
|
20
|
-
ObjectSpace._id2ref(
|
17
|
+
ObjectSpace._id2ref(thread_object_id)
|
21
18
|
end
|
22
19
|
end
|
23
20
|
end
|
data/lib/readapt/version.rb
CHANGED
data/readapt.gemspec
CHANGED
@@ -29,10 +29,10 @@ Gem::Specification.new do |spec|
|
|
29
29
|
|
30
30
|
spec.required_ruby_version = '>= 2.2'
|
31
31
|
|
32
|
-
spec.add_dependency 'backport', '~> 1.
|
32
|
+
spec.add_dependency 'backport', '~> 1.2'
|
33
33
|
spec.add_dependency 'thor', '~> 1.0'
|
34
34
|
|
35
|
-
spec.add_development_dependency "rake", "~>
|
35
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
36
36
|
spec.add_development_dependency "rake-compiler", "~> 1.0"
|
37
37
|
spec.add_development_dependency "rspec", "~> 3.0"
|
38
38
|
spec.add_development_dependency 'simplecov', '~> 0.14'
|
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: 1.1
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake-compiler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,10 +121,10 @@ files:
|
|
121
121
|
- ext/readapt/extconf.rb
|
122
122
|
- ext/readapt/frame.c
|
123
123
|
- ext/readapt/frame.h
|
124
|
-
- ext/readapt/hash_table.c
|
125
|
-
- ext/readapt/hash_table.h
|
126
124
|
- ext/readapt/inspector.c
|
127
125
|
- ext/readapt/inspector.h
|
126
|
+
- ext/readapt/lookup_table.c
|
127
|
+
- ext/readapt/lookup_table.h
|
128
128
|
- ext/readapt/monitor.c
|
129
129
|
- ext/readapt/monitor.h
|
130
130
|
- ext/readapt/normalize.c
|
@@ -194,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
194
|
- !ruby/object:Gem::Version
|
195
195
|
version: '0'
|
196
196
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
197
|
+
rubygems_version: 3.2.0
|
198
198
|
signing_key:
|
199
199
|
specification_version: 4
|
200
200
|
summary: A Ruby debugger for the Debug Adapter Protocol
|
data/ext/readapt/hash_table.h
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
#ifndef HASH_TABLE_H_
|
2
|
-
#define HASH_TABLE_H_
|
3
|
-
|
4
|
-
typedef struct ht_long_array
|
5
|
-
{
|
6
|
-
long *items;
|
7
|
-
long size;
|
8
|
-
} ht_long_array;
|
9
|
-
|
10
|
-
// ht_item is an item in the hash table
|
11
|
-
typedef struct ht_item
|
12
|
-
{
|
13
|
-
char *key;
|
14
|
-
ht_long_array *value;
|
15
|
-
} ht_item;
|
16
|
-
|
17
|
-
typedef struct ht_hash_table
|
18
|
-
{
|
19
|
-
long size;
|
20
|
-
ht_item **items;
|
21
|
-
} ht_hash_table;
|
22
|
-
|
23
|
-
ht_hash_table *ht_new();
|
24
|
-
void ht_del_hash_table(ht_hash_table *ht);
|
25
|
-
|
26
|
-
void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size);
|
27
|
-
ht_long_array *ht_search(ht_hash_table *ht, char *key);
|
28
|
-
void ht_delete(ht_hash_table *h, char *key);
|
29
|
-
|
30
|
-
#endif // HASH_TABLE_H_
|