Class: Contrast::Agent::Patching::Policy::AfterLoadPatch

Inherits:
Object
  • Object
show all
Includes:
Components::Scope::InstanceMethods
Defined in:
lib/contrast/agent/patching/policy/after_load_patch.rb

Overview

Used to handle tracking patches that need to apply special instrumentation when a module is loaded

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Components::Scope::InstanceMethods

#contrast_enter_method_scopes!, #contrast_exit_method_scopes!, #with_app_scope, #with_contrast_scope, #with_deserialization_scope, #with_split_scope

Constructor Details

#initialize(module_name, instrumentation_file_path, method_to_instrument: nil, instrumenting_module: nil) ⇒ AfterLoadPatch

Returns a new instance of AfterLoadPatch.



18
19
20
21
22
23
24
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 18

def initialize module_name, instrumentation_file_path, method_to_instrument: nil, instrumenting_module: nil
  @applied = false
  @module_name = module_name
  @method_to_instrument = method_to_instrument
  @instrumentation_file_path = instrumentation_file_path
  @instrumenting_module = instrumenting_module
end

Instance Attribute Details

#appliedObject (readonly)

Returns the value of attribute applied.



16
17
18
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 16

def applied
  @applied
end

#instrumentation_file_pathObject (readonly)

Returns the value of attribute instrumentation_file_path.



16
17
18
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 16

def instrumentation_file_path
  @instrumentation_file_path
end

#instrumenting_moduleObject (readonly)

Returns the value of attribute instrumenting_module.



16
17
18
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 16

def instrumenting_module
  @instrumenting_module
end

#method_to_instrumentObject (readonly)

Returns the value of attribute method_to_instrument.



16
17
18
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 16

def method_to_instrument
  @method_to_instrument
end

#module_nameObject (readonly)

Returns the value of attribute module_name.



16
17
18
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 16

def module_name
  @module_name
end

Instance Method Details

#applied?Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 26

def applied?
  applied
end

#applies?(loaded_module_name) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 53

def applies? loaded_module_name
  (loaded_module_name == module_name) && !blocked_by_method?
end

#blocked_by_method?Boolean

Modules can be re-opened, so the first load may not necessarily define the method we’re looking for:

patching MyMod#instrumentable:

file1:

module MyMod
  def unrelated        <-- false lead
  end
end

file2:

module MyMod
  def instrumentable   <-- actual target
  end
end

Returns:

  • (Boolean)


46
47
48
49
50
51
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 46

def blocked_by_method?
  return true  unless target_defined? # bc no methods are loaded
  return false unless method_to_instrument

  !module_lookup.instance_methods.include?(method_to_instrument)
end

#instrument!Object



61
62
63
64
65
66
67
68
69
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 61

def instrument!
  require(instrumentation_file_path)

  if instrumenting_module
    mod = Module.cs__const_get(instrumenting_module)
    with_contrast_scope { mod.instrument } if mod
  end
  @applied = true
end

#target_defined?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/contrast/agent/patching/policy/after_load_patch.rb', line 57

def target_defined?
  Contrast::Utils::ClassUtil.truly_defined?(module_name)
end