lib/ruby-debug/command.rb in ruby-debug-ide-0.1.3 vs lib/ruby-debug/command.rb in ruby-debug-ide-0.1.4
- old
+ new
@@ -16,11 +16,11 @@
DEF_OPTIONS.each do |o, v|
klass.options[o] = v if klass.options[o].nil?
end
commands << klass
end
-
+
def load_commands
dir = File.dirname(__FILE__)
Dir[File.join(dir, 'commands', '*')].each do |file|
require file if file =~ /\.rb$/
end
@@ -40,72 +40,94 @@
def options
@options ||= {}
end
end
-
+
def initialize(state, printer)
@state, @printer = state, printer
end
-
+
def match(input)
@match = regexp.match(input)
end
-
+
protected
def method_missing(meth, *args, &block)
if @printer.respond_to? meth
@printer.send meth, *args, &block
else
super
end
end
-
+
def print(*args)
@state.print(*args)
end
-
+
def confirm(msg)
@state.confirm(msg) == 'y'
end
-
+
+ # see Timeout::timeout, the difference is that we must use a DebugThread
+ # because every other thread would be halted when the event hook is reached
+ # in ruby-debug.c
+ def timeout(sec)
+ return yield if sec == nil or sec.zero?
+ raise ThreadError, "timeout within critical session" if Thread.critical
+ begin
+ x = Thread.current
+ y = DebugThread.start {
+ sleep sec
+ x.raise StandardError, "Timeout: evaluation took longer than #{sec} seconds." if x.alive?
+ }
+ yield sec
+ ensure
+ y.kill if y and y.alive?
+ end
+ end
+
def debug_eval(str, b = get_binding)
begin
- val = eval(str, b)
+ max_time = 10
+ @printer.print_debug("Evaluating with timeout after %i sec", max_time)
+ timeout(max_time) do
+ eval(str, b)
+ end
rescue StandardError, ScriptError => e
@printer.print_exception(e, @state.binding)
throw :debug_error
end
end
-
+
def debug_silent_eval(str)
begin
eval(str, get_binding)
rescue StandardError, ScriptError
nil
end
end
-
+
def hbinding(hash)
code = hash.keys.map{|k| "#{k} = hash['#{k}']"}.join(';') + ';binding'
if obj = @state.context.frame_self(@state.frame_pos)
obj.instance_eval code
else
eval code
end
end
private :hbinding
-
+
def get_binding
binding = @state.context.frame_binding(@state.frame_pos)
binding || hbinding(@state.context.frame_locals(@state.frame_pos))
end
-
+
def line_at(file, line)
Debugger.line_at(file, line)
end
-
+
def get_context(thnum)
Debugger.contexts.find{|c| c.thnum == thnum}
end
end