byebug 11.1.3 → 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 +4 -4
- data/CHANGELOG.md +46 -0
- data/CONTRIBUTING.md +9 -9
- data/GUIDE.md +38 -38
- data/README.md +2 -4
- data/ext/byebug/breakpoint.c +51 -46
- data/ext/byebug/byebug.c +32 -26
- data/ext/byebug/byebug.h +2 -0
- data/ext/byebug/context.c +48 -52
- data/ext/byebug/threads.c +33 -9
- data/lib/byebug/breakpoint.rb +1 -18
- data/lib/byebug/commands/break.rb +7 -5
- data/lib/byebug/commands/enable/breakpoints.rb +1 -1
- data/lib/byebug/commands/finish.rb +1 -1
- data/lib/byebug/commands/help.rb +1 -1
- data/lib/byebug/commands/info.rb +1 -1
- data/lib/byebug/commands/irb.rb +2 -1
- data/lib/byebug/commands/set.rb +1 -1
- data/lib/byebug/commands/step.rb +1 -1
- data/lib/byebug/commands/thread/current.rb +1 -1
- data/lib/byebug/commands/thread/list.rb +1 -1
- data/lib/byebug/commands/thread/resume.rb +1 -1
- data/lib/byebug/commands/thread/stop.rb +1 -1
- data/lib/byebug/commands/tracevar.rb +1 -1
- data/lib/byebug/commands/untracevar.rb +2 -2
- data/lib/byebug/commands/var/args.rb +1 -1
- data/lib/byebug/commands/where.rb +14 -3
- data/lib/byebug/context.rb +1 -1
- data/lib/byebug/helpers/eval.rb +4 -6
- data/lib/byebug/helpers/file.rb +5 -1
- data/lib/byebug/helpers/parse.rb +9 -2
- data/lib/byebug/helpers/reflection.rb +1 -1
- data/lib/byebug/helpers/var.rb +17 -1
- data/lib/byebug/history.rb +14 -24
- data/lib/byebug/interface.rb +1 -1
- data/lib/byebug/interfaces/local_interface.rb +8 -8
- data/lib/byebug/option_setter.rb +1 -1
- data/lib/byebug/settings/savefile.rb +2 -2
- data/lib/byebug/version.rb +1 -1
- metadata +21 -7
data/ext/byebug/byebug.c
CHANGED
|
@@ -136,26 +136,32 @@ cleanup(debug_context_t *dc)
|
|
|
136
136
|
|
|
137
137
|
#define EVENT_TEARDOWN cleanup(dc);
|
|
138
138
|
|
|
139
|
-
#define EVENT_SETUP
|
|
140
|
-
debug_context_t *dc;
|
|
141
|
-
VALUE context;
|
|
142
|
-
rb_trace_arg_t *trace_arg;
|
|
143
|
-
|
|
144
|
-
UNUSED(data);
|
|
145
|
-
|
|
146
|
-
if (!is_living_thread(rb_thread_current()))
|
|
147
|
-
return;
|
|
148
|
-
|
|
149
|
-
thread_context_lookup(rb_thread_current(), &context);
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
trace_arg = rb_tracearg_from_tracepoint(trace_point);
|
|
153
|
-
if (verbose == Qtrue)
|
|
154
|
-
trace_print(trace_arg, dc, 0, 0);
|
|
155
|
-
|
|
156
|
-
if (CTX_FL_TEST(dc, CTX_FL_IGNORE))
|
|
157
|
-
return;
|
|
158
|
-
|
|
139
|
+
#define EVENT_SETUP \
|
|
140
|
+
debug_context_t *dc; \
|
|
141
|
+
VALUE context; \
|
|
142
|
+
rb_trace_arg_t *trace_arg; \
|
|
143
|
+
\
|
|
144
|
+
UNUSED(data); \
|
|
145
|
+
\
|
|
146
|
+
if (!is_living_thread(rb_thread_current())) \
|
|
147
|
+
return; \
|
|
148
|
+
\
|
|
149
|
+
thread_context_lookup(rb_thread_current(), &context); \
|
|
150
|
+
dc = debug_context_ptr(context); \
|
|
151
|
+
\
|
|
152
|
+
trace_arg = rb_tracearg_from_tracepoint(trace_point); \
|
|
153
|
+
if (verbose == Qtrue) \
|
|
154
|
+
trace_print(trace_arg, dc, 0, 0); \
|
|
155
|
+
\
|
|
156
|
+
if (CTX_FL_TEST(dc, CTX_FL_IGNORE)) \
|
|
157
|
+
return; \
|
|
158
|
+
\
|
|
159
|
+
VALUE rb_path = rb_tracearg_path(trace_arg); \
|
|
160
|
+
const char *path = NIL_P(rb_path) ? "" : RSTRING_PTR(rb_path); \
|
|
161
|
+
\
|
|
162
|
+
if (!strncmp(path, "<internal:", strlen("<internal:"))) \
|
|
163
|
+
return; \
|
|
164
|
+
\
|
|
159
165
|
acquire_lock(dc);
|
|
160
166
|
|
|
161
167
|
|
|
@@ -436,7 +442,7 @@ raise_event(VALUE trace_point, void *data)
|
|
|
436
442
|
pm_context = context_dup(dc);
|
|
437
443
|
rb_ivar_set(raised_exception, rb_intern("@__bb_context"), pm_context);
|
|
438
444
|
|
|
439
|
-
|
|
445
|
+
new_dc = debug_context_ptr(pm_context);
|
|
440
446
|
rb_debug_inspector_open(context_backtrace_set, (void *)new_dc);
|
|
441
447
|
}
|
|
442
448
|
|
|
@@ -562,13 +568,13 @@ Contexts(VALUE self)
|
|
|
562
568
|
rb_ary_push(new_list, context);
|
|
563
569
|
}
|
|
564
570
|
|
|
565
|
-
|
|
571
|
+
t_tbl = threads_table_ptr(threads);
|
|
566
572
|
st_clear(t_tbl->tbl);
|
|
567
573
|
|
|
568
574
|
for (i = 0; i < RARRAY_LENINT(new_list); i++)
|
|
569
575
|
{
|
|
570
576
|
context = rb_ary_entry(new_list, i);
|
|
571
|
-
|
|
577
|
+
dc = debug_context_ptr(context);
|
|
572
578
|
st_insert(t_tbl->tbl, dc->thread, context);
|
|
573
579
|
}
|
|
574
580
|
|
|
@@ -677,7 +683,7 @@ Stoppable(VALUE self)
|
|
|
677
683
|
context = Current_context(self);
|
|
678
684
|
if (!NIL_P(context))
|
|
679
685
|
{
|
|
680
|
-
|
|
686
|
+
dc = debug_context_ptr(context);
|
|
681
687
|
|
|
682
688
|
if (dc->steps > 0)
|
|
683
689
|
return Qfalse;
|
|
@@ -731,7 +737,7 @@ Debug_load(int argc, VALUE *argv, VALUE self)
|
|
|
731
737
|
Start(self);
|
|
732
738
|
|
|
733
739
|
context = Current_context(self);
|
|
734
|
-
|
|
740
|
+
dc = debug_context_ptr(context);
|
|
735
741
|
|
|
736
742
|
dc->calced_stack_size = 1;
|
|
737
743
|
|
|
@@ -854,7 +860,7 @@ Add_catchpoint(VALUE self, VALUE value)
|
|
|
854
860
|
}
|
|
855
861
|
|
|
856
862
|
/*
|
|
857
|
-
* Document-
|
|
863
|
+
* Document-module: Byebug
|
|
858
864
|
*
|
|
859
865
|
* == Summary
|
|
860
866
|
*
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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);
|
|
@@ -658,6 +653,7 @@ void
|
|
|
658
653
|
Init_byebug_context(VALUE mByebug)
|
|
659
654
|
{
|
|
660
655
|
cContext = rb_define_class_under(mByebug, "Context", rb_cObject);
|
|
656
|
+
rb_undef_alloc_func(cContext);
|
|
661
657
|
|
|
662
658
|
rb_define_method(cContext, "backtrace", Context_backtrace, 0);
|
|
663
659
|
rb_define_method(cContext, "dead?", Context_dead, 0);
|
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
|
|
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
|
{
|
|
@@ -180,8 +193,16 @@ release_lock(void)
|
|
|
180
193
|
static VALUE
|
|
181
194
|
Unlock(VALUE self)
|
|
182
195
|
{
|
|
196
|
+
debug_context_t *dc;
|
|
197
|
+
VALUE context;
|
|
198
|
+
|
|
183
199
|
UNUSED(self);
|
|
184
200
|
|
|
201
|
+
thread_context_lookup(rb_thread_current(), &context);
|
|
202
|
+
dc = debug_context_ptr(context);
|
|
203
|
+
|
|
204
|
+
CTX_FL_SET(dc, CTX_FL_IGNORE);
|
|
205
|
+
|
|
185
206
|
release_lock();
|
|
186
207
|
|
|
187
208
|
return locker;
|
|
@@ -205,10 +226,12 @@ Lock(VALUE self)
|
|
|
205
226
|
rb_raise(rb_eRuntimeError, "Current thread is dead!");
|
|
206
227
|
|
|
207
228
|
thread_context_lookup(rb_thread_current(), &context);
|
|
208
|
-
|
|
229
|
+
dc = debug_context_ptr(context);
|
|
209
230
|
|
|
210
231
|
acquire_lock(dc);
|
|
211
232
|
|
|
233
|
+
CTX_FL_UNSET(dc, CTX_FL_IGNORE);
|
|
234
|
+
|
|
212
235
|
return locker;
|
|
213
236
|
}
|
|
214
237
|
|
|
@@ -224,6 +247,7 @@ void
|
|
|
224
247
|
Init_threads_table(VALUE mByebug)
|
|
225
248
|
{
|
|
226
249
|
cThreadsTable = rb_define_class_under(mByebug, "ThreadsTable", rb_cObject);
|
|
250
|
+
rb_undef_alloc_func(cThreadsTable);
|
|
227
251
|
|
|
228
252
|
rb_define_module_function(mByebug, "unlock", Unlock, 0);
|
|
229
253
|
rb_define_module_function(mByebug, "lock", Lock, 0);
|
data/lib/byebug/breakpoint.rb
CHANGED
|
@@ -53,11 +53,7 @@ module Byebug
|
|
|
53
53
|
name = "#{Time.new.to_i}_#{rand(2**31)}"
|
|
54
54
|
iseq = RubyVM::InstructionSequence.compile(File.read(filename), name)
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
potential_lines_with_trace_points(iseq, {})
|
|
58
|
-
else
|
|
59
|
-
potential_lines_without_trace_points(iseq, {})
|
|
60
|
-
end
|
|
56
|
+
potential_lines_with_trace_points(iseq, {})
|
|
61
57
|
end
|
|
62
58
|
|
|
63
59
|
def self.potential_lines_with_trace_points(iseq, lines)
|
|
@@ -71,19 +67,6 @@ module Byebug
|
|
|
71
67
|
|
|
72
68
|
private_class_method :potential_lines_with_trace_points
|
|
73
69
|
|
|
74
|
-
def self.potential_lines_without_trace_points(iseq, lines)
|
|
75
|
-
iseq.disasm.each_line do |line|
|
|
76
|
-
res = /^\d+ (?<insn>\w+)\s+.+\(\s*(?<lineno>\d+)\)$/.match(line)
|
|
77
|
-
next unless res && res[:insn] == "trace"
|
|
78
|
-
|
|
79
|
-
lines[res[:lineno].to_i] = true
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
lines.keys
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
private_class_method :potential_lines_without_trace_points
|
|
86
|
-
|
|
87
70
|
#
|
|
88
71
|
# Returns true if a breakpoint could be set in line number +lineno+ in file
|
|
89
72
|
# name +filename.
|
|
@@ -23,13 +23,15 @@ module Byebug
|
|
|
23
23
|
|
|
24
24
|
def self.description
|
|
25
25
|
<<-DESCRIPTION
|
|
26
|
-
b[reak] [<file>:]<line> [if <expr>]
|
|
26
|
+
b[reak] [[<file>:]<line> [if <expr>]]
|
|
27
27
|
b[reak] [<module>::...]<class>(.|#)<method> [if <expr>]
|
|
28
28
|
|
|
29
|
+
#{short_description}
|
|
30
|
+
|
|
29
31
|
They can be specified by line or method and an expression can be added
|
|
30
32
|
for conditionally enabled breakpoints.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
for conditionally enabled breakpoints. Without arguments create a
|
|
34
|
+
a breakpoint in the current line.
|
|
33
35
|
DESCRIPTION
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -38,9 +40,9 @@ module Byebug
|
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
def execute
|
|
41
|
-
|
|
43
|
+
b = line_breakpoint(frame.line.to_s) unless @match[1]
|
|
42
44
|
|
|
43
|
-
b
|
|
45
|
+
b ||= line_breakpoint(@match[1]) || method_breakpoint(@match[1])
|
|
44
46
|
return errmsg(pr("break.errors.location")) unless b
|
|
45
47
|
|
|
46
48
|
return puts(pr("break.created", id: b.id, file: b.source, line: b.pos)) if syntax_valid?(@match[2])
|
data/lib/byebug/commands/help.rb
CHANGED
data/lib/byebug/commands/info.rb
CHANGED
data/lib/byebug/commands/irb.rb
CHANGED
|
@@ -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 }
|
data/lib/byebug/commands/set.rb
CHANGED
data/lib/byebug/commands/step.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Byebug
|
|
|
7
7
|
#
|
|
8
8
|
# Implements the step functionality.
|
|
9
9
|
#
|
|
10
|
-
# Allows the user the continue execution until the next instruction,
|
|
10
|
+
# Allows the user the continue execution until the next instruction, possibly
|
|
11
11
|
# in a different frame. Use step to step into method calls or blocks.
|
|
12
12
|
#
|
|
13
13
|
class StepCommand < Command
|
|
@@ -20,7 +20,7 @@ module Byebug
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def self.short_description
|
|
23
|
-
"Stops tracing a global variable"
|
|
23
|
+
"Stops tracing a global variable."
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def execute
|
|
@@ -29,7 +29,7 @@ module Byebug
|
|
|
29
29
|
untrace_var(:"#{var}")
|
|
30
30
|
puts pr("trace.messages.undo", var: var)
|
|
31
31
|
else
|
|
32
|
-
errmsg pr("trace.errors.
|
|
32
|
+
errmsg pr("trace.errors.var_is_not_global", name: var)
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
end
|