readapt 1.1.0 → 1.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb2043c676504da871aeb29021aa9653bd8b521362f144a0ffad62aa24de2f67
4
- data.tar.gz: f8999e42e0c7821377d0aa9a323f9318526bfdfc599e3b5a261dab3f8f4266f0
3
+ metadata.gz: 450c74c32434e471b61235c9dd00a6e7bcbe08b16c246af30c2a4bb99aa03376
4
+ data.tar.gz: 93929a65369b6effde74000165ffa2e65081bf136da35baa5e427bc0b1058eb5
5
5
  SHA512:
6
- metadata.gz: 109b42a1bc7a173c3d8d5e6c33b208dd7a8d6636f40cd5f62020e769944275957e127bf9bae3693bae51bc7175f71f2d9f31ace717e3cd737a8c98df47410333
7
- data.tar.gz: 8cf91dd653d8093975a31d9378e5248661422a6ac18edee95fe605e8d3ce8f8378c40cf6f6de1bdd202023b2dea4472c7d46ac9a425338c0706d45f6c6839717
6
+ metadata.gz: e980de040f9cef44e82bceba51d3679a123b4a840ec5b5e04b3aa5e14af410ce9e226e074ea543f90c7734c07b20790e90e60215a40120a54b7d133d7a3374e7
7
+ data.tar.gz: d688ab5daf6c98ccb5269f2dd09dc5e06498644c616f4d592b24be73576aa380e7704349226ee1fcf79ac76f92318e819d98e13de9a053328b8a75e5adb413ab
data/.travis.yml CHANGED
@@ -8,9 +8,10 @@ rvm:
8
8
  - 2.5
9
9
  - 2.6
10
10
  - 2.7
11
+ - 3.0
11
12
  matrix:
12
13
  include:
13
- - rvm: 2.6
14
+ - rvm: 2.7
14
15
  os: osx
15
16
  before_script:
16
17
  - bundle install
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
 
@@ -1,8 +1,8 @@
1
1
  #include "ruby.h"
2
- #include "hash_table.h"
2
+ #include "lookup_table.h"
3
3
 
4
4
  static VALUE m_Breakpoints;
5
- ht_hash_table *ht;
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
- ht_insert(ht, StringValueCStr(file), ll, length);
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
- ht_long_array *lines;
40
+ lt_long_array *lines;
41
41
  long i;
42
42
 
43
- lines = ht_search(ht, file);
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
- ht_del_hash_table(ht);
65
- ht = ht_new();
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 = ht_new(); // TODO Need to free?
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 "hash_table.h"
5
+ #include "lookup_table.h"
6
6
 
7
- static ht_long_array *copy_array(const long *value, const long size)
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
- ht_long_array *result;
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(ht_long_array));
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 ht_item *ht_new_item(char *key, const long *value, const long size)
26
+ static lt_item *lt_new_item(char *key, const long *value, const long size)
27
27
  {
28
- ht_item *i = malloc(sizeof(ht_item));
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 ht_item
36
+ * Delete the lt_item
37
37
  */
38
- static void ht_del_item(ht_item *i)
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 hash table
46
+ * Initialize a new empty lookup table
47
47
  */
48
- ht_hash_table *ht_new()
48
+ lt_lookup_table *lt_new()
49
49
  {
50
- ht_hash_table *ht = malloc(sizeof(ht_hash_table));
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 hash table
57
+ * Delete the lookup table
58
58
  */
59
- void ht_del_hash_table(ht_hash_table *ht)
59
+ void lt_del_lookup_table(lt_lookup_table *ht)
60
60
  {
61
61
  int i;
62
- ht_item *item;
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
- ht_del_item(item);
68
+ lt_del_item(item);
69
69
  }
70
70
  free(ht->items);
71
71
  free(ht);
72
72
  }
73
73
 
74
- static ht_long_array *ht_search_part(ht_hash_table *ht, char *key, long cursor, long next)
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 ht_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
97
+ return lt_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
98
98
  }
99
99
  else
100
100
  {
101
- return ht_search_part(ht, key, cursor + 1, next / 2);
101
+ return lt_search_part(ht, key, cursor + 1, next / 2);
102
102
  }
103
103
  }
104
- return ht_search_part(ht, key, cursor + 1, next / 2);
104
+ return lt_search_part(ht, key, cursor + 1, next / 2);
105
105
  }
106
106
 
107
- static ht_long_array *ht_search_key(ht_hash_table *ht, char *key)
107
+ static lt_long_array *lt_search_key(lt_lookup_table *ht, char *key)
108
108
  {
109
- return ht_search_part(ht, key, 0, ht->size / 2);
109
+ return lt_search_part(ht, key, 0, ht->size / 2);
110
110
  }
111
111
 
112
- static void ht_delete_key(ht_hash_table *ht, char *key)
112
+ static void lt_delete_key(lt_lookup_table *ht, char *key)
113
113
  {
114
- ht_long_array *found;
115
- ht_item **tmp;
114
+ lt_long_array *found;
115
+ lt_item **tmp;
116
116
  long i;
117
117
  long cursor = 0;
118
118
 
119
- found = ht_search_key(ht, key);
119
+ found = lt_search_key(ht, key);
120
120
  if (found)
121
121
  {
122
- tmp = malloc(sizeof(ht_item) * (ht->size - 1));
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
- ht_del_item(ht->items[i]);
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 ht_insert_key(ht_hash_table *ht, char *key, const long *value, const long size)
141
+ static void lt_insert_key(lt_lookup_table *ht, char *key, const long *value, const long size)
142
142
  {
143
- ht_item *item;
144
- ht_item **tmp;
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
- ht_delete_key(ht, key);
150
+ lt_delete_key(ht, key);
151
151
 
152
152
  if (size == 0)
153
153
  {
154
154
  return;
155
155
  }
156
156
 
157
- item = ht_new_item(key, value, size);
158
- tmp = malloc(sizeof(ht_item) * (ht->size + 1));
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 hash table
190
+ * Add an item to the lookup table
191
191
  */
192
- void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size)
192
+ void lt_insert(lt_lookup_table *ht, char *key, const long *value, const long size)
193
193
  {
194
- ht_insert_key(ht, key, value, size);
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
- ht_long_array *ht_search(ht_hash_table *ht, char *key)
200
+ lt_long_array *lt_search(lt_lookup_table *ht, char *key)
201
201
  {
202
- return ht_search_key(ht, key);
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 ht_delete(ht_hash_table *ht, char *key)
208
+ void lt_delete(lt_lookup_table *ht, char *key)
209
209
  {
210
- ht_delete_key(ht, key);
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_
@@ -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
  }
@@ -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
- next_id++;
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
- rb_define_singleton_method(c_Thread, "all", thread_all_s, 0);
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
 
@@ -10,7 +10,8 @@ typedef struct thread_reference_struct {
10
10
  int cursor;
11
11
  int depth;
12
12
  ID control;
13
- readapt_stack_t *frames;
13
+ long thread_object_id;
14
+ readapt_stack_t *frames;
14
15
  } thread_reference_t;
15
16
 
16
17
  void initialize_threads(VALUE);
@@ -13,6 +13,7 @@ module Readapt
13
13
  @hit_condition = hit_condition
14
14
  end
15
15
 
16
+ # @return [Integer]
16
17
  def hit_cursor
17
18
  @hit_cursor ||= 0
18
19
  end
@@ -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 Exception => e
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 Exception => e
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
@@ -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
@@ -11,7 +11,7 @@ module Readapt
11
11
  class Frame
12
12
  def evaluate code
13
13
  frame_binding.eval(code).inspect
14
- rescue Exception => e
14
+ rescue StandardError => e
15
15
  "[#{e.class}] #{e.message}"
16
16
  end
17
17
 
@@ -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
@@ -3,6 +3,9 @@
3
3
  module Readapt
4
4
  module Message
5
5
  class SetExceptionBreakpoints < Base
6
+ def run
7
+ debugger.pause_on_raise = arguments['filters'] && arguments['filters'].include?('raise')
8
+ end
6
9
  end
7
10
  end
8
11
  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 = object_reference
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
@@ -6,7 +6,7 @@ module Readapt
6
6
 
7
7
  def receiving data
8
8
  send_event('output', {
9
- output: data,
9
+ output: data.force_encoding('utf-8'),
10
10
  category: 'stdout'
11
11
  })
12
12
  end
@@ -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 ||= begin
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(id)
17
+ ObjectSpace._id2ref(thread_object_id)
21
18
  end
22
19
  end
23
20
  end
@@ -1,3 +1,3 @@
1
1
  module Readapt
2
- VERSION = "1.1.0"
2
+ VERSION = "1.4.1"
3
3
  end
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.1'
32
+ spec.add_dependency 'backport', '~> 1.2'
33
33
  spec.add_dependency 'thor', '~> 1.0'
34
34
 
35
- spec.add_development_dependency "rake", "~> 10.0"
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.0
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: 2020-09-13 00:00:00.000000000 Z
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.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.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: '10.0'
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: '10.0'
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.1.2
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
@@ -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_