debugger 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. data/AUTHORS +10 -0
  2. data/CHANGES +334 -0
  3. data/ChangeLog +5655 -0
  4. data/INSTALL.SVN +154 -0
  5. data/LICENSE +23 -0
  6. data/Makefile.am +14 -0
  7. data/OLD_README +122 -0
  8. data/README.md +10 -0
  9. data/Rakefile +266 -0
  10. data/autogen.sh +4 -0
  11. data/bin/rdebug +398 -0
  12. data/cli/ruby-debug.rb +173 -0
  13. data/cli/ruby-debug/command.rb +228 -0
  14. data/cli/ruby-debug/commands/breakpoints.rb +153 -0
  15. data/cli/ruby-debug/commands/catchpoint.rb +55 -0
  16. data/cli/ruby-debug/commands/condition.rb +49 -0
  17. data/cli/ruby-debug/commands/continue.rb +38 -0
  18. data/cli/ruby-debug/commands/control.rb +107 -0
  19. data/cli/ruby-debug/commands/display.rb +120 -0
  20. data/cli/ruby-debug/commands/edit.rb +48 -0
  21. data/cli/ruby-debug/commands/enable.rb +202 -0
  22. data/cli/ruby-debug/commands/eval.rb +176 -0
  23. data/cli/ruby-debug/commands/finish.rb +42 -0
  24. data/cli/ruby-debug/commands/frame.rb +301 -0
  25. data/cli/ruby-debug/commands/help.rb +56 -0
  26. data/cli/ruby-debug/commands/info.rb +467 -0
  27. data/cli/ruby-debug/commands/irb.rb +123 -0
  28. data/cli/ruby-debug/commands/jump.rb +66 -0
  29. data/cli/ruby-debug/commands/kill.rb +51 -0
  30. data/cli/ruby-debug/commands/list.rb +94 -0
  31. data/cli/ruby-debug/commands/method.rb +84 -0
  32. data/cli/ruby-debug/commands/quit.rb +39 -0
  33. data/cli/ruby-debug/commands/reload.rb +40 -0
  34. data/cli/ruby-debug/commands/save.rb +90 -0
  35. data/cli/ruby-debug/commands/set.rb +221 -0
  36. data/cli/ruby-debug/commands/show.rb +247 -0
  37. data/cli/ruby-debug/commands/skip.rb +35 -0
  38. data/cli/ruby-debug/commands/source.rb +36 -0
  39. data/cli/ruby-debug/commands/stepping.rb +81 -0
  40. data/cli/ruby-debug/commands/threads.rb +189 -0
  41. data/cli/ruby-debug/commands/tmate.rb +36 -0
  42. data/cli/ruby-debug/commands/trace.rb +57 -0
  43. data/cli/ruby-debug/commands/variables.rb +199 -0
  44. data/cli/ruby-debug/debugger.rb +5 -0
  45. data/cli/ruby-debug/helper.rb +69 -0
  46. data/cli/ruby-debug/interface.rb +232 -0
  47. data/cli/ruby-debug/processor.rb +474 -0
  48. data/configure.ac +12 -0
  49. data/debugger.gemspec +24 -0
  50. data/doc/.cvsignore +42 -0
  51. data/doc/Makefile.am +63 -0
  52. data/doc/emacs-notes.txt +38 -0
  53. data/doc/hanoi.rb +35 -0
  54. data/doc/primes.rb +28 -0
  55. data/doc/rdebug-emacs.texi +1030 -0
  56. data/doc/rdebug.1 +241 -0
  57. data/doc/ruby-debug.texi +3791 -0
  58. data/doc/test-tri2.rb +18 -0
  59. data/doc/tri3.rb +8 -0
  60. data/doc/triangle.rb +12 -0
  61. data/emacs/Makefile.am +130 -0
  62. data/emacs/rdebug-annotate.el +385 -0
  63. data/emacs/rdebug-breaks.el +407 -0
  64. data/emacs/rdebug-cmd.el +92 -0
  65. data/emacs/rdebug-core.el +502 -0
  66. data/emacs/rdebug-dbg.el +62 -0
  67. data/emacs/rdebug-error.el +79 -0
  68. data/emacs/rdebug-fns.el +111 -0
  69. data/emacs/rdebug-frames.el +230 -0
  70. data/emacs/rdebug-gud.el +242 -0
  71. data/emacs/rdebug-help.el +104 -0
  72. data/emacs/rdebug-info.el +83 -0
  73. data/emacs/rdebug-layouts.el +180 -0
  74. data/emacs/rdebug-locring.el +118 -0
  75. data/emacs/rdebug-output.el +106 -0
  76. data/emacs/rdebug-regexp.el +118 -0
  77. data/emacs/rdebug-secondary.el +260 -0
  78. data/emacs/rdebug-shortkey.el +175 -0
  79. data/emacs/rdebug-source.el +568 -0
  80. data/emacs/rdebug-track.el +392 -0
  81. data/emacs/rdebug-varbuf.el +150 -0
  82. data/emacs/rdebug-vars.el +125 -0
  83. data/emacs/rdebug-watch.el +132 -0
  84. data/emacs/rdebug.el +326 -0
  85. data/emacs/test/elk-test.el +242 -0
  86. data/emacs/test/test-annotate.el +103 -0
  87. data/emacs/test/test-cmd.el +116 -0
  88. data/emacs/test/test-core.el +104 -0
  89. data/emacs/test/test-fns.el +65 -0
  90. data/emacs/test/test-frames.el +62 -0
  91. data/emacs/test/test-gud.el +35 -0
  92. data/emacs/test/test-indent.el +58 -0
  93. data/emacs/test/test-regexp.el +144 -0
  94. data/emacs/test/test-shortkey.el +61 -0
  95. data/ext/ruby_debug/breakpoint.c +586 -0
  96. data/ext/ruby_debug/extconf.rb +49 -0
  97. data/ext/ruby_debug/ruby_debug.c +2624 -0
  98. data/ext/ruby_debug/ruby_debug.h +148 -0
  99. data/lib/ChangeLog +1065 -0
  100. data/lib/debugger.rb +7 -0
  101. data/lib/debugger/version.rb +3 -0
  102. data/lib/ruby-debug-base.rb +304 -0
  103. data/rdbg.rb +33 -0
  104. data/runner.sh +7 -0
  105. data/svn2cl_usermap +3 -0
  106. data/test/.cvsignore +1 -0
  107. data/test/base/base.rb +74 -0
  108. data/test/base/binding.rb +31 -0
  109. data/test/base/catchpoint.rb +26 -0
  110. data/test/base/load.rb +40 -0
  111. data/test/bp_loop_issue.rb +3 -0
  112. data/test/classes.rb +11 -0
  113. data/test/cli/commands/catchpoint_test.rb +36 -0
  114. data/test/cli/commands/unit/regexp.rb +42 -0
  115. data/test/config.yaml +8 -0
  116. data/test/data/annotate.cmd +29 -0
  117. data/test/data/annotate.right +139 -0
  118. data/test/data/break_bad.cmd +18 -0
  119. data/test/data/break_bad.right +28 -0
  120. data/test/data/break_loop_bug.cmd +5 -0
  121. data/test/data/break_loop_bug.right +15 -0
  122. data/test/data/breakpoints.cmd +38 -0
  123. data/test/data/breakpoints.right +98 -0
  124. data/test/data/catch.cmd +20 -0
  125. data/test/data/catch.right +49 -0
  126. data/test/data/catch2.cmd +19 -0
  127. data/test/data/catch2.right +65 -0
  128. data/test/data/catch3.cmd +11 -0
  129. data/test/data/catch3.right +37 -0
  130. data/test/data/condition.cmd +28 -0
  131. data/test/data/condition.right +65 -0
  132. data/test/data/ctrl.cmd +23 -0
  133. data/test/data/ctrl.right +70 -0
  134. data/test/data/display.cmd +24 -0
  135. data/test/data/display.right +44 -0
  136. data/test/data/dollar-0.right +2 -0
  137. data/test/data/dollar-0a.right +2 -0
  138. data/test/data/dollar-0b.right +2 -0
  139. data/test/data/edit.cmd +12 -0
  140. data/test/data/edit.right +19 -0
  141. data/test/data/emacs_basic.cmd +43 -0
  142. data/test/data/emacs_basic.right +106 -0
  143. data/test/data/enable.cmd +20 -0
  144. data/test/data/enable.right +36 -0
  145. data/test/data/finish.cmd +16 -0
  146. data/test/data/finish.right +31 -0
  147. data/test/data/frame.cmd +26 -0
  148. data/test/data/frame.right +55 -0
  149. data/test/data/help.cmd +20 -0
  150. data/test/data/help.right +21 -0
  151. data/test/data/history.right +7 -0
  152. data/test/data/info-thread.cmd +13 -0
  153. data/test/data/info-thread.right +37 -0
  154. data/test/data/info-var-bug2.cmd +5 -0
  155. data/test/data/info-var-bug2.right +10 -0
  156. data/test/data/info-var.cmd +23 -0
  157. data/test/data/info-var.right +52 -0
  158. data/test/data/info.cmd +21 -0
  159. data/test/data/info.right +65 -0
  160. data/test/data/jump.cmd +16 -0
  161. data/test/data/jump.right +56 -0
  162. data/test/data/jump2.cmd +16 -0
  163. data/test/data/jump2.right +44 -0
  164. data/test/data/linetrace.cmd +6 -0
  165. data/test/data/linetrace.right +23 -0
  166. data/test/data/list.cmd +19 -0
  167. data/test/data/list.right +127 -0
  168. data/test/data/method.cmd +10 -0
  169. data/test/data/method.right +21 -0
  170. data/test/data/methodsig.cmd +10 -0
  171. data/test/data/methodsig.right +20 -0
  172. data/test/data/next.cmd +22 -0
  173. data/test/data/next.right +61 -0
  174. data/test/data/noquit.right +1 -0
  175. data/test/data/output.cmd +6 -0
  176. data/test/data/output.right +31 -0
  177. data/test/data/pm-bug.cmd +7 -0
  178. data/test/data/pm-bug.right +12 -0
  179. data/test/data/post-mortem-next.cmd +8 -0
  180. data/test/data/post-mortem-next.right +14 -0
  181. data/test/data/post-mortem-osx.right +31 -0
  182. data/test/data/post-mortem.cmd +13 -0
  183. data/test/data/post-mortem.right +32 -0
  184. data/test/data/quit.cmd +6 -0
  185. data/test/data/quit.right +0 -0
  186. data/test/data/raise.cmd +11 -0
  187. data/test/data/raise.right +23 -0
  188. data/test/data/save.cmd +34 -0
  189. data/test/data/save.right +59 -0
  190. data/test/data/scope-var.cmd +42 -0
  191. data/test/data/scope-var.right +587 -0
  192. data/test/data/setshow.cmd +56 -0
  193. data/test/data/setshow.right +98 -0
  194. data/test/data/source.cmd +5 -0
  195. data/test/data/source.right +15 -0
  196. data/test/data/stepping.cmd +21 -0
  197. data/test/data/stepping.right +50 -0
  198. data/test/data/test-init-cygwin.right +7 -0
  199. data/test/data/test-init-osx.right +4 -0
  200. data/test/data/test-init.right +5 -0
  201. data/test/data/trace.right +14 -0
  202. data/test/dollar-0.rb +5 -0
  203. data/test/gcd-dbg-nox.rb +31 -0
  204. data/test/gcd-dbg.rb +30 -0
  205. data/test/gcd.rb +18 -0
  206. data/test/helper.rb +144 -0
  207. data/test/info-var-bug.rb +47 -0
  208. data/test/info-var-bug2.rb +2 -0
  209. data/test/jump.rb +14 -0
  210. data/test/jump2.rb +27 -0
  211. data/test/next.rb +18 -0
  212. data/test/null.rb +1 -0
  213. data/test/output.rb +2 -0
  214. data/test/pm-base.rb +22 -0
  215. data/test/pm-bug.rb +3 -0
  216. data/test/pm-catch.rb +12 -0
  217. data/test/pm-catch2.rb +27 -0
  218. data/test/pm-catch3.rb +47 -0
  219. data/test/pm.rb +11 -0
  220. data/test/raise.rb +3 -0
  221. data/test/rdebug-save.1 +7 -0
  222. data/test/runall +12 -0
  223. data/test/scope-var.rb +29 -0
  224. data/test/tdebug.rb +248 -0
  225. data/test/test-annotate.rb +25 -0
  226. data/test/test-break-bad.rb +37 -0
  227. data/test/test-breakpoints.rb +25 -0
  228. data/test/test-catch.rb +25 -0
  229. data/test/test-catch2.rb +25 -0
  230. data/test/test-catch3.rb +25 -0
  231. data/test/test-condition.rb +25 -0
  232. data/test/test-ctrl.rb +55 -0
  233. data/test/test-display.rb +26 -0
  234. data/test/test-dollar-0.rb +40 -0
  235. data/test/test-edit.rb +26 -0
  236. data/test/test-emacs-basic.rb +26 -0
  237. data/test/test-enable.rb +25 -0
  238. data/test/test-finish.rb +34 -0
  239. data/test/test-frame.rb +34 -0
  240. data/test/test-help.rb +60 -0
  241. data/test/test-hist.rb +68 -0
  242. data/test/test-info-thread.rb +32 -0
  243. data/test/test-info-var.rb +47 -0
  244. data/test/test-info.rb +26 -0
  245. data/test/test-init.rb +44 -0
  246. data/test/test-jump.rb +35 -0
  247. data/test/test-list.rb +25 -0
  248. data/test/test-method.rb +34 -0
  249. data/test/test-next.rb +25 -0
  250. data/test/test-output.rb +26 -0
  251. data/test/test-quit.rb +30 -0
  252. data/test/test-raise.rb +25 -0
  253. data/test/test-save.rb +31 -0
  254. data/test/test-scope-var.rb +25 -0
  255. data/test/test-setshow.rb +25 -0
  256. data/test/test-source.rb +25 -0
  257. data/test/test-stepping.rb +26 -0
  258. data/test/test-trace.rb +47 -0
  259. data/test/thread1.rb +26 -0
  260. data/test/trunc-call.rb +31 -0
  261. metadata +364 -0
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ # Things to do after doing a clean SVN update to add the proper files.
3
+ ln -vfs CHANGES NEWS
4
+ autoreconf -i -s
@@ -0,0 +1,398 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #=== Summary
4
+ #
5
+ #A command-line front-end to the Ruby debugger, <tt>ruby-debug</tt>, the
6
+ #Fast Ruby Debugger.
7
+ #
8
+ #Command invocation:
9
+ #
10
+ # rdebug [options] [--] [script-options] ruby-script-to-debug
11
+ # rdebug [options] [script-options] [--client]
12
+ # rdebug [--version | --help]
13
+ #
14
+ #=== Options
15
+ #
16
+ #<tt>-A | --annotate</tt> <i>level</i>::
17
+ # Set gdb-style annotation to <i>level</i>, a number. Additional
18
+ # information is output automatically when program state is
19
+ # changed. This can be used by front-ends such as GNU Emacs to post
20
+ # this updated information without having to poll for it.
21
+ #
22
+ #<tt>--client</tt>::
23
+ # Connect to a remote debugger. Used with another rdebug invocation
24
+ # using <tt>--server</tt>. See also <tt>--host</tt> and
25
+ # <tt>--cport</tt> options
26
+ #
27
+ #<tt>--cport=</tt><i>port</i>::
28
+ # Use port <i>port</i> for access to debugger control.
29
+ #
30
+ #<tt>-d | --debug</tt>::
31
+ # Set $DEBUG true.
32
+ #
33
+ #<tt>--emacs</tt>::
34
+ # Activates full GNU Emacs mode. Is the equivalent of setting the
35
+ # options <tt>--emacs-basic --annotate=3 --no-stop --no-control
36
+ # --post-mortem</tt>.
37
+ #
38
+ #<tt>--emacs-basic</tt>::
39
+ # Activates GNU Emacs mode. Debugger prompts are prefaced with two
40
+ # octal 032 characters.
41
+ #
42
+ #<tt>-h | --host=</tt><i>host</i>::
43
+ # Use host name <i>host</i> for remote debugging.
44
+ #
45
+ #<tt>-I | --include</tt> <i>path</i>
46
+ # Add <i>path</i> to <tt>$LOAD_PATH</tt>
47
+ #
48
+ #<tt>-m | --post-mortem</tt>::
49
+ # Activate post-mortem mode.
50
+ #
51
+ #<tt>--no-control</tt>::
52
+ # Do not automatically start control thread.
53
+ #
54
+ #<tt>--no-stop</tt>::
55
+ # Do not stop when script is loaded.
56
+ #
57
+ #<tt>-p | --port=PORT</tt>::
58
+ # Host name used for remote debugging.
59
+ #
60
+ #<tt>-r | --require</tt><i>script</i>::
61
+ # Require the library, before executing your script.
62
+ #
63
+ #<tt>--script</tt> <i>file</i>::
64
+ # Run debugger script file <i>file</i>
65
+ #
66
+ #<tt>-x | --trace</tt>::
67
+ # Show lines before executing them.
68
+ #
69
+ #<tt>--no-quit</tt>::
70
+ # Do not quit when script terminates. Instead rerun the
71
+ # program.
72
+ #
73
+ #<tt>--version</tt>::
74
+ # Show the version number and exit.
75
+ #
76
+ #<tt>--verbose</tt>::
77
+ # Turn on verbose mode.
78
+ #
79
+ #<tt>--v</tt>::
80
+ # Print the version number, then turn on verbose mode if
81
+ # a script name is given. If no script name is given
82
+ # just exit after printing the version number.
83
+ #
84
+ #<tt>--nx</tt>::
85
+ # Don’t execute commands found in any initialization
86
+ # files, e.g. <tt>.rdebugrc</tt>.
87
+ #
88
+ #<tt>--keep-frame-binding</tt>::
89
+ # Keep frame bindings.
90
+ #
91
+ #<tt>--script=</tt><i>file</i>::
92
+ # Name of the script file to run
93
+ #
94
+ #<tt>-s | --server</tt>::
95
+ # Listen for remote connections. Another rdebug session
96
+ # accesses using the <tt>--client</tt> option. See also the
97
+ # <tt>--host</tt>, <tt>--port</tt> and <tt>--cport</tt> options
98
+ #
99
+ #<tt>-w | --wait</tt>::
100
+ # Wait for a client connection; implies <tt>-s</tt> option.
101
+ #
102
+ #<tt>--help</tt>::
103
+ # Show invocation help and exit.
104
+
105
+ require 'rubygems'
106
+ require 'optparse'
107
+ require 'ostruct'
108
+ require_relative '../cli/ruby-debug'
109
+
110
+ def debug_program(options)
111
+ # Make sure Ruby script syntax checks okay.
112
+ # Otherwise we get a load message that looks like rdebug has
113
+ # a problem.
114
+ output = `ruby -c "#{Debugger::PROG_SCRIPT}" 2>&1`
115
+ if $?.exitstatus != 0 and RUBY_PLATFORM !~ /mswin/
116
+ puts output
117
+ exit $?.exitstatus
118
+ end
119
+ print "\032\032starting\n" if Debugger.annotate and Debugger.annotate > 2
120
+
121
+ # Record where we are we can know if the call stack has been
122
+ # truncated or not.
123
+ Debugger.start_sentinal=caller(0)[1]
124
+
125
+ bt = Debugger.debug_load(Debugger::PROG_SCRIPT, options.stop, false)
126
+ if bt
127
+ print bt.backtrace.map{|l| "\t#{l}"}.join("\n"), "\n"
128
+ print "Uncaught exception: #{bt}\n"
129
+ end
130
+ end
131
+
132
+ # Do a shell-like path lookup for prog_script and return the results.
133
+ # If we can't find anything return prog_script.
134
+ def whence_file(prog_script)
135
+ if prog_script.index(File::SEPARATOR)
136
+ # Don't search since this name has path separator components
137
+ return prog_script
138
+ end
139
+ for dirname in ENV['PATH'].split(File::PATH_SEPARATOR) do
140
+ prog_script_try = File.join(dirname, prog_script)
141
+ return prog_script_try if File.exist?(prog_script_try)
142
+ end
143
+ # Failure
144
+ return prog_script
145
+ end
146
+
147
+ options = OpenStruct.new(
148
+ 'annotate' => Debugger.annotate,
149
+ 'client' => false,
150
+ 'control' => true,
151
+ 'cport' => Debugger::PORT + 1,
152
+ 'host' => nil,
153
+ 'quit' => true,
154
+ 'no_rewrite_program' => false,
155
+ 'stop' => true,
156
+ 'nx' => false,
157
+ 'port' => Debugger::PORT,
158
+ 'restart_script' => nil,
159
+ 'script' => nil,
160
+ 'server' => false,
161
+ 'tracing' => false,
162
+ 'verbose_long' => false,
163
+ 'wait' => false
164
+ )
165
+
166
+ def process_options(options)
167
+ program = File.basename($0)
168
+ opts = OptionParser.new do |opts|
169
+ opts.banner = <<EOB
170
+ #{program} #{Debugger::VERSION}
171
+ Usage: #{program} [options] <script.rb> -- <script.rb parameters>
172
+ EOB
173
+ opts.separator ""
174
+ opts.separator "Options:"
175
+ opts.on("-A", "--annotate LEVEL", Integer, "Set annotation level") do
176
+ |annotate|
177
+ Debugger.annotate = annotate
178
+ end
179
+ opts.on("-c", "--client", "Connect to remote debugger") do
180
+ options.client = true
181
+ end
182
+ opts.on("--cport PORT", Integer, "Port used for control commands") do
183
+ |cport|
184
+ options.cport = cport
185
+ end
186
+ opts.on("-d", "--debug", "Set $DEBUG=true") {$DEBUG = true}
187
+ opts.on("--emacs LEVEL", Integer,
188
+ "Activates full Emacs support at annotation level LEVEL") do
189
+ |level|
190
+ Debugger.annotate = level.to_i
191
+ ENV['EMACS'] = '1'
192
+ ENV['COLUMNS'] = '120' if ENV['COLUMNS'].to_i < 120
193
+ options.control = false
194
+ options.quit = false
195
+ end
196
+ opts.on('--emacs-basic', 'Activates basic Emacs mode') do
197
+ ENV['EMACS'] = '1'
198
+ end
199
+ opts.on('-h', '--host HOST', 'Host name used for remote debugging') do
200
+ |host|
201
+ options.host = host
202
+ end
203
+ opts.on('-I', '--include PATH', String, 'Add PATH to $LOAD_PATH') do |path|
204
+ $LOAD_PATH.unshift(path)
205
+ end
206
+ opts.on('--no-control', 'Do not automatically start control thread') do
207
+ options.control = false
208
+ end
209
+ opts.on('--no-quit', 'Do not quit when script finishes') do
210
+ options.quit = false
211
+ end
212
+ opts.on('--no-rewrite-program',
213
+ 'Do not set $0 to the program being debugged') do
214
+ options.no_rewrite_program = true
215
+ end
216
+ opts.on('--no-stop', 'Do not stop when script is loaded') do
217
+ options.stop = false
218
+ end
219
+ opts.on('-nx', 'Not run debugger initialization files (e.g. .rdebugrc') do
220
+ options.nx = true
221
+ end
222
+ opts.on('-p', '--port PORT', Integer, 'Port used for remote debugging') do
223
+ |port|
224
+ options.port = port
225
+ end
226
+ opts.on('-r', '--require SCRIPT', String,
227
+ 'Require the library, before executing your script') do |name|
228
+ if name == 'debug'
229
+ puts "ruby-debug is not compatible with Ruby's 'debug' library. This option is ignored."
230
+ else
231
+ require name
232
+ end
233
+ end
234
+ opts.on('--restart-script FILE', String,
235
+ 'Name of the script file to run. Erased after read') do
236
+ |restart_script|
237
+ options.restart_script = restart_script
238
+ unless File.exists?(options.restart_script)
239
+ puts "Script file '#{options.restart_script}' is not found"
240
+ exit
241
+ end
242
+ end
243
+ opts.on('--script FILE', String, 'Name of the script file to run') do
244
+ |script|
245
+ options.script = script
246
+ unless File.exists?(options.script)
247
+ puts "Script file '#{options.script}' is not found"
248
+ exit
249
+ end
250
+ end
251
+ opts.on('-s', '--server', 'Listen for remote connections') do
252
+ options.server = true
253
+ end
254
+ opts.on('-w', '--wait', 'Wait for a client connection, implies -s option') do
255
+ options.wait = true
256
+ end
257
+ opts.on('-x', '--trace', 'Turn on line tracing') {options.tracing = true}
258
+ opts.separator ''
259
+ opts.separator 'Common options:'
260
+ opts.on_tail('--help', 'Show this message') do
261
+ puts opts
262
+ exit
263
+ end
264
+ opts.on_tail('--version',
265
+ 'Print the version') do
266
+ puts "ruby-debug #{Debugger::VERSION}"
267
+ exit
268
+ end
269
+ opts.on('--verbose', 'Turn on verbose mode') do
270
+ $VERBOSE = true
271
+ options.verbose_long = true
272
+ end
273
+ opts.on_tail('-v',
274
+ 'Print version number, then turn on verbose mode') do
275
+ puts "ruby-debug #{Debugger::VERSION}"
276
+ $VERBOSE = true
277
+ end
278
+ end
279
+ return opts
280
+ end
281
+
282
+ # What file is used for debugger startup commands.
283
+ unless defined?(OPTS_INITFILE)
284
+ if RUBY_PLATFORM =~ /mswin/
285
+ # Of course MS Windows has to be different
286
+ OPTS_INITFILE = 'rdbopt.ini'
287
+ HOME_DIR = (ENV['HOME'] ||
288
+ ENV['HOMEDRIVE'].to_s + ENV['HOMEPATH'].to_s).to_s
289
+ else
290
+ OPTS_INITFILE = '.rdboptrc'
291
+ HOME_DIR = ENV['HOME'].to_s
292
+ end
293
+ end
294
+ begin
295
+ initfile = File.join(HOME_DIR, OPTS_INITFILE)
296
+ eval(File.read(initfile)) if
297
+ File.exist?(initfile)
298
+ rescue
299
+ end
300
+
301
+ opts = process_options(options)
302
+ begin
303
+ if not defined? Debugger::ARGV
304
+ Debugger::ARGV = ARGV.clone
305
+ end
306
+ rdebug_path = File.expand_path($0)
307
+ if RUBY_PLATFORM =~ /mswin/
308
+ rdebug_path += '.cmd' unless rdebug_path =~ /\.cmd$/i
309
+ end
310
+ Debugger::RDEBUG_SCRIPT = rdebug_path
311
+ Debugger::RDEBUG_FILE = __FILE__
312
+ Debugger::INITIAL_DIR = Dir.pwd
313
+ opts.parse! ARGV
314
+ rescue StandardError => e
315
+ puts opts
316
+ puts
317
+ puts e.message
318
+ exit(-1)
319
+ end
320
+
321
+ if options.client
322
+ Debugger.start_client(options.host, options.port)
323
+ else
324
+ if ARGV.empty?
325
+ exit if $VERBOSE and not options.verbose_long
326
+ puts opts
327
+ puts
328
+ puts 'Must specify a script to run'
329
+ exit(-1)
330
+ end
331
+
332
+ # save script name
333
+ prog_script = ARGV.shift
334
+ prog_script = whence_file(prog_script) unless File.exist?(prog_script)
335
+ Debugger::PROG_SCRIPT = File.expand_path prog_script
336
+
337
+ # install interruption handler
338
+ trap('INT') { Debugger.interrupt_last }
339
+
340
+ # set options
341
+ Debugger.wait_connection = options.wait
342
+
343
+ if options.server
344
+ # start remote mode
345
+ Debugger.start_remote(options.host, [options.port, options.cport]) do
346
+ # load initrc script
347
+ Debugger.run_init_script(StringIO.new) unless options.nx
348
+ end
349
+ debug_program(options)
350
+ else
351
+ # Set up trace hook for debugger
352
+ Debugger.start
353
+ # start control thread
354
+ Debugger.start_control(options.host, options.cport) if options.control
355
+
356
+ # load initrc script (e.g. .rdebugrc)
357
+ Debugger.run_init_script(StringIO.new) unless options.nx
358
+
359
+ # run restore-settings startup script if specified
360
+ if options.restart_script
361
+ require 'fileutils'
362
+ Debugger.run_script(options.restart_script)
363
+ FileUtils.rm(options.restart_script)
364
+ end
365
+
366
+ # run startup script if specified
367
+ if options.script
368
+ Debugger.run_script(options.script)
369
+ end
370
+
371
+ options.stop = false if options.tracing
372
+ Debugger.tracing = options.tracing
373
+
374
+ if !options.quit
375
+ if Debugger.started?
376
+ until Debugger.stop do end
377
+ end
378
+ begin
379
+ debug_program(options)
380
+ rescue SyntaxError
381
+ puts $!.backtrace.map{|l| "\t#{l}"}.join("\n")
382
+ puts "Uncaught Syntax Error\n"
383
+ rescue
384
+ print $!.backtrace.map{|l| "\t#{l}"}.join("\n"), "\n"
385
+ print "Uncaught exception: #{$!}\n"
386
+ end
387
+ print "The program finished.\n" unless
388
+ Debugger.annotate.to_i > 1 # annotate has its own way
389
+ interface = Debugger::LocalInterface.new
390
+ # Not sure if ControlCommandProcessor is really the right
391
+ # thing to use. CommandProcessor requires a state.
392
+ processor = Debugger::ControlCommandProcessor.new(interface)
393
+ processor.process_commands
394
+ else
395
+ debug_program(options)
396
+ end
397
+ end
398
+ end
@@ -0,0 +1,173 @@
1
+ require 'pp'
2
+ require 'stringio'
3
+ require 'socket'
4
+ require 'thread'
5
+ require 'ruby-debug-base'
6
+ require_relative 'ruby-debug/processor'
7
+
8
+ module Debugger
9
+ self.handler = CommandProcessor.new
10
+
11
+ # the port number used for remote debugging
12
+ PORT = 8989 unless defined?(PORT)
13
+
14
+ # What file is used for debugger startup commands.
15
+ unless defined?(INITFILE)
16
+ if RUBY_PLATFORM =~ /mswin/
17
+ # Of course MS Windows has to be different
18
+ INITFILE = 'rdebug.ini'
19
+ HOME_DIR = (ENV['HOME'] ||
20
+ ENV['HOMEDRIVE'].to_s + ENV['HOMEPATH'].to_s).to_s
21
+ else
22
+ INITFILE = '.rdebugrc'
23
+ HOME_DIR = ENV['HOME'].to_s
24
+ end
25
+ end
26
+
27
+ class << self
28
+ # gdb-style annotation mode. Used in GNU Emacs interface
29
+ attr_accessor :annotate
30
+
31
+ # in remote mode, wait for the remote connection
32
+ attr_accessor :wait_connection
33
+
34
+ # If set, a string to look for in caller() and is used to see
35
+ # if the call stack is truncated.
36
+ attr_accessor :start_sentinal
37
+
38
+ attr_reader :thread, :control_thread
39
+
40
+ def interface=(value) # :nodoc:
41
+ handler.interface = value
42
+ end
43
+
44
+ #
45
+ # Starts a remote debugger.
46
+ #
47
+ def start_remote(host = nil, port = PORT)
48
+ return if @thread
49
+
50
+ self.interface = nil
51
+ start
52
+
53
+ if port.kind_of?(Array)
54
+ cmd_port, ctrl_port = port
55
+ else
56
+ cmd_port, ctrl_port = port, port + 1
57
+ end
58
+
59
+ start_control(host, ctrl_port)
60
+
61
+ yield if block_given?
62
+
63
+ mutex = Mutex.new
64
+ proceed = ConditionVariable.new
65
+
66
+ @thread = DebugThread.new do
67
+ server = TCPServer.new(host, cmd_port)
68
+ while (session = server.accept)
69
+ self.interface = RemoteInterface.new(session)
70
+ if wait_connection
71
+ mutex.synchronize do
72
+ proceed.signal
73
+ end
74
+ end
75
+ end
76
+ end
77
+ if wait_connection
78
+ mutex.synchronize do
79
+ proceed.wait(mutex)
80
+ end
81
+ end
82
+ end
83
+ alias start_server start_remote
84
+
85
+ def start_control(host = nil, ctrl_port = PORT + 1) # :nodoc:
86
+ return if defined?(@control_thread) && @control_thread
87
+ @control_thread = DebugThread.new do
88
+ server = TCPServer.new(host, ctrl_port)
89
+ while (session = server.accept)
90
+ interface = RemoteInterface.new(session)
91
+ processor = ControlCommandProcessor.new(interface)
92
+ processor.process_commands
93
+ end
94
+ end
95
+ end
96
+
97
+ #
98
+ # Connects to the remote debugger
99
+ #
100
+ def start_client(host = 'localhost', port = PORT)
101
+ require "socket"
102
+ interface = Debugger::LocalInterface.new
103
+ socket = TCPSocket.new(host, port)
104
+ puts "Connected."
105
+
106
+ catch(:exit) do
107
+ while (line = socket.gets)
108
+ case line
109
+ when /^PROMPT (.*)$/
110
+ input = interface.read_command($1)
111
+ throw :exit unless input
112
+ socket.puts input
113
+ when /^CONFIRM (.*)$/
114
+ input = interface.confirm($1)
115
+ throw :exit unless input
116
+ socket.puts input
117
+ else
118
+ print line
119
+ end
120
+ end
121
+ end
122
+ socket.close
123
+ end
124
+
125
+ # Runs normal debugger initialization scripts
126
+ # Reads and executes the commands from init file (if any) in the
127
+ # current working directory. This is only done if the current
128
+ # directory is different from your home directory. Thus, you can
129
+ # have more than one init file, one generic in your home directory,
130
+ # and another, specific to the program you are debugging, in the
131
+ # directory where you invoke ruby-debug.
132
+ def run_init_script(out = handler.interface)
133
+ cwd_script_file = File.expand_path(File.join(".", INITFILE))
134
+ run_script(cwd_script_file, out) if File.exists?(cwd_script_file)
135
+
136
+ home_script_file = File.expand_path(File.join(HOME_DIR, INITFILE))
137
+ run_script(home_script_file, out) if File.exists?(home_script_file) and
138
+ cwd_script_file != home_script_file
139
+ end
140
+
141
+ #
142
+ # Runs a script file
143
+ #
144
+ def run_script(file, out = handler.interface, verbose=false)
145
+ interface = ScriptInterface.new(File.expand_path(file), out)
146
+ processor = ControlCommandProcessor.new(interface)
147
+ processor.process_commands(verbose)
148
+ end
149
+ end
150
+ end
151
+
152
+ module Kernel
153
+
154
+ # Enters the debugger in the current thread after _steps_ line events occur.
155
+ # Before entering the debugger startup script is read.
156
+ #
157
+ # Setting _steps_ to 0 will cause a break in the debugger subroutine
158
+ # and not wait for a line event to occur. You will have to go "up 1"
159
+ # in order to be back in your debugged program rather than the
160
+ # debugger. Settings _steps_ to 0 could be useful you want to stop
161
+ # right after the last statement in some scope, because the next
162
+ # step will take you out of some scope.
163
+ def debugger(steps = 1)
164
+ Debugger.start
165
+ Debugger.run_init_script(StringIO.new)
166
+ if 0 == steps
167
+ Debugger.current_context.stop_frame = 0
168
+ else
169
+ Debugger.current_context.stop_next = steps
170
+ end
171
+ end
172
+ alias breakpoint debugger unless respond_to?(:breakpoint)
173
+ end