byebug 1.8.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/GUIDE.md +14 -22
  4. data/README.md +69 -6
  5. data/bin/byebug +3 -20
  6. data/ext/byebug/breakpoint.c +185 -101
  7. data/ext/byebug/byebug.c +393 -214
  8. data/ext/byebug/byebug.h +34 -15
  9. data/ext/byebug/context.c +327 -102
  10. data/ext/byebug/extconf.rb +1 -1
  11. data/ext/byebug/locker.c +54 -0
  12. data/ext/byebug/threads.c +113 -0
  13. data/lib/byebug.rb +19 -58
  14. data/lib/byebug/command.rb +18 -19
  15. data/lib/byebug/commands/breakpoints.rb +1 -4
  16. data/lib/byebug/commands/catchpoint.rb +1 -1
  17. data/lib/byebug/commands/condition.rb +1 -1
  18. data/lib/byebug/commands/control.rb +2 -3
  19. data/lib/byebug/commands/display.rb +2 -7
  20. data/lib/byebug/commands/edit.rb +1 -1
  21. data/lib/byebug/commands/enable.rb +12 -12
  22. data/lib/byebug/commands/eval.rb +4 -4
  23. data/lib/byebug/commands/finish.rb +1 -1
  24. data/lib/byebug/commands/frame.rb +12 -8
  25. data/lib/byebug/commands/info.rb +20 -52
  26. data/lib/byebug/commands/kill.rb +1 -5
  27. data/lib/byebug/commands/list.rb +2 -1
  28. data/lib/byebug/commands/quit.rb +1 -1
  29. data/lib/byebug/commands/repl.rb +2 -2
  30. data/lib/byebug/commands/save.rb +1 -1
  31. data/lib/byebug/commands/set.rb +84 -90
  32. data/lib/byebug/commands/show.rb +44 -53
  33. data/lib/byebug/commands/skip.rb +1 -1
  34. data/lib/byebug/commands/stepping.rb +5 -4
  35. data/lib/byebug/commands/threads.rb +202 -0
  36. data/lib/byebug/commands/trace.rb +1 -1
  37. data/lib/byebug/helper.rb +3 -3
  38. data/lib/byebug/interface.rb +2 -20
  39. data/lib/byebug/processor.rb +21 -100
  40. data/lib/byebug/remote.rb +3 -3
  41. data/lib/byebug/version.rb +1 -1
  42. data/old_doc/byebug.1 +0 -6
  43. data/old_doc/byebug.texi +29 -46
  44. data/test/breakpoints_test.rb +44 -65
  45. data/test/conditions_test.rb +0 -9
  46. data/test/continue_test.rb +2 -2
  47. data/test/display_test.rb +4 -23
  48. data/test/edit_test.rb +2 -16
  49. data/test/eval_test.rb +4 -13
  50. data/test/examples/thread.rb +32 -0
  51. data/test/finish_test.rb +1 -13
  52. data/test/frame_test.rb +5 -12
  53. data/test/help_test.rb +2 -12
  54. data/test/info_test.rb +8 -18
  55. data/test/kill_test.rb +1 -10
  56. data/test/list_test.rb +5 -14
  57. data/test/method_test.rb +1 -10
  58. data/test/post_mortem_test.rb +247 -14
  59. data/test/quit_test.rb +0 -9
  60. data/test/reload_test.rb +1 -15
  61. data/test/repl_test.rb +1 -9
  62. data/test/restart_test.rb +3 -18
  63. data/test/save_test.rb +1 -13
  64. data/test/set_test.rb +35 -32
  65. data/test/show_test.rb +8 -27
  66. data/test/source_test.rb +1 -8
  67. data/test/stepping_test.rb +65 -96
  68. data/test/support/test_dsl.rb +12 -17
  69. data/test/test_helper.rb +1 -1
  70. data/test/thread_test.rb +106 -0
  71. data/test/trace_test.rb +5 -17
  72. data/test/variables_test.rb +1 -10
  73. metadata +9 -7
  74. data/lib/byebug/commands/jump.rb +0 -52
  75. data/test/jump_test.rb +0 -77
  76. data/test/support/context.rb +0 -15
@@ -69,13 +69,4 @@ class TestConditions < TestDsl::TestCase
69
69
  debug_file('conditions') { $state.line.must_equal 3 }
70
70
  end
71
71
  end
72
-
73
- describe 'Post Mortem' do
74
- it 'must be able to set conditions in post-mortem mode' do
75
- enter 'cont', 'break 12', ->{ "cond #{Byebug.breakpoints.first.id} true" },
76
- 'cont'
77
- debug_file('post_mortem') { $state.line.must_equal 12 }
78
- end
79
- end
80
-
81
72
  end
@@ -28,8 +28,8 @@ class TestContinue < TestDsl::TestCase
28
28
  it "must show error if specified line is not valid" do
29
29
  enter 'cont 123'
30
30
  debug_file 'continue'
31
- check_output_includes "Line 123 is not a stopping point in file " \
32
- "\"#{fullpath('continue')}\"", interface.error_queue
31
+ check_error_includes \
32
+ "Line 123 is not a stopping point in file \"#{fullpath('continue')}\""
33
33
  end
34
34
  end
35
35
  end
@@ -24,7 +24,7 @@ class TestDisplay < TestDsl::TestCase
24
24
  Byebug.handler.display.concat([[true, 'abc'], [true, 'd']]); 'display'
25
25
  end
26
26
  debug_file 'display'
27
- check_output_includes '1: ', 'abc = ', '2: ', 'd = 4'
27
+ check_output_includes '1: ', 'abc = nil', '2: ', 'd = 4'
28
28
  end
29
29
 
30
30
  describe 'undisplay' do
@@ -52,7 +52,7 @@ class TestDisplay < TestDsl::TestCase
52
52
 
53
53
  it 'must not show any output' do
54
54
  debug_file 'display'
55
- check_output_doesnt_include '1: ', 'abc = ', '2: ', 'd = 4'
55
+ check_output_doesnt_include '1: ', 'abc = nil', '2: ', 'd = 4'
56
56
  end
57
57
  end
58
58
 
@@ -66,7 +66,7 @@ class TestDisplay < TestDsl::TestCase
66
66
 
67
67
  it 'must not show any output' do
68
68
  debug_file 'display'
69
- check_output_includes '1: ', 'abc = ', '2: ', 'd = 4'
69
+ check_output_includes '1: ', 'abc = nil', '2: ', 'd = 4'
70
70
  end
71
71
  end
72
72
  end
@@ -113,7 +113,7 @@ class TestDisplay < TestDsl::TestCase
113
113
  enter 'display d', 'disable display 4'
114
114
  debug_file 'display'
115
115
  check_output_includes \
116
- 'Disable display argument "4" needs to be at most 1.'
116
+ '"disable display" argument "4" needs to be at most 1.'
117
117
  end
118
118
  end
119
119
 
@@ -123,23 +123,4 @@ class TestDisplay < TestDsl::TestCase
123
123
  debug_file('display') { $state.display.must_equal [[true, 'd']] }
124
124
  end
125
125
  end
126
-
127
- describe 'annotate' do
128
- after { Byebug.annotate = 0 }
129
-
130
- it 'must show display expression in annotation' do
131
- enter 'display 2 + 2', 'set annotate 3', 'next', 'next'
132
- debug_file 'display'
133
- check_output_includes "\u001A\u001Adisplay", '1:', '2 + 2 = 4'
134
- end
135
- end
136
-
137
- describe 'Post Mortem' do
138
- it 'must be able to set display expressions in post-mortem mode' do
139
- enter 'cont', 'display 2 + 2'
140
- debug_file 'post_mortem'
141
- check_output_includes '1:', '2 + 2 = 4'
142
- end
143
- end
144
-
145
126
  end
@@ -38,26 +38,12 @@ class TestEdit < TestDsl::TestCase
38
38
  it 'must show an error if there is no such line' do
39
39
  enter "edit #{fullpath('edit3')}:6"
40
40
  debug_file 'edit'
41
- check_output_includes \
42
- "File \"#{fullpath('edit3')}\" is not readable.", interface.error_queue
41
+ check_error_includes "File \"#{fullpath('edit3')}\" is not readable."
43
42
  end
44
43
 
45
44
  it 'must show an error if there is incorrect syntax' do
46
45
  enter 'edit blabla'
47
46
  debug_file 'edit'
48
- check_output_includes \
49
- 'Invalid file/line number specification: blabla', interface.error_queue
47
+ check_error_includes 'Invalid file/line number specification: blabla'
50
48
  end
51
-
52
- describe 'Post Mortem' do
53
- temporary_change_hash ENV, 'EDITOR', 'editr'
54
-
55
- it 'must work in post-mortem mode' do
56
- Byebug::Edit.any_instance.expects(:system).
57
- with("editr +2 #{fullpath('edit')}")
58
- enter 'cont', "edit #{fullpath('edit')}:2", 'cont'
59
- debug_file 'post_mortem'
60
- end
61
- end
62
-
63
49
  end
@@ -38,7 +38,7 @@ class TestEval < TestDsl::TestCase
38
38
 
39
39
  describe 'stack trace on error' do
40
40
  describe 'when enabled' do
41
- temporary_change_hash Byebug::Command.settings, :stack_trace_on_error, true
41
+ temporary_change_hash Byebug.settings, :stack_trace_on_error, true
42
42
 
43
43
  it 'must show a stack trace' do
44
44
  enter 'eval 2 / 0'
@@ -49,7 +49,7 @@ class TestEval < TestDsl::TestCase
49
49
  end
50
50
 
51
51
  describe 'when disabled' do
52
- temporary_change_hash Byebug::Command.settings, :stack_trace_on_error, false
52
+ temporary_change_hash Byebug.settings, :stack_trace_on_error, false
53
53
 
54
54
  it 'must only show exception' do
55
55
  enter 'eval 2 / 0'
@@ -69,7 +69,7 @@ class TestEval < TestDsl::TestCase
69
69
  end
70
70
 
71
71
  describe 'putl' do
72
- temporary_change_hash Byebug::Command.settings, :width, 20
72
+ temporary_change_hash Byebug.settings, :width, 20
73
73
 
74
74
  it 'must print expression and columnize the result' do
75
75
  enter 'putl [1, 2, 3, 4, 5, 9, 8, 7, 6]'
@@ -79,7 +79,7 @@ class TestEval < TestDsl::TestCase
79
79
  end
80
80
 
81
81
  describe 'ps' do
82
- temporary_change_hash Byebug::Command.settings, :width, 20
82
+ temporary_change_hash Byebug.settings, :width, 20
83
83
 
84
84
  it 'must print expression and sort and columnize the result' do
85
85
  enter 'ps [1, 2, 3, 4, 5, 9, 8, 7, 6]'
@@ -87,13 +87,4 @@ class TestEval < TestDsl::TestCase
87
87
  check_output_includes "1 3 5 7 9\n2 4 6 8"
88
88
  end
89
89
  end
90
-
91
- describe 'Post Mortem' do
92
- it 'must work in post-mortem mode' do
93
- enter 'cont', 'eval 2 + 2'
94
- debug_file 'post_mortem'
95
- check_output_includes '4'
96
- end
97
- end
98
-
99
90
  end
@@ -0,0 +1,32 @@
1
+ byebug
2
+ class ThreadExample
3
+ def initialize
4
+ Thread.main[:should_break] = false
5
+ end
6
+
7
+ def launch
8
+ @t1 = Thread.new do
9
+ while true
10
+ break if Thread.main[:should_break]
11
+ sleep 0.02
12
+ end
13
+ end
14
+
15
+ @t2 = Thread.new do
16
+ while true
17
+ sleep 0.02
18
+ end
19
+ end
20
+
21
+ @t1.join
22
+ Thread.main[:should_break]
23
+ end
24
+
25
+ def kill
26
+ @t2.kill
27
+ end
28
+ end
29
+
30
+ t = ThreadExample.new
31
+ t.launch
32
+ t.kill
@@ -27,23 +27,11 @@ class TestFinish < TestDsl::TestCase
27
27
 
28
28
  it 'must show an error' do
29
29
  debug_file('finish')
30
- check_output_includes 'Finish argument "foo" needs to be a number.'
30
+ check_output_includes '"finish" argument "foo" needs to be a number.'
31
31
  end
32
32
 
33
33
  it 'must be on the same line' do
34
34
  debug_file('finish') { $state.line.must_equal 16 }
35
35
  end
36
36
  end
37
-
38
- describe 'Post Mortem' do
39
- temporary_change_hash Byebug::Command.settings, :autoeval, false
40
-
41
- it 'must not work in post-mortem mode' do
42
- enter 'cont', 'finish'
43
- debug_file 'post_mortem'
44
- check_output_includes \
45
- 'Unknown command: "finish". Try "help".', interface.error_queue
46
- end
47
- end
48
-
49
37
  end
@@ -44,9 +44,8 @@ class TestFrame < TestDsl::TestCase
44
44
  end
45
45
 
46
46
  it 'must set frame to the last one' do
47
- enter 'bt', 'frame -1'
47
+ enter 'frame -1'
48
48
  debug_file('frame') { $state.file.must_match /minitest\/unit.rb/ }
49
- check_output_doesnt_include "at #{@tst_file}:"
50
49
  end
51
50
 
52
51
  it 'must not set frame if the frame number is too low' do
@@ -70,7 +69,7 @@ class TestFrame < TestDsl::TestCase
70
69
  end
71
70
 
72
71
  describe 'when set' do
73
- temporary_change_hash Byebug::Command.settings, :frame_fullpath, true
72
+ temporary_change_hash Byebug.settings, :fullpath, true
74
73
 
75
74
  it 'must display current backtrace with fullpaths' do
76
75
  enter 'where'
@@ -83,7 +82,7 @@ class TestFrame < TestDsl::TestCase
83
82
  end
84
83
 
85
84
  describe 'when unset' do
86
- temporary_change_hash Byebug::Command.settings, :frame_fullpath, false
85
+ temporary_change_hash Byebug.settings, :fullpath, false
87
86
 
88
87
  it 'must display current backtrace with shortpaths' do
89
88
  enter 'where'
@@ -99,7 +98,7 @@ class TestFrame < TestDsl::TestCase
99
98
 
100
99
  describe 'callstyle' do
101
100
  describe 'long' do
102
- temporary_change_hash Byebug::Command.settings, :callstyle, :long
101
+ temporary_change_hash Byebug.settings, :callstyle, :long
103
102
 
104
103
  it 'displays current backtrace with callstyle "long"' do
105
104
  enter 'where'
@@ -113,7 +112,7 @@ class TestFrame < TestDsl::TestCase
113
112
  end
114
113
 
115
114
  describe 'short' do
116
- temporary_change_hash Byebug::Command.settings, :callstyle, :short
115
+ temporary_change_hash Byebug.settings, :callstyle, :short
117
116
 
118
117
  it 'displays current backtrace with callstyle "short"' do
119
118
  enter 'where'
@@ -195,10 +194,4 @@ class TestFrame < TestDsl::TestCase
195
194
  end
196
195
  end
197
196
 
198
- describe 'Post Mortem' do
199
- it 'must work in post-mortem mode' do
200
- enter 'cont', 'frame'
201
- debug_file('post_mortem') { $state.line.must_equal 8 }
202
- end
203
- end
204
197
  end
@@ -7,7 +7,7 @@ class TestHelp < TestDsl::TestCase
7
7
  Byebug::Command.commands.select(&:event).map(&:names).flatten.uniq.sort }
8
8
 
9
9
  describe 'when typed alone' do
10
- temporary_change_hash Byebug::Command.settings, :width, 50
10
+ temporary_change_hash Byebug.settings, :width, 50
11
11
 
12
12
  it 'must show self help when typed alone' do
13
13
  enter 'help'
@@ -29,8 +29,7 @@ class TestHelp < TestDsl::TestCase
29
29
  it 'must show an error if an undefined command is specified' do
30
30
  enter 'help foobar'
31
31
  debug_file 'help'
32
- check_output_includes \
33
- 'Undefined command: "foobar". Try "help".', interface.error_queue
32
+ check_error_includes 'Undefined command: "foobar". Try "help".'
34
33
  end
35
34
 
36
35
  it "must show a command's help" do
@@ -53,13 +52,4 @@ class TestHelp < TestDsl::TestCase
53
52
  "With an integer argument, list info on that breakpoint."
54
53
  end
55
54
  end
56
-
57
- describe 'Post Mortem' do
58
- it 'must work in post-mortem mode' do
59
- enter 'cont', 'help'
60
- debug_file 'post_mortem'
61
- check_output_includes 'Available commands:'
62
- end
63
- end
64
-
65
55
  end
@@ -4,7 +4,7 @@ class TestInfo < TestDsl::TestCase
4
4
  include Columnize
5
5
 
6
6
  describe 'Args info' do
7
- temporary_change_hash Byebug::Command.settings, :width, 15
7
+ temporary_change_hash Byebug.settings, :width, 15
8
8
 
9
9
  it 'must show info about all args' do
10
10
  enter 'break 3', 'cont', 'info args'
@@ -39,8 +39,7 @@ class TestInfo < TestDsl::TestCase
39
39
  it 'must show an error if no breakpoints are found' do
40
40
  enter 'break 7', 'info breakpoints 123'
41
41
  debug_file 'info'
42
- check_output_includes \
43
- 'No breakpoints found among list given.', interface.error_queue
42
+ check_error_includes 'No breakpoints found among list given.'
44
43
  end
45
44
 
46
45
  it 'must show hit count' do
@@ -99,7 +98,7 @@ class TestInfo < TestDsl::TestCase
99
98
  let(:sha1) { LineCache.sha1(file) }
100
99
  let(:breakpoint_line_numbers) {
101
100
  columnize(LineCache.trace_line_numbers(file).to_a.sort,
102
- Byebug::Command.settings[:width]) }
101
+ Byebug.settings[:width]) }
103
102
 
104
103
  it 'must show basic info about the file' do
105
104
  enter "info file #{file} basic"
@@ -155,7 +154,7 @@ class TestInfo < TestDsl::TestCase
155
154
  it 'must not show any info if the parameter is invalid' do
156
155
  enter "info file #{file} blabla"
157
156
  debug_file 'info'
158
- check_output_includes 'Invalid parameter blabla', interface.error_queue
157
+ check_error_includes 'Invalid parameter blabla'
159
158
  end
160
159
  end
161
160
 
@@ -176,18 +175,18 @@ class TestInfo < TestDsl::TestCase
176
175
  end
177
176
 
178
177
  describe 'Locals info' do
179
- temporary_change_hash Byebug::Command.settings, :width, 21
178
+ temporary_change_hash Byebug.settings, :width, 28
180
179
 
181
180
  it 'must show the current local variables' do
182
181
  enter 'break 21', 'cont', 'info locals'
183
182
  debug_file 'info'
184
- check_output_includes 'a = "1111111111111...', 'b = 2'
183
+ check_output_includes 'a = "11111111111111111111...', 'b = 2'
185
184
  end
186
185
 
187
186
  it 'must fail if local variable doesn\'t respond to #to_s or to #inspect' do
188
187
  enter 'break 26', 'cont', 'info locals'
189
188
  debug_file 'info'
190
- check_output_includes '*Error in evaluation*'
189
+ check_output_includes 'a = *Error in evaluation*'
191
190
  end
192
191
  end
193
192
 
@@ -248,7 +247,7 @@ class TestInfo < TestDsl::TestCase
248
247
  end
249
248
 
250
249
  describe 'Variables info' do
251
- temporary_change_hash Byebug::Command.settings, :width, 30
250
+ temporary_change_hash Byebug.settings, :width, 30
252
251
 
253
252
  it 'must show all variables' do
254
253
  enter 'break 21', 'cont', 'info variables'
@@ -283,13 +282,4 @@ class TestInfo < TestDsl::TestCase
283
282
  check_output_includes /List of "info" subcommands:/
284
283
  end
285
284
  end
286
-
287
- describe 'Post Mortem' do
288
- it 'must work in post-mortem mode' do
289
- enter 'cont', 'info line'
290
- debug_file 'post_mortem'
291
- check_output_includes "Line 8 of \"#{fullpath('post_mortem')}\""
292
- end
293
- end
294
-
295
285
  end
@@ -32,16 +32,7 @@ class TestKill < TestDsl::TestCase
32
32
  it 'must show an error' do
33
33
  enter 'kill BLA'
34
34
  debug_file('kill')
35
- check_output_includes \
36
- 'signal name BLA is not a signal I know about', interface.error_queue
37
- end
38
- end
39
-
40
- describe 'Post Mortem' do
41
- it 'must work in post-mortem mode' do
42
- Process.expects(:kill).with('USR1', Process.pid)
43
- enter 'cont', 'kill USR1'
44
- debug_file 'post_mortem'
35
+ check_error_includes 'signal name BLA is not a signal I know about'
45
36
  end
46
37
  end
47
38
  end
@@ -28,7 +28,7 @@ class TestList < TestDsl::TestCase
28
28
  end
29
29
 
30
30
  describe 'very large' do
31
- temporary_change_hash Byebug::Command.settings, :listsize, 50
31
+ temporary_change_hash Byebug.settings, :listsize, 50
32
32
 
33
33
  it 'must list whole file if number of lines is smaller than listsize' do
34
34
  enter 'break 3', 'cont'
@@ -57,7 +57,7 @@ class TestList < TestDsl::TestCase
57
57
  end
58
58
 
59
59
  describe 'list backwards' do
60
- temporary_change_hash Byebug::Command.settings, :autolist, 0
60
+ temporary_change_hash Byebug.settings, :autolist, 0
61
61
 
62
62
  it 'must show surrounding lines with the first call' do
63
63
  enter 'break 15', 'cont', 'list -'
@@ -77,7 +77,7 @@ class TestList < TestDsl::TestCase
77
77
  end
78
78
 
79
79
  describe 'list surrounding' do
80
- temporary_change_hash Byebug::Command.settings, :autolist, 0
80
+ temporary_change_hash Byebug.settings, :autolist, 0
81
81
 
82
82
  it 'must show the surrounding lines with =' do
83
83
  enter 'break 5', 'cont', 'list ='
@@ -140,7 +140,7 @@ class TestList < TestDsl::TestCase
140
140
  after { change_line_in_file(fullpath('list'), 4, 'a = 4') }
141
141
 
142
142
  describe 'when autoreload is false' do
143
- temporary_change_hash Byebug::Command.settings, :autoreload, false
143
+ temporary_change_hash Byebug.settings, :autoreload, false
144
144
 
145
145
  it 'must not reload listing with file changes' do
146
146
  enter -> { change_line_in_file fullpath('list'), 4, 'a = 100' ;
@@ -163,8 +163,7 @@ class TestList < TestDsl::TestCase
163
163
  it 'must show an error when there is no such file' do
164
164
  enter -> { $state.file = 'blabla'; 'list 4-4' }
165
165
  debug_file 'list'
166
- check_output_includes 'No sourcefile available for blabla',
167
- interface.error_queue
166
+ check_error_includes 'No sourcefile available for blabla'
168
167
  end
169
168
 
170
169
  it 'must correctly print lines containing % sign' do
@@ -172,12 +171,4 @@ class TestList < TestDsl::TestCase
172
171
  debug_file 'list'
173
172
  check_output_includes "23: a = '%23'"
174
173
  end
175
-
176
- describe 'Post Mortem' do
177
- it 'must work in post-mortem mode' do
178
- enter 'cont'
179
- debug_file 'post_mortem'
180
- check_output_includes "[3, 12] in #{fullpath('post_mortem')}"
181
- end
182
- end
183
174
  end