| ############################################################################### |
| # Copyright (c) 2005, 2007 IBM Corporation and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License v. 2.0 which is available at |
| # http://www.eclipse.org/legal/epl-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 |
| # |
| |
| ############################################################################### |
| |
| require 'stringio' |
| require 'common/Logger' |
| require 'dbgp/StreamPacket' |
| |
| module XoredDebugger |
| class StdoutCapturer |
| attr_accessor :state |
| |
| def initialize(&redirector) |
| @redirector = redirector |
| @state = CaptureManager::COPY |
| @capture = StringIO.new |
| $stdout = @capture |
| end |
| |
| def flush_captured |
| temp_capturer = StringIO.new |
| $stdout = temp_capturer |
| @capture.rewind |
| captured = @capture.read |
| @capture = temp_capturer |
| |
| unless captured.empty? |
| STDOUT.write(captured) if @state != CaptureManager::REDIRECT |
| @redirector.call(captured) if @state != CaptureManager::DISABLE |
| end |
| end |
| |
| def terminate |
| $stdout = STDOUT |
| end |
| end # class StdoutCapturer |
| |
| |
| class StderrCapturer |
| attr_accessor :state |
| |
| def initialize(&redirector) |
| @redirector = redirector |
| @state = CaptureManager::COPY |
| @capture = StringIO.new |
| $stderr = @capture |
| end |
| |
| def flush_captured |
| temp_capturer = StringIO.new |
| $stderr = temp_capturer |
| @capture.rewind |
| captured = @capture.read |
| @capture = temp_capturer |
| |
| unless captured.empty? |
| STDERR.write(captured) if @state != CaptureManager::REDIRECT |
| @redirector.call(captured) if @state != CaptureManager::DISABLE |
| end |
| end |
| |
| def terminate |
| $stderr = STDOUT |
| end |
| end # class StderrCapturer |
| |
| class CaptureManager |
| DISABLE = 0 |
| COPY = 1 |
| REDIRECT = 2 |
| include Logger |
| |
| attr_reader :stdout_capturer |
| attr_reader :stderr_capturer |
| |
| def initialize(thread_manager) |
| @thread_manager = thread_manager |
| @stdout_capturer = StdoutCapturer.new { |
| |message| |
| # send through main thread's connection |
| dbgp_thread = @thread_manager.get_dbgp_thread(Thread.main) |
| if (!dbgp_thread.nil?) |
| dbgp_thread.communicator.sendPacket(StreamPacket.new('stdout', message)) |
| else |
| puts("Could not redirect message, cause communication links broken. Message:\n" + message) |
| end |
| } |
| |
| @stderr_capturer = StderrCapturer.new { |
| |message| |
| # send through main thread's connection |
| dbgp_thread = @thread_manager.get_dbgp_thread(Thread.main) |
| if (!dbgp_thread.nil?) |
| dbgp_thread.communicator.sendPacket(StreamPacket.new('stderr', message)) |
| else |
| puts("Could not redirect message, cause communication links broken. Message:\n" + message) |
| end |
| } |
| |
| @terminating = false |
| debugger = thread_manager.debugger |
| @flusher = debugger.create_debug_thread do |
| flusher_loop |
| end |
| end |
| |
| def flusher_loop |
| begin |
| log('Capture flusher started') |
| while (@terminating == false) |
| sleep 0.5 |
| @stdout_capturer.flush_captured |
| @stderr_capturer.flush_captured |
| end |
| log('Capture flusher terminated') |
| rescue Exception |
| puts $!.message |
| logException($!, 'in capture flusher') |
| end |
| end |
| |
| def terminate() |
| @stdout_capturer.terminate |
| @stderr_capturer.terminate |
| @terminating = true |
| @flusher.wakeup() |
| @flusher.join |
| end |
| end # class CaptureManager |
| end # module XoredDebugger |