blob: cbe38991fca39059cf96c5ed44914a9b4d061a1b [file] [log] [blame]
###############################################################################
# Copyright (c) 2005, 2007 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
###############################################################################
require 'common/Logger'
require 'common/Params'
require 'cgi'
require 'monitor'
require 'debugger/AbstractDebugger'
require 'basic/BasicBreakpointManager'
require 'basic/BasicContext'
module Kernel
alias_method(:xored_debugger_set_trace_func, :set_trace_func)
def set_trace_func(proc)
raise "Cannot call 'set_trace_func' method during debugging session."
end
end
module XoredDebugger
class DebugThread < Thread
end
class BasicDebugger < AbstractDebugger
include Logger
def initialize()
super
end
def get_debugger_id
'org.eclipse.dltk.ruby.basicdebugger'
end
def start
log('Setting tracing function')
xored_debugger_set_trace_func proc { |event, file, line, id, binding, klass, *rest|
trace(event, file, line, id, binding, klass)
}
end
def terminate
log('Terminating debugger')
begin
super
ensure
xored_debugger_set_trace_func nil
end
end
def create_breakpoint_manager()
BasicBreakpointManager.new
end
def create_context_impl(thread)
return BasicContext.new(thread)
end
def create_debug_thread(*args, &block)
DebugThread.new(*args, &block)
end
def is_debug_thread?(thread)
thread.is_a? DebugThread
end
# Tracing
def trace(event, file, line, id, binding, klass)
begin
# Don't debug debugger intenal threads
# NOTE: To disable tracing of thread create it from tracing
# function (doesn't work with JRuby)
if (Thread.current.is_a? DebugThread)
return
end
context = current_context
# if thread was suspended, then stop execution
context.check_suspended
# Output handling
case event
when 'line'
# checking line breakpoint
context.stack_update(file, line, binding, get_label(binding, klass, id))
if (breakpoint_manager.check_line_breakpoint(file, line, context))
context.reset_stepping
handler.at_breakpoint(context) unless handler.nil?
handler.at_line(context, file, line) unless handler.nil?
else
if (context.check_stepping)
context.reset_stepping
handler.at_line(context, file, line) unless handler.nil?
end
end
when 'raise'
# checking exception breakpoint
context.stack_update(file, line, binding, get_label(binding, klass, id))
if (breakpoint_manager.check_exception_breakpoint($!, context))
context.reset_stepping
handler.at_catchpoint(context, $!) unless handler.nil?
handler.at_line(context, file, line) unless handler.nil?
end
when 'call', 'c-call', 'class'
context.stack_push(file, line, binding, get_label(binding, klass, id))
when 'return', 'c-return', 'end'
context.stack_pop
else
log('Warning: unknown event type "' + event + '"')
end
rescue Exception
logException($!, 'in tracing function')
end
end
def get_label(binding, klass, id)
label = ''
# Causes null pointer in JRuby
label += klass.to_s if klass != false
label += '::' + id.id2name unless id.nil?
label = get_module_name(binding) if label.empty?
return label
end
def get_module_name(binding)
modules = Kernel.eval('Module.nesting', binding)
if (!modules.empty?)
mod = modules[0].to_s
if (mod.is_a? Class)
mod.name
else
mod.to_s
end
else
'toplevel'
end
end
end # class BasicDebugger
end # module