This repository was archived by the owner on Nov 15, 2021. It is now read-only.
forked from mark-moseley/ruby-debug
-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathtdebug.rb
More file actions
executable file
·246 lines (222 loc) · 7 KB
/
tdebug.rb
File metadata and controls
executable file
·246 lines (222 loc) · 7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#!/usr/bin/env ruby
# -*- Ruby -*-
# This is a hacked down copy of rdebug which can be used for testing
# FIXME: use the real rdebug script - DRY.
require 'stringio'
require 'optparse'
require "ostruct"
TOP_SRC_DIR = File.join(File.dirname(__FILE__), "..") unless
defined?(TOP_SRC_DIR)
$:.unshift File.join(TOP_SRC_DIR, "ext")
$:.unshift File.join(TOP_SRC_DIR, "lib")
def debug_program(options)
# Make sure Ruby script syntax checks okay.
# Otherwise we get a load message that looks like rdebug has
# a problem.
output = `ruby -c "#{Debugger::PROG_SCRIPT}" 2>&1`
if $?.exitstatus != 0 and RUBY_PLATFORM !~ /mswin/
puts output
exit $?.exitstatus
end
print "\032\032starting\n" if Debugger.annotate and Debugger.annotate > 2
unless options.no_rewrite_program
# Set $0 so things like __FILE == $0 work.
# A more reliable way to do this is to put $0 = __FILE__ *after*
# loading the script to be debugged. For this, adding a debug hook
# for the first time and then switching to the debug hook that's
# normally used would be helpful. Doing this would also help other
# first-time initializations such as reloading debugger state
# after a restart.
# However This is just a little more than I want to take on right
# now, so I think I'll stick with the slightly hacky approach.
$RDEBUG_0 = $0
# cygwin does some sort of funky truncation on $0 ./abcdef => ./ab
# probably something to do with 3-letter extension truncation.
# The hacky workaround is to do slice assignment. Ugh.
d0 = if '.' == File.dirname(Debugger::PROG_SCRIPT) and
Debugger::PROG_SCRIPT[0..0] != '.'
File.join('.', Debugger::PROG_SCRIPT)
else
Debugger::PROG_SCRIPT
end
if $0.frozen?
$0 = d0
else
$0[0..-1] = d0
end
end
# Record where we are we can know if the call stack has been
# truncated or not.
Debugger.start_sentinal=caller(0)[1]
bt = Debugger.debug_load(Debugger::PROG_SCRIPT, !options.nostop, false)
if bt
if options.post_mortem
Debugger.handle_post_mortem(bt)
else
print bt.backtrace.map{|l| "\t#{l}"}.join("\n"), "\n"
print "Uncaught exception: #{bt}\n"
end
end
end
options = OpenStruct.new(
'annotate' => false,
'emacs' => false,
'no-quit' => false,
'no-stop' => false,
'nx' => false,
'post_mortem' => false,
'script' => nil,
'tracing' => false,
'verbose_long'=> false,
'wait' => false
)
require "ruby-debug"
program = File.basename($0)
opts = OptionParser.new do |opts|
opts.banner = <<EOB
#{program} #{Debugger::VERSION}
Usage: #{program} [options] <script.rb> -- <script.rb parameters>
EOB
opts.separator ""
opts.separator "Options:"
opts.on("-A", "--annotate LEVEL", Integer, "Set annotation level") do |s|
Debugger.annotate = s
end
opts.on("-d", "--debug", "Set $DEBUG=true") {$DEBUG = true}
opts.on("--emacs-basic", "Activates basic Emacs mode") do
ENV['EMACS'] = '1'
options.emacs = true
end
opts.on("-m", "--post-mortem", "Activate post-mortem mode") do
options.post_mortem = true
end
opts.on("--no-control", "Do not automatically start control thread") do
options.control = false
end
opts.on("--no-quit", "Do not quit when script finishes") do
options.noquit = true
end
opts.on("--no-stop", "Do not stop when script is loaded") do
options.nostop = true
end
opts.on("-nx", "Not run debugger initialization files (e.g. .rdebugrc") do
options.nx = true
end
opts.on("-I", "--include PATH", String, "Add PATH to $LOAD_PATH") do |path|
$LOAD_PATH.unshift(*path.split(':'))
end
opts.on("-r", "--require SCRIPT", String,
"Require the library, before executing your script") do |name|
if name == 'debug'
puts "ruby-debug is not compatible with Ruby's 'debug' library. This option is ignored."
else
require name
end
end
opts.on("--script FILE", String, "Name of the script file to run") do |s|
options.script = s
unless File.exists?(options.script)
puts "Script file '#{options.script}' is not found"
exit
end
end
opts.on("-x", "--trace", "Turn on line tracing") {options.tracing = true}
ENV['EMACS'] = nil unless options.emacs
opts.separator ""
opts.separator "Common options:"
opts.on_tail("--help", "Show this message") do
puts opts
exit
end
opts.on_tail("--version",
"Print the version") do
puts "ruby-debug #{Debugger::VERSION}"
exit
end
opts.on("--verbose", "Turn on verbose mode") do
$VERBOSE = true
options.verbose_long = true
end
opts.on_tail("-v",
"Print version number, then turn on verbose mode") do
puts "ruby-debug #{Debugger::VERSION}"
$VERBOSE = true
end
end
begin
if not defined? Debugger::ARGV
Debugger::ARGV = ARGV.clone
end
rdebug_path = File.expand_path($0)
if RUBY_PLATFORM =~ /mswin/
rdebug_path += '.cmd' unless rdebug_path =~ /\.cmd$/i
end
Debugger::RDEBUG_SCRIPT = rdebug_path
Debugger::RDEBUG_FILE = __FILE__
Debugger::INITIAL_DIR = Dir.pwd
opts.parse! ARGV
rescue StandardError => e
puts opts
puts
puts e.message
exit(-1)
end
if ARGV.empty?
exit if $VERBOSE and not options.verbose_long
puts opts
puts
puts 'Must specify a script to run'
exit(-1)
end
# save script name
Debugger::PROG_SCRIPT = ARGV.shift
# install interruption handler
trap('INT') { Debugger.interrupt_last }
# set options
Debugger.wait_connection = false
# Add Debugger trace hook.
Debugger.start
# start control thread
Debugger.start_control(options.host, options.cport) if options.control
# activate post-mortem
Debugger.post_mortem if options.post_mortem
# Set up an interface to read commands from a debugger script file.
if options.script
Debugger.interface = Debugger::ScriptInterface.new(options.script,
STDOUT, true)
end
options.nostop = true if options.tracing
Debugger.tracing = options.tracing
# Make sure Ruby script syntax checks okay.
# Otherwise we get a load message that looks like rdebug has
# a problem.
output = `ruby -c #{Debugger::PROG_SCRIPT} 2>&1`
if $?.exitstatus != 0 and RUBY_PLATFORM !~ /mswin/
puts output
exit $?.exitstatus
end
# load initrc script (e.g. .rdebugrc)
Debugger.run_init_script(StringIO.new) unless options.nx
# run startup script if specified
if options.script
Debugger.run_script(options.script)
end
# activate post-mortem
Debugger.post_mortem if options.post_mortem
options.stop = false if options.tracing
Debugger.tracing = options.tracing
if options.noquit
if Debugger.started?
until Debugger.stop do end
end
debug_program(options)
print "The program finished.\n" unless
Debugger.annotate.to_i > 1 # annotate has its own way
interface = Debugger::LocalInterface.new
# Not sure if ControlCommandProcessor is really the right
# thing to use. CommandProcessor requires a state.
processor = Debugger::ControlCommandProcessor.new(interface)
processor.process_commands
else
debug_program(options)
end