byebug 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +125 -99
  4. data/CONTRIBUTING.md +4 -6
  5. data/GUIDE.md +42 -20
  6. data/Gemfile +5 -3
  7. data/README.md +2 -3
  8. data/Rakefile +11 -7
  9. data/bin/byebug +2 -252
  10. data/byebug.gemspec +7 -4
  11. data/ext/byebug/byebug.c +17 -18
  12. data/ext/byebug/byebug.h +4 -5
  13. data/ext/byebug/context.c +37 -39
  14. data/ext/byebug/threads.c +39 -18
  15. data/lib/byebug.rb +2 -110
  16. data/lib/byebug/attacher.rb +23 -0
  17. data/lib/byebug/breakpoint.rb +60 -0
  18. data/lib/byebug/command.rb +62 -70
  19. data/lib/byebug/commands/break.rb +24 -24
  20. data/lib/byebug/commands/catchpoint.rb +18 -10
  21. data/lib/byebug/commands/condition.rb +18 -17
  22. data/lib/byebug/commands/continue.rb +17 -9
  23. data/lib/byebug/commands/delete.rb +19 -13
  24. data/lib/byebug/commands/display.rb +19 -53
  25. data/lib/byebug/commands/edit.rb +7 -4
  26. data/lib/byebug/commands/enable_disable.rb +130 -0
  27. data/lib/byebug/commands/eval.rb +40 -22
  28. data/lib/byebug/commands/finish.rb +13 -4
  29. data/lib/byebug/commands/frame.rb +65 -45
  30. data/lib/byebug/commands/help.rb +17 -18
  31. data/lib/byebug/commands/history.rb +14 -8
  32. data/lib/byebug/commands/info.rb +160 -182
  33. data/lib/byebug/commands/interrupt.rb +4 -1
  34. data/lib/byebug/commands/irb.rb +30 -0
  35. data/lib/byebug/commands/kill.rb +7 -8
  36. data/lib/byebug/commands/list.rb +71 -66
  37. data/lib/byebug/commands/method.rb +14 -6
  38. data/lib/byebug/commands/pry.rb +35 -0
  39. data/lib/byebug/commands/quit.rb +9 -6
  40. data/lib/byebug/commands/reload.rb +5 -2
  41. data/lib/byebug/commands/restart.rb +13 -9
  42. data/lib/byebug/commands/save.rb +17 -17
  43. data/lib/byebug/commands/set.rb +16 -15
  44. data/lib/byebug/commands/show.rb +10 -11
  45. data/lib/byebug/commands/source.rb +11 -5
  46. data/lib/byebug/commands/stepping.rb +38 -24
  47. data/lib/byebug/commands/threads.rb +45 -31
  48. data/lib/byebug/commands/trace.rb +22 -9
  49. data/lib/byebug/commands/undisplay.rb +45 -0
  50. data/lib/byebug/commands/variables.rb +83 -27
  51. data/lib/byebug/context.rb +25 -22
  52. data/lib/byebug/core.rb +82 -0
  53. data/lib/byebug/helper.rb +37 -28
  54. data/lib/byebug/history.rb +8 -4
  55. data/lib/byebug/interface.rb +12 -17
  56. data/lib/byebug/interfaces/local_interface.rb +11 -8
  57. data/lib/byebug/interfaces/remote_interface.rb +11 -8
  58. data/lib/byebug/interfaces/script_interface.rb +9 -6
  59. data/lib/byebug/options.rb +46 -0
  60. data/lib/byebug/processor.rb +7 -1
  61. data/lib/byebug/processors/command_processor.rb +135 -125
  62. data/lib/byebug/processors/control_command_processor.rb +23 -23
  63. data/lib/byebug/remote.rb +17 -26
  64. data/lib/byebug/runner.rb +100 -0
  65. data/lib/byebug/setting.rb +33 -8
  66. data/lib/byebug/settings/autoeval.rb +5 -15
  67. data/lib/byebug/settings/autoirb.rb +4 -1
  68. data/lib/byebug/settings/autolist.rb +5 -2
  69. data/lib/byebug/settings/autoreload.rb +5 -2
  70. data/lib/byebug/settings/autosave.rb +6 -2
  71. data/lib/byebug/settings/basename.rb +7 -2
  72. data/lib/byebug/settings/callstyle.rb +4 -1
  73. data/lib/byebug/settings/forcestep.rb +6 -3
  74. data/lib/byebug/settings/fullpath.rb +5 -2
  75. data/lib/byebug/settings/histfile.rb +5 -3
  76. data/lib/byebug/settings/histsize.rb +5 -3
  77. data/lib/byebug/settings/linetrace.rb +4 -1
  78. data/lib/byebug/settings/listsize.rb +5 -1
  79. data/lib/byebug/settings/post_mortem.rb +21 -13
  80. data/lib/byebug/settings/stack_on_error.rb +6 -2
  81. data/lib/byebug/settings/testing.rb +6 -1
  82. data/lib/byebug/settings/tracing_plus.rb +5 -1
  83. data/lib/byebug/settings/verbose.rb +13 -2
  84. data/lib/byebug/settings/width.rb +4 -1
  85. data/lib/byebug/version.rb +1 -1
  86. data/test/{break_test.rb → commands/break_test.rb} +41 -53
  87. data/test/{condition_test.rb → commands/condition_test.rb} +14 -14
  88. data/test/{continue_test.rb → commands/continue_test.rb} +0 -0
  89. data/test/{delete_test.rb → commands/delete_test.rb} +2 -2
  90. data/test/commands/display_test.rb +37 -0
  91. data/test/{edit_test.rb → commands/edit_test.rb} +0 -0
  92. data/test/{eval_test.rb → commands/eval_test.rb} +1 -0
  93. data/test/{finish_test.rb → commands/finish_test.rb} +11 -1
  94. data/test/{frame_test.rb → commands/frame_test.rb} +12 -16
  95. data/test/{help_test.rb → commands/help_test.rb} +21 -4
  96. data/test/{history_test.rb → commands/history_test.rb} +0 -0
  97. data/test/{info_test.rb → commands/info_test.rb} +5 -55
  98. data/test/{interrupt_test.rb → commands/interrupt_test.rb} +0 -0
  99. data/test/commands/irb_test.rb +28 -0
  100. data/test/{kill_test.rb → commands/kill_test.rb} +1 -1
  101. data/test/{list_test.rb → commands/list_test.rb} +1 -1
  102. data/test/{method_test.rb → commands/method_test.rb} +0 -0
  103. data/test/{post_mortem_test.rb → commands/post_mortem_test.rb} +6 -10
  104. data/test/{pry_test.rb → commands/pry_test.rb} +4 -13
  105. data/test/{quit_test.rb → commands/quit_test.rb} +4 -4
  106. data/test/{reload_test.rb → commands/reload_test.rb} +0 -0
  107. data/test/{restart_test.rb → commands/restart_test.rb} +6 -0
  108. data/test/{save_test.rb → commands/save_test.rb} +2 -2
  109. data/test/{set_test.rb → commands/set_test.rb} +9 -2
  110. data/test/{show_test.rb → commands/show_test.rb} +1 -1
  111. data/test/{source_test.rb → commands/source_test.rb} +3 -3
  112. data/test/{stepping_test.rb → commands/stepping_test.rb} +44 -35
  113. data/test/{thread_test.rb → commands/thread_test.rb} +0 -0
  114. data/test/{trace_test.rb → commands/trace_test.rb} +0 -0
  115. data/test/{display_test.rb → commands/undisplay_test.rb} +7 -45
  116. data/test/{variables_test.rb → commands/variables_test.rb} +10 -1
  117. data/test/debugger_alias_test.rb +2 -2
  118. data/test/runner_test.rb +127 -0
  119. data/test/support/matchers.rb +27 -25
  120. data/test/support/test_interface.rb +9 -5
  121. data/test/support/utils.rb +96 -101
  122. data/test/test_helper.rb +32 -20
  123. metadata +93 -68
  124. data/lib/byebug/commands/enable.rb +0 -154
  125. data/lib/byebug/commands/repl.rb +0 -126
  126. data/test/irb_test.rb +0 -47
  127. data/test/support/breakpoint.rb +0 -13
@@ -1,4 +1,7 @@
1
1
  module Byebug
2
+ #
3
+ # Show information about every line that is executed.
4
+ #
2
5
  class TraceCommand < Command
3
6
  def regexp
4
7
  /^\s* tr(?:acevar)? (?: \s+ (\S+))? # (variable-name)?
@@ -7,20 +10,24 @@ module Byebug
7
10
  end
8
11
 
9
12
  def execute
10
- varname = @match[1]
11
- if global_variables.include?("$#{varname}".to_sym)
13
+ var = @match[1]
14
+ if global_variables.include?("$#{var}".to_sym)
12
15
  if @match[2] && @match[2] !~ /(:?no)?stop/
13
- errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[2]}\"\n"
16
+ errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[2]}\""
14
17
  else
15
- dbg_cmd = (@match[2] && @match[2] !~ /nostop/) ? 'byebug(1, false)' : ''
18
+ dbg_cmd = if @match[2] && @match[2] !~ /nostop/
19
+ 'byebug(1, false)'
20
+ else
21
+ ''
22
+ end
16
23
  end
17
- eval("trace_var(:\"\$#{varname}\") do |val|
18
- print \"traced global variable '#{varname}' has value '\#{val}'\"\n
24
+ eval("trace_var(:\"\$#{var}\") do |val|
25
+ puts \"traced global variable '#{var}' has value '\#{val}'\"
19
26
  #{dbg_cmd}
20
27
  end")
21
- print "Tracing global variable \"#{varname}\".\n"
28
+ puts "Tracing global variable \"#{var}\"."
22
29
  else
23
- errmsg "'#{varname}' is not a global variable.\n"
30
+ errmsg "'#{var}' is not a global variable."
24
31
  end
25
32
  end
26
33
 
@@ -30,7 +37,13 @@ module Byebug
30
37
  end
31
38
 
32
39
  def description
33
- %{tr[acevar] VARNAME [stop|nostop]\tset trace variable on VARNAME}
40
+ %(tr[acevar] <variable> [[no]stop]
41
+
42
+ Start tracing variable <variable>.
43
+
44
+ If "stop" is specified, execution will stop every time the variable
45
+ changes its value. If nothing or "nostop" is specified, execution
46
+ won't stop, changes will just be logged in byebug's output.)
34
47
  end
35
48
  end
36
49
  end
@@ -0,0 +1,45 @@
1
+ module Byebug
2
+ #
3
+ # Remove expressions from display list.
4
+ #
5
+ class UndisplayCommand < Command
6
+ self.allow_in_post_mortem = false
7
+
8
+ def regexp
9
+ /^\s* undisp(?:lay)? (?:\s+(\S+))? \s*$/x
10
+ end
11
+
12
+ def execute
13
+ if @match[1]
14
+ pos, err = get_int(@match[1], 'Undisplay')
15
+ return errmsg(err) unless pos
16
+
17
+ unless @state.display[pos - 1]
18
+ return errmsg("Display expression #{pos} is not defined.")
19
+ end
20
+
21
+ @state.display[pos - 1][0] = nil
22
+ else
23
+ return unless confirm('Clear all expressions? (y/n) ')
24
+
25
+ @state.display.each { |d| d[0] = false }
26
+ end
27
+ end
28
+
29
+ class << self
30
+ def names
31
+ %w(undisplay)
32
+ end
33
+
34
+ def description
35
+ %(undisp[lay][ nnn]
36
+
37
+ Cancel some expressions to be displayed when program stops. Arguments
38
+ are the code numbers of the expressions to stop displaying. No
39
+ argument means cancel all automatic-display expressions. "delete
40
+ display" has the same effect as this command. Do "info display" to see
41
+ the current list of code numbers.)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,20 +1,23 @@
1
1
  module Byebug
2
+ #
3
+ # Utilities for the var command.
4
+ #
2
5
  module VarFunctions
3
6
  def var_list(ary, b = get_binding)
4
7
  ary.sort!
5
- for v in ary
8
+ ary.each do |v|
6
9
  begin
7
10
  s = bb_eval(v.to_s, b).inspect
8
11
  rescue
9
12
  begin
10
13
  s = bb_eval(v.to_s, b).to_s
11
14
  rescue
12
- s = "*Error in evaluation*"
15
+ s = '*Error in evaluation*'
13
16
  end
14
17
  end
15
18
  s = "#{v} = #{s}"
16
- s[Setting[:width]-3..-1] = "..." if s.size > Setting[:width]
17
- print "#{s}\n"
19
+ s[Setting[:width] - 3..-1] = '...' if s.size > Setting[:width]
20
+ puts s
18
21
  end
19
22
  end
20
23
 
@@ -24,20 +27,65 @@ module Byebug
24
27
  end
25
28
 
26
29
  def var_global
27
- var_list(global_variables.reject { |v| [:$=, :$KCODE, :$-K].include?(v) })
30
+ globals = global_variables.reject do |v|
31
+ [:$IGNORECASE, :$=, :$KCODE, :$-K].include?(v)
32
+ end
33
+
34
+ var_list(globals)
35
+ end
36
+
37
+ def var_instance(where)
38
+ obj = bb_eval(where)
39
+ var_list(obj.instance_variables, obj.instance_eval { binding })
40
+ end
41
+
42
+ def var_local
43
+ _self = @state.context.frame_self(@state.frame_pos)
44
+ locals = @state.context.frame_locals
45
+ locals.keys.sort.each do |name|
46
+ puts format(' %s => %p', name, locals[name])
47
+ end
28
48
  end
29
49
  end
30
50
 
51
+ #
52
+ # Show all variables and its values.
53
+ #
54
+ class VarAllCommand < Command
55
+ def regexp
56
+ /^\s* v(?:ar)? \s+ a(?:ll)? \s*$/x
57
+ end
58
+
59
+ def execute
60
+ var_class_self
61
+ var_global
62
+ var_instance('self')
63
+ var_local
64
+ end
65
+
66
+ class << self
67
+ def names
68
+ %w(var)
69
+ end
70
+
71
+ def description
72
+ %(v[ar] a[ll]
73
+
74
+ Show local, global and instance & class variables of self.)
75
+ end
76
+ end
77
+ end
78
+
79
+ #
80
+ # Show class variables and its values.
81
+ #
31
82
  class VarClassCommand < Command
32
83
  def regexp
33
84
  /^\s* v(?:ar)? \s+ cl(?:ass)? \s*/x
34
85
  end
35
86
 
36
87
  def execute
37
- unless @state.context
38
- errmsg "can't get class variables here.\n"
39
- return
40
- end
88
+ return errmsg "can't get class variables here.\n" unless @state.context
41
89
  var_class_self
42
90
  end
43
91
 
@@ -47,11 +95,14 @@ module Byebug
47
95
  end
48
96
 
49
97
  def description
50
- %{v[ar] cl[ass] \t\t\tshow class variables of self}
98
+ %(v[ar] cl[ass] Show class variables of self.)
51
99
  end
52
100
  end
53
101
  end
54
102
 
103
+ #
104
+ # Show constants and its values.
105
+ #
55
106
  class VarConstantCommand < Command
56
107
  def regexp
57
108
  /^\s* v(?:ar)? \s+ co(?:nst(?:ant)?)? \s+/x
@@ -59,16 +110,15 @@ module Byebug
59
110
 
60
111
  def execute
61
112
  obj = bb_eval(@match.post_match)
62
- if obj.kind_of? Module
113
+ if obj.is_a? Module
63
114
  constants = bb_eval("#{@match.post_match}.constants")
64
115
  constants.sort!
65
- for c in constants
66
- next if c =~ /SCRIPT/
67
- value = obj.const_get(c) rescue "ERROR: #{$!}"
68
- print " %s => %p\n", c, value
116
+ constants.each do |c|
117
+ value = obj.const_get(c)
118
+ puts format(' %s => %p', c, value)
69
119
  end
70
120
  else
71
- print "Should be Class/Module: #{@match.post_match}\n"
121
+ puts "Should be Class/Module: #{@match.post_match}"
72
122
  end
73
123
  end
74
124
 
@@ -78,11 +128,14 @@ module Byebug
78
128
  end
79
129
 
80
130
  def description
81
- %{v[ar] co[nst] <object>\t\tshow constants of object}
131
+ %(v[ar] co[nst] <object> Show constants of <object>.)
82
132
  end
83
133
  end
84
134
  end
85
135
 
136
+ #
137
+ # Show global variables and its values.
138
+ #
86
139
  class VarGlobalCommand < Command
87
140
  def regexp
88
141
  /^\s* v(?:ar)? \s+ g(?:lobal)? \s*$/x
@@ -98,19 +151,21 @@ module Byebug
98
151
  end
99
152
 
100
153
  def description
101
- %{v[ar] g[lobal]\t\t\tshow global variables}
154
+ %(v[ar] g[lobal] Show global variables.)
102
155
  end
103
156
  end
104
157
  end
105
158
 
159
+ #
160
+ # Show instance variables and its values.
161
+ #
106
162
  class VarInstanceCommand < Command
107
163
  def regexp
108
164
  /^\s* v(?:ar)? \s+ ins(?:tance)? \s*/x
109
165
  end
110
166
 
111
167
  def execute
112
- obj = bb_eval(@match.post_match.empty? ? 'self' : @match.post_match)
113
- var_list(obj.instance_variables, obj.instance_eval { binding() })
168
+ var_instance(@match.post_match.empty? ? 'self' : @match.post_match)
114
169
  end
115
170
 
116
171
  class << self
@@ -119,22 +174,23 @@ module Byebug
119
174
  end
120
175
 
121
176
  def description
122
- %{v[ar] i[nstance] <object>\tshow instance variables of object}
177
+ %(v[ar] i[nstance] <object>
178
+
179
+ Show instance variables of <object>.)
123
180
  end
124
181
  end
125
182
  end
126
183
 
184
+ #
185
+ # Show local variables and its values.
186
+ #
127
187
  class VarLocalCommand < Command
128
188
  def regexp
129
189
  /^\s* v(?:ar)? \s+ l(?:ocal)? \s*$/x
130
190
  end
131
191
 
132
192
  def execute
133
- _self = @state.context.frame_self(@state.frame_pos)
134
- locals = @state.context.frame_locals
135
- locals.keys.sort.each do |name|
136
- print " %s => %p\n", name, locals[name]
137
- end
193
+ var_local
138
194
  end
139
195
 
140
196
  class << self
@@ -143,7 +199,7 @@ module Byebug
143
199
  end
144
200
 
145
201
  def description
146
- %{v[ar] l[ocal]\t\t\tshow local variables}
202
+ %(v[ar] l[ocal] Sow local variables.)
147
203
  end
148
204
  end
149
205
  end
@@ -1,19 +1,22 @@
1
1
  module Byebug
2
-
2
+ #
3
+ # Mantains context information for the debugger and it's the main
4
+ # communication point between the library and the C-extension through the
5
+ # at_breakpoint, at_catchpoint, at_tracing, at_line and at_return callbacks
6
+ #
3
7
  class Context
4
-
5
8
  class << self
6
9
  def stack_size(byebug_frames = false)
7
- if backtrace = Thread.current.backtrace_locations(0)
8
- unless byebug_frames
9
- backtrace = backtrace.drop_while { |l| !ignored(l.path) }
10
- .drop_while { |l| ignored(l.path) }
11
- .take_while { |l| !ignored(l.path) }
12
- end
13
- backtrace.size
14
- else
15
- 0
10
+ backtrace = Thread.current.backtrace_locations(0)
11
+ return 0 unless backtrace
12
+
13
+ unless byebug_frames
14
+ backtrace = backtrace.drop_while { |l| !ignored(l.path) }
15
+ .drop_while { |l| ignored(l.path) }
16
+ .take_while { |l| !ignored(l.path) }
16
17
  end
18
+
19
+ backtrace.size
17
20
  end
18
21
 
19
22
  def ignored(path)
@@ -23,32 +26,32 @@ module Byebug
23
26
  end
24
27
 
25
28
  def interrupt
26
- self.step_into 1
29
+ step_into 1
27
30
  end
28
31
 
29
- def frame_locals frame_no = 0
32
+ def frame_locals(frame_no = 0)
30
33
  bind = frame_binding frame_no
31
- eval "local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}", bind
34
+ eval 'local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}', bind
32
35
  end
33
36
 
34
- def c_frame_args frame_no
37
+ def c_frame_args(frame_no)
35
38
  myself = frame_self frame_no
36
39
  return [] unless myself.to_s != 'main'
37
40
  myself.send(:method, frame_method(frame_no)).parameters
38
41
  end
39
42
 
40
- def ruby_frame_args bind
43
+ def ruby_frame_args(bind)
41
44
  return [] unless eval '__method__', bind
42
45
  begin
43
- eval "self.method(__method__).parameters", bind
46
+ eval 'self.method(__method__).parameters', bind
44
47
  rescue NameError => e
45
- print "WARNING: Got exception #{e.class}: \"#{e.message}\" " \
46
- "while retreving parameters from frame\n"
48
+ puts "WARNING: Got exception #{e.class}: \"#{e.message}\" " \
49
+ 'while retreving parameters from frame'
47
50
  return []
48
51
  end
49
52
  end
50
53
 
51
- def frame_args frame_no = 0
54
+ def frame_args(frame_no = 0)
52
55
  bind = frame_binding frame_no
53
56
  if bind.nil?
54
57
  c_frame_args frame_no
@@ -58,7 +61,7 @@ module Byebug
58
61
  end
59
62
 
60
63
  def handler
61
- Byebug.handler or raise 'No interface loaded'
64
+ Byebug.handler || fail('No interface loaded')
62
65
  end
63
66
 
64
67
  def at_breakpoint(brkpnt)
@@ -74,7 +77,7 @@ module Byebug
74
77
  end
75
78
 
76
79
  def at_line(file, line)
77
- handler.at_line(self, file, line)
80
+ handler.at_line(self, file, line) unless IGNORED_FILES.include?(file)
78
81
  end
79
82
 
80
83
  def at_return(file, line)
@@ -0,0 +1,82 @@
1
+ require 'byebug/byebug'
2
+ require 'byebug/version'
3
+ require 'byebug/context'
4
+ require 'byebug/breakpoint'
5
+ require 'byebug/interface'
6
+ require 'byebug/processor'
7
+ require 'byebug/setting'
8
+ require 'byebug/remote'
9
+
10
+ require 'stringio'
11
+ require 'tracer'
12
+ require 'linecache19'
13
+
14
+ module Byebug
15
+ # List of files byebug will ignore while debugging
16
+ IGNORED_FILES = Dir.glob(File.expand_path('../**/*.rb', __FILE__))
17
+
18
+ # Configuration file used for startup commands. Default value is .byebugrc
19
+ INITFILE = '.byebugrc' unless defined?(INITFILE)
20
+
21
+ class << self
22
+ attr_accessor :handler
23
+ end
24
+
25
+ Byebug.handler = CommandProcessor.new
26
+
27
+ def self.source_reload
28
+ hsh = 'SCRIPT_LINES__'
29
+ Object.send(:remove_const, hsh) if Object.const_defined?(hsh)
30
+ Object.const_set(hsh, {})
31
+ end
32
+
33
+ #
34
+ # Byebug's interface is its handler's interface
35
+ #
36
+ def self.interface=(value)
37
+ handler.interface = value
38
+ end
39
+
40
+ #
41
+ # Byebug's prints according to its handler's interface
42
+ #
43
+ def self.puts(message)
44
+ handler.interface.puts(message)
45
+ end
46
+
47
+ #
48
+ # Runs normal byebug initialization scripts.
49
+ #
50
+ # Reads and executes the commands from init file (if any) in the current
51
+ # working directory. This is only done if the current directory is
52
+ # different from your home directory. Thus, you can have more than one init
53
+ # file, one generic in your home directory, and another, specific to the
54
+ # program you are debugging, in the directory where you invoke byebug.
55
+ #
56
+ def self.run_init_script(out = handler.interface)
57
+ cwd_script = File.expand_path(File.join('.', INITFILE))
58
+ run_script(cwd_script, out, true) if File.exist?(cwd_script)
59
+
60
+ home_script = File.expand_path(File.join(ENV['HOME'].to_s, INITFILE))
61
+ if File.exist?(home_script) && cwd_script != home_script
62
+ run_script(home_script, out, true)
63
+ end
64
+ end
65
+
66
+ #
67
+ # Runs a script file
68
+ #
69
+ def self.run_script(file, out = handler.interface, verbose = false)
70
+ interface = ScriptInterface.new(File.expand_path(file), out)
71
+ processor = ControlCommandProcessor.new(interface)
72
+ processor.process_commands(verbose)
73
+ end
74
+ end
75
+
76
+ #
77
+ # Extends the extension class to be able to pass information about the
78
+ # debugging environment from the c-extension to the user.
79
+ #
80
+ class Exception
81
+ attr_reader :__bb_file, :__bb_line, :__bb_binding, :__bb_context
82
+ end