Class: Vivarium::Box

Inherits:
Module
  • Object
show all
Defined in:
lib/vivarium/box.rb

Overview

Box provides an isolated execution context where method calls are automatically traced through Vivarium’s observation system.

Usage:

box = Vivarium::Box.new
box.eval('class MyClass; def foo; "result"; end; end')
result = box::MyClass.new.foo  # automatically traced if Vivarium.observe is active

Constant Summary collapse

DEFAULT_FILTER =
{
  include_events: %w[
    proc_fork proc_exec span_start span_stop
    sock_connect dns_req odd_socket
    ssl_write
    dlopen mmap_exec
    task_kill
    setid_change capable_check bprm_creds
  ]
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pin_dir: Vivarium.bpf_pin_dir, dest: $stdout, filter: DEFAULT_FILTER) ⇒ Box

Returns a new instance of Box.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/vivarium/box.rb', line 26

def initialize(pin_dir: Vivarium.bpf_pin_dir, dest: $stdout, filter: DEFAULT_FILTER)
  super()
  @inner_box = Ruby::Box.new
  @pin_dir = pin_dir
  @dest = dest
  @filter = filter
  @session = nil

  @tracing_level = [0]
  # Set up TracePoint to automatically trace method calls within this box
  @tracer = TracePoint.new(:call, :return) do |tp|
    handle_trace_event(tp, @tracing_level, @inner_box)
  end
end

Instance Attribute Details

#inner_boxObject (readonly)

Returns the value of attribute inner_box.



40
41
42
# File 'lib/vivarium/box.rb', line 40

def inner_box
  @inner_box
end

#tracerObject (readonly)

Returns the value of attribute tracer.



40
41
42
# File 'lib/vivarium/box.rb', line 40

def tracer
  @tracer
end

Instance Method Details

#const_missing(name) ⇒ Object

Intercept constant access to resolve from the box’s evaluated context



82
83
84
85
86
# File 'lib/vivarium/box.rb', line 82

def const_missing(name)
  @inner_box.const_get(name)
rescue NameError => e
  raise NameError, "#{name} not found in box: #{e.message}"
end

#done_load!Object



88
89
90
# File 'lib/vivarium/box.rb', line 88

def done_load!
  @tracer.enable
end

#eval(code) ⇒ Object

Evaluate code within the box context



43
44
45
46
47
48
49
# File 'lib/vivarium/box.rb', line 43

def eval(code)
  result = nil
  Vivarium.observe(filter: @filter) do
    result = @inner_box.eval(code)
  end
  result
end

#load(path, wrap = false) ⇒ Object

Load a file within the box context (executed every time, unlike require) Automatically traced if Vivarium.observe is active



73
74
75
76
77
78
79
# File 'lib/vivarium/box.rb', line 73

def load(path, wrap = false)
  result = nil
  Vivarium.observe(filter: @filter) do
    result = @inner_box.load(path, wrap)
  end
  result
end

#require(path) ⇒ Object

Require a file within the box context Automatically traced if Vivarium.observe is active



53
54
55
56
57
58
59
# File 'lib/vivarium/box.rb', line 53

def require(path)
  result = nil
  Vivarium.observe(filter: @filter) do
    result = @inner_box.require(path)
  end
  result
end

#require_relative(path) ⇒ Object

Require a file relative to the current file within the box context Automatically traced if Vivarium.observe is active



63
64
65
66
67
68
69
# File 'lib/vivarium/box.rb', line 63

def require_relative(path)
  result = nil
  Vivarium.observe(filter: @filter) do
    result = @inner_box.require_relative(path)
  end
  result
end