class Argtrace::CallStack

call stack of tracing targets

Public Class Methods

new() click to toggle source
# File lib/argtrace/tracer.rb, line 15
def initialize
  # thread.object_id => stack
  @stack = Hash.new{|h,k| h[k] = []}
end

Public Instance Methods

find_by_block_location(tp) click to toggle source

find callinfo which use specific block

# File lib/argtrace/tracer.rb, line 49
def find_by_block_location(tp)
  id = Thread.current.object_id
  ret = []
  @stack[id].each do |info|
    if info.block_proc && info.block_proc.source_location == [tp.path, tp.lineno]
      # Warning: sometimes different block has same location.
      # I cannot handle such case strictly, but use heuristics by comparing parameter names.
      if tp.parameters.map{|x| x[1]} == info.block_proc.parameters.map{|x| x[1]}
        ret << info
      end
    end
  end
  return ret
end
pop_callstack(tp) click to toggle source
# File lib/argtrace/tracer.rb, line 28
    def pop_callstack(tp)
      id = Thread.current.object_id
      ent = @stack[id].pop
      if ent
        # DEBUG:
        # p "[#{id}]<<" + " "*@stack[id].size*2 + ent.signature.to_s

        if tp.method_id != ent.signature.method_id
          raise <<~EOF
            callstack is broken
            returning by tracepoint: #{tp.defined_class}::#{tp.method_id}
            top of stack: #{ent.signature.to_s}
            rest of stack:
              #{@stack[id].map{|x| x.signature.to_s}.join("\n  ")}
          EOF
        end
      end
      return ent
    end
push_callstack(callinfo) click to toggle source
# File lib/argtrace/tracer.rb, line 20
def push_callstack(callinfo)
  id = Thread.current.object_id
  # DEBUG:
  # p "[#{id}]>>" + " "*@stack[id].size*2 + callinfo.signature.to_s

  @stack[id].push callinfo
end