Module: Rcov::RCOV__

Defined in:
lib/rcov/lowlevel.rb,
ext/rcovrt/1.8/rcovrt.c,
ext/rcovrt/1.8/callsite.c

Overview

RCOV__ performs the low-level tracing of the execution, gathering code coverage information in the process. The C core made available through the rcovrt extension will be used if possible. Otherwise the functionality will be emulated using set_trace_func, but this is very expensive and will fail if other libraries (e.g. breakpoint) change the trace_func.

Do not use this module; it is very low-level and subject to frequent changes. Rcov::CodeCoverageAnalyzer offers a much more convenient and stable interface.

Constant Summary collapse

COVER =
{}
CALLSITES =
{}
DEFSITES =
{}

Class Method Summary collapse

Class Method Details

.ABIObject



232
233
234
235
236
237
238
239
240
241
# File 'ext/rcovrt/1.8/rcovrt.c', line 232

static VALUE cov_ABI(VALUE self) {
  VALUE ret;

  ret = rb_ary_new();
  rb_ary_push(ret, INT2FIX(RCOVRT_VERSION_MAJOR));
  rb_ary_push(ret, INT2FIX(RCOVRT_VERSION_MINOR));
  rb_ary_push(ret, INT2FIX(RCOVRT_VERSION_REV));

  return ret;
}

.format_backtrace_array(backtrace) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/rcov/lowlevel.rb', line 136

def self.format_backtrace_array(backtrace)
  backtrace.map do |line|
    md = /^([^:]*)(?::(\d+)(?::in `(.*)'))?/.match(line)
    raise "Bad backtrace format" unless md
    [nil, md[3] ? md[3].to_sym : nil, md[1], (md[2] || '').to_i]
  end
end

.generate_callsite_infoObject

:nodoc:



132
133
134
# File 'lib/rcov/lowlevel.rb', line 132

def self.generate_callsite_info # :nodoc:
  [CALLSITES, DEFSITES]
end

.generate_coverage_infoObject

:nodoc:



128
129
130
# File 'lib/rcov/lowlevel.rb', line 128

def self.generate_coverage_info # :nodoc:
  Marshal.load(Marshal.dump(COVER))
end

.install_callsite_hookObject

:nodoc:



71
72
73
74
# File 'lib/rcov/lowlevel.rb', line 71

def self.install_callsite_hook # :nodoc:
  install_common_hook
  @callsite_hook_activated = true
end

.install_common_hookObject

:nodoc:



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/rcov/lowlevel.rb', line 76

def self.install_common_hook # :nodoc:
  set_trace_func lambda {|event, file, line, id, binding, klass|
    next unless SCRIPT_LINES__.has_key? file
    case event
    when 'call'
      if @callsite_hook_activated
        receiver = eval("self", binding)
        klass = class << klass; self end unless klass === receiver
        begin
          DEFSITES[[klass.to_s, id.to_s]] = [file, line]
        rescue Exception
        end
        caller_arr = self.format_backtrace_array(caller[1,1])
        begin
          hash = CALLSITES[[klass.to_s, id.to_s]] ||= {}
          hash[caller_arr] ||= 0
          hash[caller_arr] += 1
          #puts "#{event} #{file} #{line} #{klass.inspect} " +
          #     "#{klass.object_id} #{id} #{eval('self', binding)}"
        rescue Exception
        end
      end
    when 'c-call', 'c-return', 'class'
      return
    end
    if @coverage_hook_activated
      COVER[file] ||= Array.new(SCRIPT_LINES__[file].size, 0)
      COVER[file][line - 1] ||= 0
      COVER[file][line - 1] += 1
    end
  }
end

.install_coverage_hookObject

:nodoc:



66
67
68
69
# File 'lib/rcov/lowlevel.rb', line 66

def self.install_coverage_hook # :nodoc:
  install_common_hook
  @coverage_hook_activated = true
end

.remove_callsite_hookObject

:nodoc:



114
115
116
117
# File 'lib/rcov/lowlevel.rb', line 114

def self.remove_callsite_hook # :nodoc:
  @callsite_hook_activated = false
  set_trace_func(nil) if !@coverage_hook_activated
end

.remove_coverage_hookObject

:nodoc:



109
110
111
112
# File 'lib/rcov/lowlevel.rb', line 109

def self.remove_coverage_hook # :nodoc:
  @coverage_hook_activated = false
  set_trace_func(nil) if !@callsite_hook_activated
end

.reset_callsiteObject

:nodoc:



123
124
125
126
# File 'lib/rcov/lowlevel.rb', line 123

def self.reset_callsite # :nodoc:
  CALLSITES.replace({})
  DEFSITES.replace({})
end

.reset_coverageObject

:nodoc:



119
120
121
# File 'lib/rcov/lowlevel.rb', line 119

def self.reset_coverage # :nodoc:
  COVER.replace({})
end