byebug 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +125 -99
- data/CONTRIBUTING.md +4 -6
- data/GUIDE.md +42 -20
- data/Gemfile +5 -3
- data/README.md +2 -3
- data/Rakefile +11 -7
- data/bin/byebug +2 -252
- data/byebug.gemspec +7 -4
- data/ext/byebug/byebug.c +17 -18
- data/ext/byebug/byebug.h +4 -5
- data/ext/byebug/context.c +37 -39
- data/ext/byebug/threads.c +39 -18
- data/lib/byebug.rb +2 -110
- data/lib/byebug/attacher.rb +23 -0
- data/lib/byebug/breakpoint.rb +60 -0
- data/lib/byebug/command.rb +62 -70
- data/lib/byebug/commands/break.rb +24 -24
- data/lib/byebug/commands/catchpoint.rb +18 -10
- data/lib/byebug/commands/condition.rb +18 -17
- data/lib/byebug/commands/continue.rb +17 -9
- data/lib/byebug/commands/delete.rb +19 -13
- data/lib/byebug/commands/display.rb +19 -53
- data/lib/byebug/commands/edit.rb +7 -4
- data/lib/byebug/commands/enable_disable.rb +130 -0
- data/lib/byebug/commands/eval.rb +40 -22
- data/lib/byebug/commands/finish.rb +13 -4
- data/lib/byebug/commands/frame.rb +65 -45
- data/lib/byebug/commands/help.rb +17 -18
- data/lib/byebug/commands/history.rb +14 -8
- data/lib/byebug/commands/info.rb +160 -182
- data/lib/byebug/commands/interrupt.rb +4 -1
- data/lib/byebug/commands/irb.rb +30 -0
- data/lib/byebug/commands/kill.rb +7 -8
- data/lib/byebug/commands/list.rb +71 -66
- data/lib/byebug/commands/method.rb +14 -6
- data/lib/byebug/commands/pry.rb +35 -0
- data/lib/byebug/commands/quit.rb +9 -6
- data/lib/byebug/commands/reload.rb +5 -2
- data/lib/byebug/commands/restart.rb +13 -9
- data/lib/byebug/commands/save.rb +17 -17
- data/lib/byebug/commands/set.rb +16 -15
- data/lib/byebug/commands/show.rb +10 -11
- data/lib/byebug/commands/source.rb +11 -5
- data/lib/byebug/commands/stepping.rb +38 -24
- data/lib/byebug/commands/threads.rb +45 -31
- data/lib/byebug/commands/trace.rb +22 -9
- data/lib/byebug/commands/undisplay.rb +45 -0
- data/lib/byebug/commands/variables.rb +83 -27
- data/lib/byebug/context.rb +25 -22
- data/lib/byebug/core.rb +82 -0
- data/lib/byebug/helper.rb +37 -28
- data/lib/byebug/history.rb +8 -4
- data/lib/byebug/interface.rb +12 -17
- data/lib/byebug/interfaces/local_interface.rb +11 -8
- data/lib/byebug/interfaces/remote_interface.rb +11 -8
- data/lib/byebug/interfaces/script_interface.rb +9 -6
- data/lib/byebug/options.rb +46 -0
- data/lib/byebug/processor.rb +7 -1
- data/lib/byebug/processors/command_processor.rb +135 -125
- data/lib/byebug/processors/control_command_processor.rb +23 -23
- data/lib/byebug/remote.rb +17 -26
- data/lib/byebug/runner.rb +100 -0
- data/lib/byebug/setting.rb +33 -8
- data/lib/byebug/settings/autoeval.rb +5 -15
- data/lib/byebug/settings/autoirb.rb +4 -1
- data/lib/byebug/settings/autolist.rb +5 -2
- data/lib/byebug/settings/autoreload.rb +5 -2
- data/lib/byebug/settings/autosave.rb +6 -2
- data/lib/byebug/settings/basename.rb +7 -2
- data/lib/byebug/settings/callstyle.rb +4 -1
- data/lib/byebug/settings/forcestep.rb +6 -3
- data/lib/byebug/settings/fullpath.rb +5 -2
- data/lib/byebug/settings/histfile.rb +5 -3
- data/lib/byebug/settings/histsize.rb +5 -3
- data/lib/byebug/settings/linetrace.rb +4 -1
- data/lib/byebug/settings/listsize.rb +5 -1
- data/lib/byebug/settings/post_mortem.rb +21 -13
- data/lib/byebug/settings/stack_on_error.rb +6 -2
- data/lib/byebug/settings/testing.rb +6 -1
- data/lib/byebug/settings/tracing_plus.rb +5 -1
- data/lib/byebug/settings/verbose.rb +13 -2
- data/lib/byebug/settings/width.rb +4 -1
- data/lib/byebug/version.rb +1 -1
- data/test/{break_test.rb → commands/break_test.rb} +41 -53
- data/test/{condition_test.rb → commands/condition_test.rb} +14 -14
- data/test/{continue_test.rb → commands/continue_test.rb} +0 -0
- data/test/{delete_test.rb → commands/delete_test.rb} +2 -2
- data/test/commands/display_test.rb +37 -0
- data/test/{edit_test.rb → commands/edit_test.rb} +0 -0
- data/test/{eval_test.rb → commands/eval_test.rb} +1 -0
- data/test/{finish_test.rb → commands/finish_test.rb} +11 -1
- data/test/{frame_test.rb → commands/frame_test.rb} +12 -16
- data/test/{help_test.rb → commands/help_test.rb} +21 -4
- data/test/{history_test.rb → commands/history_test.rb} +0 -0
- data/test/{info_test.rb → commands/info_test.rb} +5 -55
- data/test/{interrupt_test.rb → commands/interrupt_test.rb} +0 -0
- data/test/commands/irb_test.rb +28 -0
- data/test/{kill_test.rb → commands/kill_test.rb} +1 -1
- data/test/{list_test.rb → commands/list_test.rb} +1 -1
- data/test/{method_test.rb → commands/method_test.rb} +0 -0
- data/test/{post_mortem_test.rb → commands/post_mortem_test.rb} +6 -10
- data/test/{pry_test.rb → commands/pry_test.rb} +4 -13
- data/test/{quit_test.rb → commands/quit_test.rb} +4 -4
- data/test/{reload_test.rb → commands/reload_test.rb} +0 -0
- data/test/{restart_test.rb → commands/restart_test.rb} +6 -0
- data/test/{save_test.rb → commands/save_test.rb} +2 -2
- data/test/{set_test.rb → commands/set_test.rb} +9 -2
- data/test/{show_test.rb → commands/show_test.rb} +1 -1
- data/test/{source_test.rb → commands/source_test.rb} +3 -3
- data/test/{stepping_test.rb → commands/stepping_test.rb} +44 -35
- data/test/{thread_test.rb → commands/thread_test.rb} +0 -0
- data/test/{trace_test.rb → commands/trace_test.rb} +0 -0
- data/test/{display_test.rb → commands/undisplay_test.rb} +7 -45
- data/test/{variables_test.rb → commands/variables_test.rb} +10 -1
- data/test/debugger_alias_test.rb +2 -2
- data/test/runner_test.rb +127 -0
- data/test/support/matchers.rb +27 -25
- data/test/support/test_interface.rb +9 -5
- data/test/support/utils.rb +96 -101
- data/test/test_helper.rb +32 -20
- metadata +93 -68
- data/lib/byebug/commands/enable.rb +0 -154
- data/lib/byebug/commands/repl.rb +0 -126
- data/test/irb_test.rb +0 -47
- data/test/support/breakpoint.rb +0 -13
data/ext/byebug/byebug.h
CHANGED
@@ -66,16 +66,15 @@ extern void add_to_locked(VALUE thread);
|
|
66
66
|
extern VALUE remove_from_locked();
|
67
67
|
|
68
68
|
/* functions from threads.c */
|
69
|
-
extern VALUE
|
70
|
-
extern
|
71
|
-
extern void
|
69
|
+
extern void Init_threads_table(VALUE mByebug);
|
70
|
+
extern VALUE create_threads_table(void);
|
71
|
+
extern void check_threads_table(void);
|
72
72
|
extern void thread_context_lookup(VALUE thread, VALUE *context);
|
73
73
|
extern void halt_while_other_thread_is_active(debug_context_t *dc);
|
74
74
|
|
75
75
|
/* global variables */
|
76
76
|
extern VALUE locker;
|
77
77
|
extern VALUE threads;
|
78
|
-
extern VALUE cThreadsTable;
|
79
78
|
|
80
79
|
/* functions */
|
81
80
|
extern void Init_context(VALUE mByebug);
|
@@ -117,11 +116,11 @@ typedef struct {
|
|
117
116
|
enum hit_condition hit_condition;
|
118
117
|
} breakpoint_t;
|
119
118
|
|
119
|
+
extern void Init_breakpoint(VALUE mByebug);
|
120
120
|
extern VALUE catchpoint_hit_count(VALUE catchpoints, VALUE exception, VALUE *exception_name);
|
121
121
|
extern VALUE find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos,
|
122
122
|
VALUE binding);
|
123
123
|
extern VALUE find_breakpoint_by_method(VALUE breakpoints, VALUE klass,
|
124
124
|
VALUE mid, VALUE binding, VALUE self);
|
125
|
-
extern void Init_breakpoint(VALUE mByebug);
|
126
125
|
|
127
126
|
#endif
|
data/ext/byebug/context.c
CHANGED
@@ -40,7 +40,7 @@ context_mark(void *data)
|
|
40
40
|
static int
|
41
41
|
real_stack_size()
|
42
42
|
{
|
43
|
-
return FIX2INT(rb_funcall(cContext, rb_intern("stack_size"),
|
43
|
+
return FIX2INT(rb_funcall(cContext, rb_intern("stack_size"), 0));
|
44
44
|
}
|
45
45
|
|
46
46
|
extern VALUE
|
@@ -182,25 +182,19 @@ call_with_debug_inspector(struct call_with_inspection_data *data)
|
|
182
182
|
close_debug_inspector, (VALUE)data);
|
183
183
|
}
|
184
184
|
|
185
|
-
#define FRAME_SETUP
|
186
|
-
debug_context_t *context;
|
187
|
-
VALUE frame_no;
|
188
|
-
int frame_n
|
189
|
-
Data_Get_Struct(self, debug_context_t, context);
|
190
|
-
if (!rb_scan_args(argc, argv, "01", &frame_no))
|
191
|
-
frame_n = 0;
|
192
|
-
else
|
193
|
-
frame_n = FIX2INT(frame_no);
|
194
|
-
stack_size = real_stack_size(); \
|
195
|
-
if (frame_n < 0 || frame_n >= stack_size) \
|
196
|
-
{ \
|
197
|
-
rb_raise(rb_eArgError, "Invalid frame number %d, stack (0...%d)", \
|
198
|
-
frame_n, stack_size - 1); \
|
199
|
-
} \
|
185
|
+
#define FRAME_SETUP \
|
186
|
+
debug_context_t *context; \
|
187
|
+
VALUE frame_no; \
|
188
|
+
int frame_n; \
|
189
|
+
Data_Get_Struct(self, debug_context_t, context); \
|
190
|
+
if (!rb_scan_args(argc, argv, "01", &frame_no)) \
|
191
|
+
frame_n = 0; \
|
192
|
+
else \
|
193
|
+
frame_n = FIX2INT(frame_no);
|
200
194
|
|
201
195
|
/*
|
202
196
|
* call-seq:
|
203
|
-
* context.frame_binding(frame_position=0) -> binding
|
197
|
+
* context.frame_binding(frame_position = 0) -> binding
|
204
198
|
*
|
205
199
|
* Returns frame's binding.
|
206
200
|
*/
|
@@ -214,7 +208,7 @@ Context_frame_binding(int argc, VALUE *argv, VALUE self)
|
|
214
208
|
|
215
209
|
/*
|
216
210
|
* call-seq:
|
217
|
-
* context.frame_class(frame_position=0) -> binding
|
211
|
+
* context.frame_class(frame_position = 0) -> binding
|
218
212
|
*
|
219
213
|
* Returns frame's defined class.
|
220
214
|
*/
|
@@ -228,7 +222,7 @@ Context_frame_class(int argc, VALUE *argv, VALUE self)
|
|
228
222
|
|
229
223
|
/*
|
230
224
|
* call-seq:
|
231
|
-
* context.frame_file(frame_position=0) -> string
|
225
|
+
* context.frame_file(frame_position = 0) -> string
|
232
226
|
*
|
233
227
|
* Returns the name of the file in the frame.
|
234
228
|
*/
|
@@ -418,32 +412,32 @@ Context_step_into(int argc, VALUE *argv, VALUE self)
|
|
418
412
|
|
419
413
|
/*
|
420
414
|
* call-seq:
|
421
|
-
* context.step_out(
|
415
|
+
* context.step_out(n_frames = 1, force = false)
|
422
416
|
*
|
423
|
-
* Stops after +n_frames+ frames are finished.
|
424
|
-
*
|
425
|
-
*
|
426
|
-
*
|
427
|
-
* triggered.
|
417
|
+
* Stops after +n_frames+ frames are finished. +force+ parameter (if true)
|
418
|
+
* ensures that the execution will stop in the specified frame even when there
|
419
|
+
* are no more instructions to run. In that case, it will stop when the return
|
420
|
+
* event for that frame is triggered.
|
428
421
|
*/
|
429
422
|
static VALUE
|
430
423
|
Context_step_out(int argc, VALUE *argv, VALUE self)
|
431
424
|
{
|
432
425
|
int n_args, n_frames;
|
433
|
-
VALUE v_frames,
|
426
|
+
VALUE v_frames, force;
|
434
427
|
debug_context_t *context;
|
435
428
|
|
436
|
-
n_args = rb_scan_args(argc, argv, "02", &v_frames, &
|
429
|
+
n_args = rb_scan_args(argc, argv, "02", &v_frames, &force);
|
437
430
|
n_frames = n_args == 0 ? 1 : FIX2INT(v_frames);
|
438
|
-
v_force = (n_args < 2) ? Qfalse : v_force;
|
439
431
|
|
440
432
|
Data_Get_Struct(self, debug_context_t, context);
|
441
433
|
|
442
434
|
if (n_frames < 0 || n_frames >= context->calced_stack_size)
|
443
|
-
rb_raise(rb_eRuntimeError,
|
435
|
+
rb_raise(rb_eRuntimeError,
|
436
|
+
"You wan't to finish %d frames, but stack size is only %d",
|
437
|
+
n_frames, context->calced_stack_size);
|
444
438
|
|
445
439
|
context->steps_out = n_frames;
|
446
|
-
if (RTEST(
|
440
|
+
if (n_args == 2 && RTEST(force))
|
447
441
|
CTX_FL_SET(context, CTX_FL_STOP_ON_RET);
|
448
442
|
else
|
449
443
|
CTX_FL_UNSET(context, CTX_FL_STOP_ON_RET);
|
@@ -453,17 +447,18 @@ Context_step_out(int argc, VALUE *argv, VALUE self)
|
|
453
447
|
|
454
448
|
/*
|
455
449
|
* call-seq:
|
456
|
-
* context.step_over(lines, frame =
|
450
|
+
* context.step_over(lines, frame = 0, force = false)
|
457
451
|
*
|
458
452
|
* Steps over +lines+ lines.
|
459
|
-
* Make step over operation on +frame+, by default the
|
453
|
+
* Make step over operation on +frame+, by default the newest frame.
|
460
454
|
* +force+ parameter (if true) ensures that the cursor moves away from the
|
461
455
|
* current line.
|
462
456
|
*/
|
463
457
|
static VALUE
|
464
458
|
Context_step_over(int argc, VALUE *argv, VALUE self)
|
465
459
|
{
|
466
|
-
|
460
|
+
int n_args, frame;
|
461
|
+
VALUE lines, v_frame, force;
|
467
462
|
debug_context_t *context;
|
468
463
|
|
469
464
|
Data_Get_Struct(self, debug_context_t, context);
|
@@ -471,14 +466,18 @@ Context_step_over(int argc, VALUE *argv, VALUE self)
|
|
471
466
|
if (context->calced_stack_size == 0)
|
472
467
|
rb_raise(rb_eRuntimeError, "No frames collected.");
|
473
468
|
|
474
|
-
rb_scan_args(argc, argv, "12", &lines, &
|
475
|
-
|
476
|
-
|
469
|
+
n_args = rb_scan_args(argc, argv, "12", &lines, &v_frame, &force);
|
470
|
+
frame = n_args == 1 ? 0 : FIX2INT(v_frame);
|
471
|
+
|
472
|
+
if (frame < 0 || frame >= context->calced_stack_size)
|
473
|
+
rb_raise(rb_eRuntimeError,
|
474
|
+
"Destination frame (%d) is out of range (%d)",
|
475
|
+
frame, context->calced_stack_size);
|
477
476
|
|
478
477
|
context->lines = FIX2INT(lines);
|
479
|
-
context->dest_frame = context->calced_stack_size -
|
478
|
+
context->dest_frame = context->calced_stack_size - frame;
|
480
479
|
|
481
|
-
if (RTEST(force))
|
480
|
+
if (n_args == 3 && RTEST(force))
|
482
481
|
CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
|
483
482
|
else
|
484
483
|
CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
|
@@ -597,7 +596,6 @@ Context_set_tracing(VALUE self, VALUE value)
|
|
597
596
|
return value;
|
598
597
|
}
|
599
598
|
|
600
|
-
|
601
599
|
/* :nodoc: */
|
602
600
|
static VALUE
|
603
601
|
DebugThread_inherited(VALUE klass)
|
data/ext/byebug/threads.c
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
#include <byebug.h>
|
2
2
|
|
3
|
+
/* Threads table class */
|
4
|
+
static VALUE cThreadsTable;
|
5
|
+
|
3
6
|
static int
|
4
7
|
t_tbl_mark_keyvalue(st_data_t key, st_data_t value, st_data_t tbl)
|
5
8
|
{
|
@@ -29,8 +32,12 @@ t_tbl_free(void* data)
|
|
29
32
|
xfree(t_tbl);
|
30
33
|
}
|
31
34
|
|
35
|
+
/*
|
36
|
+
* Creates a numeric hash whose keys are the currently active threads and
|
37
|
+
* whose values are their associated contexts.
|
38
|
+
*/
|
32
39
|
VALUE
|
33
|
-
|
40
|
+
create_threads_table(void)
|
34
41
|
{
|
35
42
|
threads_table_t *t_tbl;
|
36
43
|
|
@@ -39,42 +46,42 @@ threads_create(void)
|
|
39
46
|
return Data_Wrap_Struct(cThreadsTable, t_tbl_mark, t_tbl_free, t_tbl);
|
40
47
|
}
|
41
48
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
Data_Get_Struct(table, threads_table_t, t_tbl);
|
48
|
-
st_clear(t_tbl->tbl);
|
49
|
-
}
|
50
|
-
|
49
|
+
/*
|
50
|
+
* The condition to be in the thread's table is to be either running or
|
51
|
+
* sleeping, namely, to be Thread#alive?
|
52
|
+
*/
|
51
53
|
static int
|
52
54
|
is_living_thread(VALUE thread)
|
53
55
|
{
|
54
56
|
return rb_funcall(thread, rb_intern("alive?"), 0) == Qtrue;
|
55
57
|
}
|
56
58
|
|
59
|
+
/*
|
60
|
+
* Checks a single entry in the threads table.
|
61
|
+
*
|
62
|
+
* If it has no associated context or the key doesn't correspond to a living
|
63
|
+
* thread, the entry is removed from the thread's list.
|
64
|
+
*/
|
57
65
|
static int
|
58
|
-
|
66
|
+
check_thread_i(st_data_t key, st_data_t value, st_data_t dummy)
|
59
67
|
{
|
60
|
-
VALUE thread;
|
61
|
-
|
62
68
|
if (!value) return ST_DELETE;
|
63
69
|
|
64
|
-
|
65
|
-
|
66
|
-
if (!is_living_thread(thread)) return ST_DELETE;
|
70
|
+
if (!is_living_thread((VALUE)key)) return ST_DELETE;
|
67
71
|
|
68
72
|
return ST_CONTINUE;
|
69
73
|
}
|
70
74
|
|
75
|
+
/*
|
76
|
+
* Checks threads table for dead/finished threads.
|
77
|
+
*/
|
71
78
|
void
|
72
|
-
|
79
|
+
check_threads_table(void)
|
73
80
|
{
|
74
81
|
threads_table_t *t_tbl;
|
75
82
|
|
76
83
|
Data_Get_Struct(threads, threads_table_t, t_tbl);
|
77
|
-
st_foreach(t_tbl->tbl,
|
84
|
+
st_foreach(t_tbl->tbl, check_thread_i, 0);
|
78
85
|
}
|
79
86
|
|
80
87
|
void
|
@@ -111,3 +118,17 @@ halt_while_other_thread_is_active(debug_context_t *dc)
|
|
111
118
|
else break;
|
112
119
|
}
|
113
120
|
}
|
121
|
+
|
122
|
+
/*
|
123
|
+
*
|
124
|
+
* Document-class: ThreadsTable
|
125
|
+
*
|
126
|
+
* == Sumary
|
127
|
+
*
|
128
|
+
* Hash table holding currently active threads and their associated contexts
|
129
|
+
*/
|
130
|
+
void
|
131
|
+
Init_threads_table(VALUE mByebug)
|
132
|
+
{
|
133
|
+
cThreadsTable = rb_define_class_under(mByebug, "ThreadsTable", rb_cObject);
|
134
|
+
}
|
data/lib/byebug.rb
CHANGED
@@ -1,110 +1,2 @@
|
|
1
|
-
require 'byebug/
|
2
|
-
require 'byebug/
|
3
|
-
require 'byebug/context'
|
4
|
-
require 'byebug/interface'
|
5
|
-
require 'byebug/processor'
|
6
|
-
require 'byebug/setting'
|
7
|
-
require 'byebug/remote'
|
8
|
-
require 'stringio'
|
9
|
-
require 'tracer'
|
10
|
-
require 'linecache19'
|
11
|
-
|
12
|
-
module Byebug
|
13
|
-
|
14
|
-
# List of files byebug will ignore while debugging
|
15
|
-
IGNORED_FILES = Dir.glob(File.expand_path('../**/*.rb', __FILE__))
|
16
|
-
|
17
|
-
# Configuration file used for startup commands. Default value is .byebugrc
|
18
|
-
INITFILE = '.byebugrc' unless defined?(INITFILE)
|
19
|
-
|
20
|
-
# Stores program being debugged to make restarts possible
|
21
|
-
PROG_SCRIPT = $0 unless defined?(PROG_SCRIPT)
|
22
|
-
|
23
|
-
class << self
|
24
|
-
|
25
|
-
# processor modules provide +handler+ object
|
26
|
-
attr_accessor :handler
|
27
|
-
Byebug.handler = CommandProcessor.new
|
28
|
-
|
29
|
-
def source_reload
|
30
|
-
hsh = 'SCRIPT_LINES__'
|
31
|
-
Object.send(:remove_const, hsh) if Object.const_defined?(hsh)
|
32
|
-
Object.const_set(hsh, {})
|
33
|
-
end
|
34
|
-
|
35
|
-
#
|
36
|
-
# Add a new breakpoint
|
37
|
-
#
|
38
|
-
# @param [String] file
|
39
|
-
# @param [Fixnum] line
|
40
|
-
# @param [String] expr
|
41
|
-
#
|
42
|
-
def add_breakpoint(file, line, expr=nil)
|
43
|
-
breakpoint = Breakpoint.new(file, line, expr)
|
44
|
-
breakpoints << breakpoint
|
45
|
-
breakpoint
|
46
|
-
end
|
47
|
-
|
48
|
-
#
|
49
|
-
# Remove a breakpoint
|
50
|
-
#
|
51
|
-
# @param [integer] breakpoint number
|
52
|
-
#
|
53
|
-
def remove_breakpoint(id)
|
54
|
-
breakpoints.reject! { |b| b.id == id }
|
55
|
-
end
|
56
|
-
|
57
|
-
def interface=(value)
|
58
|
-
handler.interface = value
|
59
|
-
end
|
60
|
-
|
61
|
-
extend Forwardable
|
62
|
-
def_delegators :"handler.interface", :print
|
63
|
-
|
64
|
-
#
|
65
|
-
# Runs normal byebug initialization scripts.
|
66
|
-
#
|
67
|
-
# Reads and executes the commands from init file (if any) in the current
|
68
|
-
# working directory. This is only done if the current directory is
|
69
|
-
# different from your home directory. Thus, you can have more than one init
|
70
|
-
# file, one generic in your home directory, and another, specific to the
|
71
|
-
# program you are debugging, in the directory where you invoke byebug.
|
72
|
-
#
|
73
|
-
def run_init_script(out = handler.interface)
|
74
|
-
cwd_script = File.expand_path(File.join(".", INITFILE))
|
75
|
-
run_script(cwd_script, out) if File.exist?(cwd_script)
|
76
|
-
|
77
|
-
home_script = File.expand_path(File.join(ENV['HOME'].to_s, INITFILE))
|
78
|
-
if File.exist?(home_script) and cwd_script != home_script
|
79
|
-
run_script(home_script, out)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
#
|
84
|
-
# Runs a script file
|
85
|
-
#
|
86
|
-
def run_script(file, out = handler.interface, verbose=false)
|
87
|
-
interface = ScriptInterface.new(File.expand_path(file), out)
|
88
|
-
processor = ControlCommandProcessor.new(interface)
|
89
|
-
processor.process_commands(verbose)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
class Exception
|
95
|
-
attr_reader :__bb_file, :__bb_line, :__bb_binding, :__bb_context
|
96
|
-
end
|
97
|
-
|
98
|
-
module Kernel
|
99
|
-
#
|
100
|
-
# Enters byebug right before (or right after if _before_ is false) return
|
101
|
-
# events occur. Before entering byebug the init script is read.
|
102
|
-
#
|
103
|
-
def byebug(steps_out = 1, before = true)
|
104
|
-
Byebug.run_init_script(StringIO.new)
|
105
|
-
Byebug.start
|
106
|
-
Byebug.current_context.step_out(steps_out, before)
|
107
|
-
end
|
108
|
-
|
109
|
-
alias_method :debugger, :byebug
|
110
|
-
end
|
1
|
+
require 'byebug/core'
|
2
|
+
require 'byebug/attacher'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Byebug
|
2
|
+
# Stores program being debugged to make restarts possible
|
3
|
+
PROG_SCRIPT = $PROGRAM_NAME unless defined?(PROG_SCRIPT)
|
4
|
+
end
|
5
|
+
|
6
|
+
#
|
7
|
+
# Adds a `byebug` method to the Kernel module.
|
8
|
+
#
|
9
|
+
# Dropping a `byebug` call anywhere in your code, you get a debug prompt.
|
10
|
+
#
|
11
|
+
module Kernel
|
12
|
+
#
|
13
|
+
# Enters byebug right before (or right after if _before_ is false) return
|
14
|
+
# events occur. Before entering byebug the init script is read.
|
15
|
+
#
|
16
|
+
def byebug(steps_out = 1, before = true)
|
17
|
+
Byebug.start
|
18
|
+
Byebug.run_init_script(StringIO.new)
|
19
|
+
Byebug.current_context.step_out(steps_out, before)
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :debugger, :byebug
|
23
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Byebug
|
2
|
+
#
|
3
|
+
# Implements breakpoints
|
4
|
+
#
|
5
|
+
class Breakpoint
|
6
|
+
#
|
7
|
+
# First breakpoint, in order of creation
|
8
|
+
#
|
9
|
+
def self.first
|
10
|
+
Byebug.breakpoints.first
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Last breakpoint, in order of creation
|
15
|
+
#
|
16
|
+
def self.last
|
17
|
+
Byebug.breakpoints.last
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Adds a new breakpoint
|
22
|
+
#
|
23
|
+
# @param [String] file
|
24
|
+
# @param [Fixnum] line
|
25
|
+
# @param [String] expr
|
26
|
+
#
|
27
|
+
def self.add(file, line, expr = nil)
|
28
|
+
breakpoint = Breakpoint.new(file, line, expr)
|
29
|
+
Byebug.breakpoints << breakpoint
|
30
|
+
breakpoint
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Removes a breakpoint
|
35
|
+
#
|
36
|
+
# @param [integer] breakpoint number
|
37
|
+
#
|
38
|
+
def self.remove(id)
|
39
|
+
Byebug.breakpoints.reject! { |b| b.id == id }
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# True if there's no breakpoints
|
44
|
+
#
|
45
|
+
def self.none?
|
46
|
+
Byebug.breakpoints.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Prints all information associated to the breakpoint
|
51
|
+
#
|
52
|
+
def inspect
|
53
|
+
meths = %w(id pos source expr hit_condition hit_count hit_value enabled?)
|
54
|
+
values = meths.map do |field|
|
55
|
+
"#{field}: #{send(field)}"
|
56
|
+
end.join(', ')
|
57
|
+
"#<Byebug::Breakpoint #{values}>"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|