byebug 12.0.0 → 13.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44cf64e7bdc187e8302b39d4b1dbf6c00fd27f4c19e01f6331414ee4eed05ab1
4
- data.tar.gz: 9ddbee412b023e83f7468749cd945ef93d2dddaf7152d477218d1b326db52b20
3
+ metadata.gz: f8c848a8629ef3fc193536f1a7461445f0add1cfc2143ed53f5f93c2589241fb
4
+ data.tar.gz: f33dc257897c04065cf9208293ba4c8a7ae1ec809fcbfb259cbcfa3efe93388f
5
5
  SHA512:
6
- metadata.gz: 0d6540614504a2b8703ae3309cfb01293d442e22166db4d3164452e3e17a2c1202fae273acd5d386c46350c036164e66fe31631652c29aa44db3f02bdff3e709
7
- data.tar.gz: ae3fdff0ece10e3de0819cce3321de2dcab9c12ec09f2725caa4ccaf69b26970aec0e0e44854f293e9c6a724ffa8bc25aabd4800e5888eba76f21c3717dc208f
6
+ metadata.gz: 9a83b9c70d31cd4b7e0647f408df9f33fedd566f00dcddc7b3943c73c10f7005292755de38daebf52348e1a0994d035ecb00b56c05f940b30e82fee7b9ab1051
7
+ data.tar.gz: 41356dc3dd9e2f9c3b08bcc3c56b5531de1c4b07416a71ed1d9599f78b3a5e3ab1ce8549583fbd165da72ee983eddd7ee8b5a8935eabaab4c874aa322e6e4556
data/CHANGELOG.md CHANGED
@@ -2,11 +2,27 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [13.0.0] - 2026-01-15
6
+
7
+ ### Fixed
8
+
9
+ * [#924](https://github.com/deivid-rodriguez/byebug/pull/924): Use typed data APIs to fix Ruby 4.0 deprecation ([@nobu]).
10
+ * [#876](https://github.com/deivid-rodriguez/byebug/pull/876): Add explicit require of `stringio` ([@pabloh]).
11
+ * [#909](https://github.com/deivid-rodriguez/byebug/pull/909): Avoid loading readline at all to play nice with Ruby 4.0.
12
+ * [#905](https://github.com/deivid-rodriguez/byebug/pull/905): Make reline an explicit dependency to fix Ruby 3.4 warnings.
13
+ * [#824](https://github.com/deivid-rodriguez/byebug/pull/824): Improve startup by loading IRB lazily ([@pocke]).
14
+ * [#848](https://github.com/deivid-rodriguez/byebug/pull/848): Grammar fixes in GUIDE.md ([@alexymik]).
15
+ * [#804](https://github.com/deivid-rodriguez/byebug/pull/804): Fix typo in context.rb documentation ([@ono-max]).
16
+
17
+ ### Removed
18
+
19
+ * Support for MRI 3.1. Byebug no longer installs on this platform.
20
+
5
21
  ## [12.0.0] - 2025-03-25
6
22
 
7
23
  ### Changed
8
24
 
9
- * [#690](https://github.com/deivid-rodriguez/byebug/pull/690): `break` without any arguments now sets a breakpoint on the current line, just like `gdb` ([@sergioro9].
25
+ * [#690](https://github.com/deivid-rodriguez/byebug/pull/690): `break` without any arguments now sets a breakpoint on the current line, just like `gdb` ([@sergioro9]).
10
26
 
11
27
  ### Fixed
12
28
 
@@ -843,6 +859,7 @@
843
859
  * Initial release.
844
860
 
845
861
  [Unreleased]: https://github.com/deivid-rodriguez/byebug/compare/v11.1.3...HEAD
862
+ [13.0.0]: https://github.com/deivid-rodriguez/byebug/compare/v12.0.0...v13.0.0
846
863
  [12.0.0]: https://github.com/deivid-rodriguez/byebug/compare/v11.1.3...v12.0.0
847
864
  [11.1.3]: https://github.com/deivid-rodriguez/byebug/compare/v11.1.2...v11.1.3
848
865
  [11.1.2]: https://github.com/deivid-rodriguez/byebug/compare/v11.1.1...v11.1.2
@@ -926,6 +943,7 @@
926
943
  [1.0.0]: https://github.com/deivid-rodriguez/byebug/compare/v0.0.1...v1.0.0
927
944
 
928
945
  [@akaneko3]: https://github.com/akaneko3
946
+ [@alexymik]: https://github.com/alexymik
929
947
  [@andreychernih]: https://github.com/andreychernih
930
948
  [@ark6]: https://github.com/ark6
931
949
  [@astashov]: https://github.com/astashov
@@ -946,6 +964,9 @@
946
964
  [@mrkn]: https://github.com/mrkn
947
965
  [@nobu]: https://github.com/nobu
948
966
  [@Olgagr]: https://github.com/Olgagr
967
+ [@ono-max]: https://github.com/ono-max
968
+ [@pabloh]: https://github.com/pabloh
969
+ [@pocke]: https://github.com/pocke
949
970
  [@sethk]: https://github.com/sethk
950
971
  [@sergioro9]: https://github.com/sergioro9
951
972
  [@shuky19]: https://github.com/shuky19
data/CONTRIBUTING.md CHANGED
@@ -31,15 +31,15 @@ abide by its terms.
31
31
  * Run the test suite using the default rake task (`bin/rake`). This task is
32
32
  composed of 3 subtasks: `bin/rake compile`, `bin/rake test` & `bin/rake lint`.
33
33
  * If you want to run specific tests, use the provided test runner, like so:
34
- * Specific test files. For example, `bin/minitest test/commands/break_test.rb`
35
- * Specific test classes. For example, `bin/minitest BreakAtLinesTest`
36
- * Specific tests. For example,
37
- `bin/minitest test_catch_removes_specific_catchpoint`
38
- * Specific fully qualified tests. For example,
39
- `bin/minitest BreakAtLinesTest#test_setting_breakpoint_sets_correct_fields`
40
- * You can combine any of them and you will get the union of all filters. For
41
- example: `bin/minitest BreakAtLinesTest
42
- test_catch_removes_specific_catchpoint`
34
+ * Specific test files. For example, `bin/minitest test/commands/break_test.rb`
35
+ * Specific test classes. For example, `bin/minitest BreakAtLinesTest`
36
+ * Specific tests. For example,
37
+ `bin/minitest test_catch_removes_specific_catchpoint`
38
+ * Specific fully qualified tests. For example,
39
+ `bin/minitest BreakAtLinesTest#test_setting_breakpoint_sets_correct_fields`
40
+ * You can combine any of them and you will get the union of all filters. For
41
+ example: `bin/minitest BreakAtLinesTest
42
+ test_catch_removes_specific_catchpoint`
43
43
 
44
44
  ## Code style
45
45
 
data/GUIDE.md CHANGED
@@ -1455,7 +1455,7 @@ display a short list of named classes of commands
1455
1455
  frame -- Moves to a frame in the call stack
1456
1456
  help -- Helps you using byebug
1457
1457
  history -- Shows byebug's history of commands
1458
- info -- Shows several informations about the program being debugged
1458
+ info -- Shows information about the program being debugged
1459
1459
  interrupt -- Interrupts the program
1460
1460
  irb -- Starts an IRB session
1461
1461
  kill -- Sends a signal to the current process
data/README.md CHANGED
@@ -41,7 +41,7 @@ more][Tidelift for enterprise].
41
41
 
42
42
  ## Requirements
43
43
 
44
- * _Required_: MRI 3.1.0 or higher.
44
+ * _Required_: MRI 3.2.0 or higher.
45
45
 
46
46
  ## Install
47
47
 
@@ -141,7 +141,7 @@ relying on `byebug`.
141
141
  ## Getting Started
142
142
 
143
143
  Read [byebug's markdown
144
- guide](https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md) to get
144
+ guide](https://github.com/deivid-rodriguez/byebug/blob/main/GUIDE.md) to get
145
145
  started. Proper documentation will be eventually written.
146
146
 
147
147
  ## Related projects
@@ -21,6 +21,29 @@ eval_expression(VALUE args)
21
21
  return rb_funcall2(rb_mKernel, idEval, 2, RARRAY_PTR(args));
22
22
  }
23
23
 
24
+ static void
25
+ mark_breakpoint(void *data)
26
+ {
27
+ breakpoint_t *breakpoint = data;
28
+
29
+ rb_gc_mark(breakpoint->source);
30
+ rb_gc_mark(breakpoint->expr);
31
+ }
32
+
33
+ static const rb_data_type_t breakpoint_type = {
34
+ "Byebug::Breakpoint",
35
+ {mark_breakpoint, RUBY_TYPED_DEFAULT_FREE},
36
+ };
37
+
38
+ static breakpoint_t *
39
+ brkpt_ptr(VALUE self)
40
+ {
41
+ breakpoint_t *breakpoint;
42
+
43
+ TypedData_Get_Struct(self, breakpoint_t, &breakpoint_type, breakpoint);
44
+ return breakpoint;
45
+ }
46
+
24
47
  /*
25
48
  * call-seq:
26
49
  * breakpoint.enabled? -> bool
@@ -30,9 +53,8 @@ eval_expression(VALUE args)
30
53
  static VALUE
31
54
  brkpt_enabled(VALUE self)
32
55
  {
33
- breakpoint_t *breakpoint;
56
+ breakpoint_t *breakpoint = brkpt_ptr(self);
34
57
 
35
- Data_Get_Struct(self, breakpoint_t, breakpoint);
36
58
  return breakpoint->enabled;
37
59
  }
38
60
 
@@ -45,9 +67,8 @@ brkpt_enabled(VALUE self)
45
67
  static VALUE
46
68
  brkpt_set_enabled(VALUE self, VALUE enabled)
47
69
  {
48
- breakpoint_t *breakpoint;
70
+ breakpoint_t *breakpoint = brkpt_ptr(self);
49
71
 
50
- Data_Get_Struct(self, breakpoint_t, breakpoint);
51
72
  return breakpoint->enabled = enabled;
52
73
  }
53
74
 
@@ -61,9 +82,8 @@ brkpt_set_enabled(VALUE self, VALUE enabled)
61
82
  static VALUE
62
83
  brkpt_expr(VALUE self)
63
84
  {
64
- breakpoint_t *breakpoint;
85
+ breakpoint_t *breakpoint = brkpt_ptr(self);
65
86
 
66
- Data_Get_Struct(self, breakpoint_t, breakpoint);
67
87
  return breakpoint->expr;
68
88
  }
69
89
 
@@ -77,9 +97,8 @@ brkpt_expr(VALUE self)
77
97
  static VALUE
78
98
  brkpt_set_expr(VALUE self, VALUE expr)
79
99
  {
80
- breakpoint_t *breakpoint;
100
+ breakpoint_t *breakpoint = brkpt_ptr(self);
81
101
 
82
- Data_Get_Struct(self, breakpoint_t, breakpoint);
83
102
  breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr);
84
103
  return expr;
85
104
  }
@@ -94,9 +113,8 @@ brkpt_set_expr(VALUE self, VALUE expr)
94
113
  static VALUE
95
114
  brkpt_hit_condition(VALUE self)
96
115
  {
97
- breakpoint_t *breakpoint;
116
+ breakpoint_t *breakpoint = brkpt_ptr(self);
98
117
 
99
- Data_Get_Struct(self, breakpoint_t, breakpoint);
100
118
  switch (breakpoint->hit_condition)
101
119
  {
102
120
  case HIT_COND_GE:
@@ -124,11 +142,9 @@ brkpt_hit_condition(VALUE self)
124
142
  static VALUE
125
143
  brkpt_set_hit_condition(VALUE self, VALUE value)
126
144
  {
127
- breakpoint_t *breakpoint;
145
+ breakpoint_t *breakpoint = brkpt_ptr(self);
128
146
  ID id_value;
129
147
 
130
- Data_Get_Struct(self, breakpoint_t, breakpoint);
131
-
132
148
  if (NIL_P(value))
133
149
  {
134
150
  breakpoint->hit_condition = HIT_COND_NONE;
@@ -157,9 +173,8 @@ brkpt_set_hit_condition(VALUE self, VALUE value)
157
173
  static VALUE
158
174
  brkpt_hit_count(VALUE self)
159
175
  {
160
- breakpoint_t *breakpoint;
176
+ breakpoint_t *breakpoint = brkpt_ptr(self);
161
177
 
162
- Data_Get_Struct(self, breakpoint_t, breakpoint);
163
178
  return INT2FIX(breakpoint->hit_count);
164
179
  }
165
180
 
@@ -173,9 +188,8 @@ brkpt_hit_count(VALUE self)
173
188
  static VALUE
174
189
  brkpt_hit_value(VALUE self)
175
190
  {
176
- breakpoint_t *breakpoint;
191
+ breakpoint_t *breakpoint = brkpt_ptr(self);
177
192
 
178
- Data_Get_Struct(self, breakpoint_t, breakpoint);
179
193
  return INT2FIX(breakpoint->hit_value);
180
194
  }
181
195
 
@@ -189,9 +203,8 @@ brkpt_hit_value(VALUE self)
189
203
  static VALUE
190
204
  brkpt_set_hit_value(VALUE self, VALUE value)
191
205
  {
192
- breakpoint_t *breakpoint;
206
+ breakpoint_t *breakpoint = brkpt_ptr(self);
193
207
 
194
- Data_Get_Struct(self, breakpoint_t, breakpoint);
195
208
  breakpoint->hit_value = FIX2INT(value);
196
209
  return value;
197
210
  }
@@ -205,9 +218,8 @@ brkpt_set_hit_value(VALUE self, VALUE value)
205
218
  static VALUE
206
219
  brkpt_id(VALUE self)
207
220
  {
208
- breakpoint_t *breakpoint;
221
+ breakpoint_t *breakpoint = brkpt_ptr(self);
209
222
 
210
- Data_Get_Struct(self, breakpoint_t, breakpoint);
211
223
  return INT2FIX(breakpoint->id);
212
224
  }
213
225
 
@@ -221,9 +233,8 @@ brkpt_id(VALUE self)
221
233
  static VALUE
222
234
  brkpt_pos(VALUE self)
223
235
  {
224
- breakpoint_t *breakpoint;
236
+ breakpoint_t *breakpoint = brkpt_ptr(self);
225
237
 
226
- Data_Get_Struct(self, breakpoint_t, breakpoint);
227
238
  if (breakpoint->type == BP_METHOD_TYPE)
228
239
  return rb_str_new2(rb_id2name(breakpoint->pos.mid));
229
240
  else
@@ -239,33 +250,23 @@ brkpt_pos(VALUE self)
239
250
  static VALUE
240
251
  brkpt_source(VALUE self)
241
252
  {
242
- breakpoint_t *breakpoint;
253
+ breakpoint_t *breakpoint = brkpt_ptr(self);
243
254
 
244
- Data_Get_Struct(self, breakpoint_t, breakpoint);
245
255
  return breakpoint->source;
246
256
  }
247
257
 
248
- static void
249
- mark_breakpoint(breakpoint_t *breakpoint)
250
- {
251
- rb_gc_mark(breakpoint->source);
252
- rb_gc_mark(breakpoint->expr);
253
- }
254
-
255
258
  static VALUE
256
259
  brkpt_create(VALUE klass)
257
260
  {
258
- breakpoint_t *breakpoint = ALLOC(breakpoint_t);
261
+ breakpoint_t *breakpoint;
259
262
 
260
- return Data_Wrap_Struct(klass, mark_breakpoint, xfree, breakpoint);
263
+ return TypedData_Make_Struct(klass, breakpoint_t, &breakpoint_type, breakpoint);
261
264
  }
262
265
 
263
266
  static VALUE
264
267
  brkpt_initialize(VALUE self, VALUE source, VALUE pos, VALUE expr)
265
268
  {
266
- breakpoint_t *breakpoint;
267
-
268
- Data_Get_Struct(self, breakpoint_t, breakpoint);
269
+ breakpoint_t *breakpoint = brkpt_ptr(self);
269
270
 
270
271
  breakpoint->type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
271
272
  if (breakpoint->type == BP_POS_TYPE)
@@ -360,7 +361,7 @@ check_breakpoint_by_hit_condition(VALUE rb_breakpoint)
360
361
  if (NIL_P(rb_breakpoint))
361
362
  return 0;
362
363
 
363
- Data_Get_Struct(rb_breakpoint, breakpoint_t, breakpoint);
364
+ breakpoint = brkpt_ptr(rb_breakpoint);
364
365
  breakpoint->hit_count++;
365
366
 
366
367
  if (Qtrue != breakpoint->enabled)
@@ -397,7 +398,7 @@ check_breakpoint_by_pos(VALUE rb_breakpoint, char *file, int line)
397
398
  if (NIL_P(rb_breakpoint))
398
399
  return 0;
399
400
 
400
- Data_Get_Struct(rb_breakpoint, breakpoint_t, breakpoint);
401
+ breakpoint = brkpt_ptr(rb_breakpoint);
401
402
 
402
403
  if (Qfalse == breakpoint->enabled || breakpoint->type != BP_POS_TYPE
403
404
  || breakpoint->pos.line != line)
@@ -414,7 +415,7 @@ check_breakpoint_by_method(VALUE rb_breakpoint, VALUE klass, ID mid, VALUE self)
414
415
  if (NIL_P(rb_breakpoint))
415
416
  return 0;
416
417
 
417
- Data_Get_Struct(rb_breakpoint, breakpoint_t, breakpoint);
418
+ breakpoint = brkpt_ptr(rb_breakpoint);
418
419
 
419
420
  if (Qfalse == breakpoint->enabled || breakpoint->type != BP_METHOD_TYPE
420
421
  || breakpoint->pos.mid != mid)
@@ -437,7 +438,7 @@ check_breakpoint_by_expr(VALUE rb_breakpoint, VALUE bind)
437
438
  if (NIL_P(rb_breakpoint))
438
439
  return 0;
439
440
 
440
- Data_Get_Struct(rb_breakpoint, breakpoint_t, breakpoint);
441
+ breakpoint = brkpt_ptr(rb_breakpoint);
441
442
 
442
443
  if (Qfalse == breakpoint->enabled)
443
444
  return 0;
data/ext/byebug/byebug.c CHANGED
@@ -147,7 +147,7 @@ cleanup(debug_context_t *dc)
147
147
  return; \
148
148
  \
149
149
  thread_context_lookup(rb_thread_current(), &context); \
150
- Data_Get_Struct(context, debug_context_t, dc); \
150
+ dc = debug_context_ptr(context); \
151
151
  \
152
152
  trace_arg = rb_tracearg_from_tracepoint(trace_point); \
153
153
  if (verbose == Qtrue) \
@@ -442,7 +442,7 @@ raise_event(VALUE trace_point, void *data)
442
442
  pm_context = context_dup(dc);
443
443
  rb_ivar_set(raised_exception, rb_intern("@__bb_context"), pm_context);
444
444
 
445
- Data_Get_Struct(pm_context, debug_context_t, new_dc);
445
+ new_dc = debug_context_ptr(pm_context);
446
446
  rb_debug_inspector_open(context_backtrace_set, (void *)new_dc);
447
447
  }
448
448
 
@@ -568,13 +568,13 @@ Contexts(VALUE self)
568
568
  rb_ary_push(new_list, context);
569
569
  }
570
570
 
571
- Data_Get_Struct(threads, threads_table_t, t_tbl);
571
+ t_tbl = threads_table_ptr(threads);
572
572
  st_clear(t_tbl->tbl);
573
573
 
574
574
  for (i = 0; i < RARRAY_LENINT(new_list); i++)
575
575
  {
576
576
  context = rb_ary_entry(new_list, i);
577
- Data_Get_Struct(context, debug_context_t, dc);
577
+ dc = debug_context_ptr(context);
578
578
  st_insert(t_tbl->tbl, dc->thread, context);
579
579
  }
580
580
 
@@ -683,7 +683,7 @@ Stoppable(VALUE self)
683
683
  context = Current_context(self);
684
684
  if (!NIL_P(context))
685
685
  {
686
- Data_Get_Struct(context, debug_context_t, dc);
686
+ dc = debug_context_ptr(context);
687
687
 
688
688
  if (dc->steps > 0)
689
689
  return Qfalse;
@@ -737,7 +737,7 @@ Debug_load(int argc, VALUE *argv, VALUE self)
737
737
  Start(self);
738
738
 
739
739
  context = Current_context(self);
740
- Data_Get_Struct(context, debug_context_t, dc);
740
+ dc = debug_context_ptr(context);
741
741
 
742
742
  dc->calced_stack_size = 1;
743
743
 
data/ext/byebug/byebug.h CHANGED
@@ -116,6 +116,7 @@ extern void byebug_remove_from_locked(VALUE thread);
116
116
  /* functions from threads.c */
117
117
  extern void Init_threads_table(VALUE mByebug);
118
118
  extern VALUE create_threads_table(void);
119
+ extern threads_table_t *threads_table_ptr(VALUE thrads);
119
120
  extern void thread_context_lookup(VALUE thread, VALUE *context);
120
121
  extern int is_living_thread(VALUE thread);
121
122
  extern void acquire_lock(debug_context_t *dc);
@@ -128,6 +129,7 @@ extern VALUE next_thread;
128
129
  /* functions from context.c */
129
130
  extern void Init_byebug_context(VALUE mByebug);
130
131
  extern VALUE byebug_context_create(VALUE thread);
132
+ extern debug_context_t *debug_context_ptr(VALUE context);
131
133
  extern VALUE context_dup(debug_context_t *context);
132
134
  extern void byebug_reset_stepping_stop_points(debug_context_t *context);
133
135
  extern VALUE call_with_debug_inspector(struct call_with_inspection_data *data);
data/ext/byebug/context.c CHANGED
@@ -15,6 +15,25 @@ byebug_reset_stepping_stop_points(debug_context_t *context)
15
15
  context->steps_out = -1;
16
16
  }
17
17
 
18
+ static void context_mark(void *data);
19
+
20
+ static const rb_data_type_t debug_context_type = {
21
+ "Byebug::Context",
22
+ {
23
+ context_mark,
24
+ RUBY_NEVER_FREE,
25
+ },
26
+ };
27
+
28
+ debug_context_t *
29
+ debug_context_ptr(VALUE self)
30
+ {
31
+ debug_context_t *context;
32
+
33
+ TypedData_Get_Struct(self, debug_context_t, &debug_context_type, context);
34
+ return context;
35
+ }
36
+
18
37
  /*
19
38
  * call-seq:
20
39
  * context.dead? -> bool
@@ -25,9 +44,8 @@ byebug_reset_stepping_stop_points(debug_context_t *context)
25
44
  static inline VALUE
26
45
  Context_dead(VALUE self)
27
46
  {
28
- debug_context_t *context;
47
+ debug_context_t *context = debug_context_ptr(self);
29
48
 
30
- Data_Get_Struct(self, debug_context_t, context);
31
49
  return CTX_FL_TEST(context, CTX_FL_DEAD) ? Qtrue : Qfalse;
32
50
  }
33
51
 
@@ -58,7 +76,8 @@ dc_stack_size(debug_context_t *context)
58
76
  extern VALUE
59
77
  byebug_context_create(VALUE thread)
60
78
  {
61
- debug_context_t *context = ALLOC(debug_context_t);
79
+ debug_context_t *context;
80
+ VALUE obj = TypedData_Make_Struct(cContext, debug_context_t, &debug_context_type, context);
62
81
 
63
82
  context->flags = 0;
64
83
  context->thnum = ++thnum_max;
@@ -72,20 +91,21 @@ byebug_context_create(VALUE thread)
72
91
  if (rb_obj_class(thread) == cDebugThread)
73
92
  CTX_FL_SET(context, CTX_FL_IGNORE);
74
93
 
75
- return Data_Wrap_Struct(cContext, context_mark, 0, context);
94
+ return obj;
76
95
  }
77
96
 
78
97
  extern VALUE
79
98
  context_dup(debug_context_t *context)
80
99
  {
81
- debug_context_t *new_context = ALLOC(debug_context_t);
100
+ debug_context_t *new_context;
101
+ VALUE obj = TypedData_Make_Struct(cContext, debug_context_t, &debug_context_type, new_context);
82
102
 
83
103
  memcpy(new_context, context, sizeof(debug_context_t));
84
104
  byebug_reset_stepping_stop_points(new_context);
85
105
  new_context->backtrace = context->backtrace;
86
106
  CTX_FL_SET(new_context, CTX_FL_DEAD);
87
107
 
88
- return Data_Wrap_Struct(cContext, context_mark, 0, new_context);
108
+ return obj;
89
109
  }
90
110
 
91
111
 
@@ -204,14 +224,13 @@ call_with_debug_inspector(struct call_with_inspection_data *data)
204
224
  (VALUE)data);
205
225
  }
206
226
 
207
- #define FRAME_SETUP \
208
- debug_context_t *context; \
209
- VALUE frame_no; \
210
- int frame_n; \
211
- Data_Get_Struct(self, debug_context_t, context); \
212
- if (!rb_scan_args(argc, argv, "01", &frame_no)) \
213
- frame_n = 0; \
214
- else \
227
+ #define FRAME_SETUP \
228
+ debug_context_t *context = debug_context_ptr(self); \
229
+ VALUE frame_no; \
230
+ int frame_n; \
231
+ if (!rb_scan_args(argc, argv, "01", &frame_no)) \
232
+ frame_n = 0; \
233
+ else \
215
234
  frame_n = FIX2INT(frame_no);
216
235
 
217
236
  /*
@@ -325,9 +344,8 @@ Context_frame_self(int argc, VALUE *argv, VALUE self)
325
344
  static inline VALUE
326
345
  Context_ignored(VALUE self)
327
346
  {
328
- debug_context_t *context;
347
+ debug_context_t *context = debug_context_ptr(self);
329
348
 
330
- Data_Get_Struct(self, debug_context_t, context);
331
349
  return CTX_FL_TEST(context, CTX_FL_IGNORE) ? Qtrue : Qfalse;
332
350
  }
333
351
 
@@ -340,9 +358,7 @@ Context_ignored(VALUE self)
340
358
  static VALUE
341
359
  Context_resume(VALUE self)
342
360
  {
343
- debug_context_t *context;
344
-
345
- Data_Get_Struct(self, debug_context_t, context);
361
+ debug_context_t *context = debug_context_ptr(self);
346
362
 
347
363
  if (!CTX_FL_TEST(context, CTX_FL_SUSPEND))
348
364
  return Qnil;
@@ -364,9 +380,7 @@ Context_resume(VALUE self)
364
380
  static inline VALUE
365
381
  Context_backtrace(VALUE self)
366
382
  {
367
- debug_context_t *context;
368
-
369
- Data_Get_Struct(self, debug_context_t, context);
383
+ debug_context_t *context = debug_context_ptr(self);
370
384
 
371
385
  return dc_backtrace(context);
372
386
  }
@@ -374,11 +388,9 @@ Context_backtrace(VALUE self)
374
388
  static VALUE
375
389
  Context_stop_reason(VALUE self)
376
390
  {
377
- debug_context_t *context;
391
+ debug_context_t *context = debug_context_ptr(self);
378
392
  const char *symbol;
379
393
 
380
- Data_Get_Struct(self, debug_context_t, context);
381
-
382
394
  if (CTX_FL_TEST(context, CTX_FL_DEAD))
383
395
  symbol = "post-mortem";
384
396
  else
@@ -412,9 +424,7 @@ Context_step_into(int argc, VALUE *argv, VALUE self)
412
424
  {
413
425
  VALUE steps, v_frame;
414
426
  int n_args, from_frame;
415
- debug_context_t *context;
416
-
417
- Data_Get_Struct(self, debug_context_t, context);
427
+ debug_context_t *context = debug_context_ptr(self);
418
428
 
419
429
  if (context->calced_stack_size == 0)
420
430
  rb_raise(rb_eRuntimeError, "No frames collected.");
@@ -452,13 +462,11 @@ Context_step_out(int argc, VALUE *argv, VALUE self)
452
462
  {
453
463
  int n_args, n_frames;
454
464
  VALUE v_frames, force;
455
- debug_context_t *context;
465
+ debug_context_t *context = debug_context_ptr(self);
456
466
 
457
467
  n_args = rb_scan_args(argc, argv, "02", &v_frames, &force);
458
468
  n_frames = n_args == 0 ? 1 : FIX2INT(v_frames);
459
469
 
460
- Data_Get_Struct(self, debug_context_t, context);
461
-
462
470
  if (n_frames < 0 || n_frames > context->calced_stack_size)
463
471
  rb_raise(rb_eRuntimeError,
464
472
  "You want to finish %d frames, but stack size is only %d",
@@ -485,9 +493,7 @@ Context_step_over(int argc, VALUE *argv, VALUE self)
485
493
  {
486
494
  int n_args, frame;
487
495
  VALUE lines, v_frame;
488
- debug_context_t *context;
489
-
490
- Data_Get_Struct(self, debug_context_t, context);
496
+ debug_context_t *context = debug_context_ptr(self);
491
497
 
492
498
  if (context->calced_stack_size == 0)
493
499
  rb_raise(rb_eRuntimeError, "No frames collected.");
@@ -515,9 +521,7 @@ static VALUE
515
521
  Context_suspend(VALUE self)
516
522
  {
517
523
  VALUE status;
518
- debug_context_t *context;
519
-
520
- Data_Get_Struct(self, debug_context_t, context);
524
+ debug_context_t *context = debug_context_ptr(self);
521
525
 
522
526
  status = rb_funcall(context->thread, rb_intern("status"), 0);
523
527
 
@@ -542,9 +546,7 @@ Context_suspend(VALUE self)
542
546
  static VALUE
543
547
  Context_switch(VALUE self)
544
548
  {
545
- debug_context_t *context;
546
-
547
- Data_Get_Struct(self, debug_context_t, context);
549
+ debug_context_t *context = debug_context_ptr(self);
548
550
 
549
551
  next_thread = context->thread;
550
552
 
@@ -564,9 +566,7 @@ Context_switch(VALUE self)
564
566
  static VALUE
565
567
  Context_is_suspended(VALUE self)
566
568
  {
567
- debug_context_t *context;
568
-
569
- Data_Get_Struct(self, debug_context_t, context);
569
+ debug_context_t *context = debug_context_ptr(self);
570
570
 
571
571
  return CTX_FL_TEST(context, CTX_FL_SUSPEND) ? Qtrue : Qfalse;
572
572
  }
@@ -580,9 +580,8 @@ Context_is_suspended(VALUE self)
580
580
  static inline VALUE
581
581
  Context_thnum(VALUE self)
582
582
  {
583
- debug_context_t *context;
583
+ debug_context_t *context = debug_context_ptr(self);
584
584
 
585
- Data_Get_Struct(self, debug_context_t, context);
586
585
  return INT2FIX(context->thnum);
587
586
  }
588
587
 
@@ -595,9 +594,8 @@ Context_thnum(VALUE self)
595
594
  static inline VALUE
596
595
  Context_thread(VALUE self)
597
596
  {
598
- debug_context_t *context;
597
+ debug_context_t *context = debug_context_ptr(self);
599
598
 
600
- Data_Get_Struct(self, debug_context_t, context);
601
599
  return context->thread;
602
600
  }
603
601
 
@@ -610,9 +608,8 @@ Context_thread(VALUE self)
610
608
  static VALUE
611
609
  Context_tracing(VALUE self)
612
610
  {
613
- debug_context_t *context;
611
+ debug_context_t *context = debug_context_ptr(self);
614
612
 
615
- Data_Get_Struct(self, debug_context_t, context);
616
613
  return CTX_FL_TEST(context, CTX_FL_TRACING) ? Qtrue : Qfalse;
617
614
  }
618
615
 
@@ -625,9 +622,7 @@ Context_tracing(VALUE self)
625
622
  static VALUE
626
623
  Context_set_tracing(VALUE self, VALUE value)
627
624
  {
628
- debug_context_t *context;
629
-
630
- Data_Get_Struct(self, debug_context_t, context);
625
+ debug_context_t *context = debug_context_ptr(self);
631
626
 
632
627
  if (RTEST(value))
633
628
  CTX_FL_SET(context, CTX_FL_TRACING);
data/ext/byebug/threads.c CHANGED
@@ -42,6 +42,14 @@ t_tbl_free(void *data)
42
42
  xfree(t_tbl);
43
43
  }
44
44
 
45
+ static const rb_data_type_t threads_table_type = {
46
+ "Byebug::ThreadsTable",
47
+ {
48
+ t_tbl_mark,
49
+ t_tbl_free,
50
+ },
51
+ };
52
+
45
53
  /*
46
54
  * Creates a numeric hash whose keys are the currently active threads and
47
55
  * whose values are their associated contexts.
@@ -50,10 +58,19 @@ VALUE
50
58
  create_threads_table(void)
51
59
  {
52
60
  threads_table_t *t_tbl;
61
+ VALUE tbl = TypedData_Make_Struct(cThreadsTable, threads_table_t, &threads_table_type, t_tbl);
53
62
 
54
- t_tbl = ALLOC(threads_table_t);
55
63
  t_tbl->tbl = st_init_numtable();
56
- return Data_Wrap_Struct(cThreadsTable, t_tbl_mark, t_tbl_free, t_tbl);
64
+ return tbl;
65
+ }
66
+
67
+ threads_table_t *
68
+ threads_table_ptr(VALUE threads)
69
+ {
70
+ threads_table_t *t_tbl;
71
+
72
+ TypedData_Get_Struct(threads, threads_table_t, &threads_table_type, t_tbl);
73
+ return t_tbl;
57
74
  }
58
75
 
59
76
  /*
@@ -100,9 +117,7 @@ is_living_thread(VALUE thread)
100
117
  static void
101
118
  cleanup_dead_threads(void)
102
119
  {
103
- threads_table_t *t_tbl;
104
-
105
- Data_Get_Struct(threads, threads_table_t, t_tbl);
120
+ threads_table_t *t_tbl = threads_table_ptr(threads);
106
121
  st_foreach(t_tbl->tbl, check_thread_i, 0);
107
122
  }
108
123
 
@@ -112,9 +127,7 @@ cleanup_dead_threads(void)
112
127
  void
113
128
  thread_context_lookup(VALUE thread, VALUE *context)
114
129
  {
115
- threads_table_t *t_tbl;
116
-
117
- Data_Get_Struct(threads, threads_table_t, t_tbl);
130
+ threads_table_t *t_tbl = threads_table_ptr(threads);
118
131
 
119
132
  if (!st_lookup(t_tbl->tbl, thread, context) || !*context)
120
133
  {
@@ -186,7 +199,7 @@ Unlock(VALUE self)
186
199
  UNUSED(self);
187
200
 
188
201
  thread_context_lookup(rb_thread_current(), &context);
189
- Data_Get_Struct(context, debug_context_t, dc);
202
+ dc = debug_context_ptr(context);
190
203
 
191
204
  CTX_FL_SET(dc, CTX_FL_IGNORE);
192
205
 
@@ -213,7 +226,7 @@ Lock(VALUE self)
213
226
  rb_raise(rb_eRuntimeError, "Current thread is dead!");
214
227
 
215
228
  thread_context_lookup(rb_thread_current(), &context);
216
- Data_Get_Struct(context, debug_context_t, dc);
229
+ dc = debug_context_ptr(context);
217
230
 
218
231
  acquire_lock(dc);
219
232
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../command"
4
- require "irb"
5
4
  require "English"
6
5
 
7
6
  module Byebug
@@ -30,6 +29,8 @@ module Byebug
30
29
  def execute
31
30
  return errmsg(pr("base.errors.only_local")) unless processor.interface.instance_of?(LocalInterface)
32
31
 
32
+ require "irb"
33
+
33
34
  # @todo IRB tries to parse $ARGV so we must clear it (see #197). Add a
34
35
  # test case for it so we can remove this comment.
35
36
  with_clean_argv { IRB.start }
@@ -54,7 +54,7 @@ module Byebug
54
54
  context.stack_size
55
55
  end
56
56
 
57
- bt = prc("frame.line", (0...max_frame)) do |_, index|
57
+ bt = prc("frame.line", 0...max_frame) do |_, index|
58
58
  Frame.new(context, index).to_hash
59
59
  end
60
60
 
@@ -7,7 +7,7 @@ require_relative "processors/command_processor"
7
7
 
8
8
  module Byebug
9
9
  #
10
- # Mantains context information for the debugger and it's the main
10
+ # Maintains context information for the debugger and it's the main
11
11
  # communication point between the library and the C-extension through the
12
12
  # at_breakpoint, at_catchpoint, at_tracing, at_line and at_return callbacks
13
13
  #
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "stringio"
4
+
3
5
  module Byebug
4
6
  module Helpers
5
7
  #
@@ -1,16 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- begin
4
- require "readline"
5
- rescue LoadError
6
- warn <<-MESSAGE
7
- Sorry, you can't use byebug without Readline. To solve this, you need to
8
- rebuild Ruby with Readline support. If using Ubuntu, try `sudo apt-get
9
- install libreadline-dev` and then reinstall your Ruby.
10
- MESSAGE
11
-
12
- raise
13
- end
3
+ require "reline"
14
4
 
15
5
  module Byebug
16
6
  #
@@ -27,7 +17,7 @@ module Byebug
27
17
  # Array holding the list of commands in history
28
18
  #
29
19
  def buffer
30
- Readline::HISTORY.to_a
20
+ Reline::HISTORY.to_a
31
21
  end
32
22
 
33
23
  #
@@ -60,21 +50,21 @@ module Byebug
60
50
  end
61
51
 
62
52
  #
63
- # Adds a new command to Readline's history.
53
+ # Adds a new command to Reline's history.
64
54
  #
65
55
  def push(cmd)
66
56
  return if ignore?(cmd)
67
57
 
68
58
  @size += 1
69
- Readline::HISTORY.push(cmd)
59
+ Reline::HISTORY.push(cmd)
70
60
  end
71
61
 
72
62
  #
73
- # Removes a command from Readline's history.
63
+ # Removes a command from Reline's history.
74
64
  #
75
65
  def pop
76
66
  @size -= 1
77
- Readline::HISTORY.pop
67
+ Reline::HISTORY.pop
78
68
  end
79
69
 
80
70
  #
@@ -122,9 +112,9 @@ module Byebug
122
112
  #
123
113
  def ignore?(buf)
124
114
  return true if /^\s*$/.match?(buf)
125
- return false if Readline::HISTORY.empty?
115
+ return false if Reline::HISTORY.empty?
126
116
 
127
- buffer[Readline::HISTORY.length - 1] == buf
117
+ buffer[Reline::HISTORY.length - 1] == buf
128
118
  end
129
119
  end
130
120
  end
@@ -15,13 +15,13 @@ module Byebug
15
15
  end
16
16
 
17
17
  #
18
- # Reads a single line of input using Readline. If Ctrl-D is pressed, it
18
+ # Reads a single line of input using Reline. If Ctrl-D is pressed, it
19
19
  # returns "continue", meaning that program's execution will go on.
20
20
  #
21
21
  # @param prompt Prompt to be displayed.
22
22
  #
23
23
  def readline(prompt)
24
- with_repl_like_sigint { without_readline_completion { Readline.readline(prompt) || EOF_ALIAS } }
24
+ with_repl_like_sigint { without_reline_completion { Reline.readline(prompt) || EOF_ALIAS } }
25
25
  end
26
26
 
27
27
  #
@@ -42,21 +42,21 @@ module Byebug
42
42
  end
43
43
 
44
44
  #
45
- # Disable any Readline completion procs.
45
+ # Disable any Reline completion procs.
46
46
  #
47
47
  # Other gems, for example, IRB could've installed completion procs that are
48
48
  # dependent on them being loaded. Disable those while byebug is the REPL
49
- # making use of Readline.
49
+ # making use of Reline.
50
50
  #
51
- def without_readline_completion
52
- orig_completion = Readline.completion_proc
51
+ def without_reline_completion
52
+ orig_completion = Reline.completion_proc
53
53
  return yield unless orig_completion
54
54
 
55
55
  begin
56
- Readline.completion_proc = ->(_) { nil }
56
+ Reline.completion_proc = ->(_) { nil }
57
57
  yield
58
58
  ensure
59
- Readline.completion_proc = orig_completion
59
+ Reline.completion_proc = orig_completion
60
60
  end
61
61
  end
62
62
  end
@@ -4,5 +4,5 @@
4
4
  # Reopen main module to define the library version
5
5
  #
6
6
  module Byebug
7
- VERSION = "12.0.0"
7
+ VERSION = "13.0.0"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: byebug
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.0.0
4
+ version: 13.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Rodriguez
@@ -10,8 +10,22 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2025-03-25 00:00:00.000000000 Z
13
+ date: 2026-01-15 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: reline
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 0.6.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 0.6.0
15
29
  - !ruby/object:Gem::Dependency
16
30
  name: bundler
17
31
  requirement: !ruby/object:Gem::Requirement
@@ -185,7 +199,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
185
199
  requirements:
186
200
  - - ">="
187
201
  - !ruby/object:Gem::Version
188
- version: 3.1.0
202
+ version: 3.2.0
189
203
  required_rubygems_version: !ruby/object:Gem::Requirement
190
204
  requirements:
191
205
  - - ">="