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