blob: 0b765c84fe71d62a1e42c56c64da08aaace53935 [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 'thread'
module XoredDebugger
class Breakpoint
COND_GREATER_OR_EQUALS = '>='
COND_EQUALS = '=='
COND_MULTIPLE = '%'
def initialize(id, state = true, temporary = false, expression = nil, hit_value = 1, hit_condition = COND_GREATER_OR_EQUALS)
@id = id # Unique identifier
@state = state # Enabled or disabled
@temporary = temporary # Breakpoint should be removed after first hit
@expression = expression
@hit_count = 0 # Number of breakpoint hits
@hit_value = hit_value # Special value used with hit_condition
@hit_condition = hit_condition # The relation between hit_value and hit_count
end
attr_reader :id
attr_reader :state
attr_writer :state
attr_reader :hit_count, :hit_value, :hit_condition
def update(state, temporary, expression, hit_value, hit_condition)
@state = state
@temporary = temporary
@expression = expression
@hit_value = hit_value
@hit_condition = hit_condition
end
def hit(stack)
@hit_count += 1
# Expression
unless @expression.nil?
begin
if not stack.eval(expression)
return false # Expression evaluated to false
end
rescue Exception
return false # Expression can not be evaluated
end
end
# State
if not @state
return false # Breakpoint disabled
end
# Hit condition
case @hit_condition
when COND_GREATER_OR_EQUALS
@hit_count >= @hit_value
when COND_EQUALS
@hit_count == @hit_value
when COND_MULTIPLE
(@hit_count % @hit_value) == 0
else
false
end
end
def exists
@temporary ? @hit_count == 0 : true
end
protected :hit
end # class Breakpoint
#
# N.B. Stores absolute path names
#
class LineBreakpoint < Breakpoint
def initialize(id, file, line, state = true, temporary = false, expression = nil, hit_value = 1, hit_condition = COND_GREATER_OR_EQUALS)
super(id, state, temporary, expression, hit_value, hit_condition)
@file = file
@line = line
end
attr_reader :line, :file
def hit(stack, file, line)
@file == file and @line == line and super(stack)
end
attr_reader :file, :line
end # class LineBreakpoint
class ExceptionBreakpoint < Breakpoint
def initialize(id, exception, state = true, temporary = false)
super(id, state, temporary)
@exception = exception
end
def hit(stack, exception)
@exception == exception and super(stack)
end
end # class ExceptionBreakpoint
class Breakpoints
private
@@id = 0
def Breakpoints.next_id
@@id += 1
end
public
def initialize
@mutex = Mutex.new
@line_bps = {}
@exception_bps = {}
end
def [] (id)
@line_bps[id]
end
def line_break?(stack, file, line)
@mutex.synchronize do
result = false
for bp in @line_bps.values do
if bp.hit(stack, file, line)
result = true
end
end
result
end
end
def exception_break?(stack, exception)
@mutex.synchronize do
end
end
def set_line_bpt(file, line, state, temporary, expression, hit_value, hit_condition)
@mutex.synchronize do
id = Breakpoints.next_id
@line_bps[id] = LineBreakpoint.new(id, file, line, state, temporary, expression, hit_value, hit_condition)
id
end
end
def set_exception_bpt(exception, state)
@mutex.synchronize do
id = Breakpoints.next_id
# TODO:
id
end
end
def update(id, state, temporary, expression, hit_value, hit_condition)
@mutex.synchronize do
@line_bps[id].update(state, temporary, expression, hit_value, hit_condition)
end
end
def remove(id)
@mutex.synchronize do
(not @line_bps.delete(id).nil?) or (not @exception_bps.delete(id).nil?)
end
end
end # class Breakpoints
end # module XoredDebugger