blob: 14ac78f3c5b0d6573bf8f4c2f13dc80df93446c7 [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 'cgi'
require 'thread'
require 'dbgp/command'
require 'dbgp/socket_io'
require 'dbgp/test_io'
require 'dbgp/printer'
require 'dbgp/capturer'
require 'dbgp/ruby_thread'
require 'dbgp/ruby_breakpoints'
module XoredDebugger
class RubyDebugger
private
def add_thread(thread)
@logger.puts('Adding thread: ' + thread.to_s)
printer = Printer.new
io = @test ? TestIO.new(@logger, printer) : SocketIO.new(@host, @port, @logger, printer)
@threads[thread] = RubyThread.new(self, thread, io, @key)
end
def remove_thread(thread)
@logger.puts('Removing thread: ' + thread.to_s)
@threads[thread].terminate
@threads.delete(thread)
end
def thread_list
Thread.list - [@remover]
end
def add_threads
@mutex.synchronize do
added = thread_list - @threads.keys
added.each { |t|
add_thread(t)
}
end
end
def remove_threads
@mutex.synchronize do
@threads.each { |t, thread|
if thread.terminated?
Thread.kill(t)
end
}
removed = @threads.keys - thread_list
removed.each { |t|
remove_thread(t)
}
end
end
public
def initialize(host, port, key, logger, test)
@host = host
@port = port
@key = key
@logger = logger
@test = test
@threads = {}
@stdout_capturer = StdoutCapturer.new(true)
#@stderr_capturer = StderrCapturer.new(true)
@breakpoints = Breakpoints.new
@mutex = Mutex.new
@remover = Thread.new do
loop do
remove_threads
sleep 0.5
end
end
end
def terminate
@logger.puts('Debugger termination...')
Thread.kill(@remover)
@mutex.synchronize do
@threads.each { |thread, t|
t.terminate
}
end
end
def breakpoints
@breakpoints
end
def logger
@logger
end
def capturer
@stdout_capturer
end
# Logging
def log(text)
@logger.puts(text)
end
# Test mode
def test?
@test
end
# Tracing
def trace(event, file, line, id, binding, klass)
if Thread.current == @remover
return
end
add_threads
thread = @threads[Thread.current]
thread.trace(event, file, line, id, binding, klass)
end
end # class RubyDebugger
end # module