Class: RubyMemcheck::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_memcheck/configuration.rb

Constant Summary collapse

DEFAULT_VALGRIND =
"valgrind"
DEFAULT_VALGRIND_OPTIONS =
[
  "--num-callers=50",
  "--error-limit=no",
  "--trace-children=yes",
  "--undef-value-errors=no",
  "--leak-check=full",
  "--show-leak-kinds=definite",
].freeze
DEFAULT_VALGRIND_SUPPRESSIONS_DIR =
"suppressions"
DEFAULT_SKIPPED_RUBY_FUNCTIONS =
[
  /\Aeval_string_with_cref\z/,
  /\Arb_add_method_cfunc\z/,
  /\Arb_check_funcall/,
  /\Arb_class_boot\z/, # Called for all the different ways to create a Class
  /\Arb_enc_raise\z/,
  /\Arb_exc_raise\z/,
  /\Arb_extend_object\z/,
  /\Arb_funcall/,
  /\Arb_intern/,
  /\Arb_ivar_set\z/,
  /\Arb_module_new\z/,
  /\Arb_raise\z/,
  /\Arb_rescue/,
  /\Arb_respond_to\z/,
  /\Arb_thread_create\z/, # Threads are relased to a cache, so they may be reported as a leak
  /\Arb_yield/,
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(binary_name:, ruby: FileUtils::RUBY, valgrind: DEFAULT_VALGRIND, valgrind_options: DEFAULT_VALGRIND_OPTIONS, valgrind_suppressions_dir: DEFAULT_VALGRIND_SUPPRESSIONS_DIR, valgrind_generate_suppressions: false, skipped_ruby_functions: DEFAULT_SKIPPED_RUBY_FUNCTIONS, valgrind_xml_dir: Dir.mktmpdir, output_io: $stderr) ⇒ Configuration

Returns a new instance of Configuration.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/ruby_memcheck/configuration.rb', line 38

def initialize(
  binary_name:,
  ruby: FileUtils::RUBY,
  valgrind: DEFAULT_VALGRIND,
  valgrind_options: DEFAULT_VALGRIND_OPTIONS,
  valgrind_suppressions_dir: DEFAULT_VALGRIND_SUPPRESSIONS_DIR,
  valgrind_generate_suppressions: false,
  skipped_ruby_functions: DEFAULT_SKIPPED_RUBY_FUNCTIONS,
  valgrind_xml_dir: Dir.mktmpdir,
  output_io: $stderr
)
  @binary_name = binary_name
  @ruby = ruby
  @valgrind = valgrind
  @valgrind_options = valgrind_options
  @valgrind_suppressions_dir = File.expand_path(valgrind_suppressions_dir)
  @valgrind_generate_suppressions = valgrind_generate_suppressions
  @skipped_ruby_functions = skipped_ruby_functions
  @output_io = output_io

  if valgrind_xml_dir
    valgrind_xml_dir = File.expand_path(valgrind_xml_dir)
    FileUtils.mkdir_p(valgrind_xml_dir)
    @valgrind_xml_dir = valgrind_xml_dir
    @valgrind_options += [
      "--xml=yes",
      # %p will be replaced with the PID
      # This prevents forking and shelling out from generating a corrupted XML
      # See --log-file from https://valgrind.org/docs/manual/manual-core.html
      "--xml-file=#{File.join(valgrind_xml_dir, "%p.out")}",
    ]
  end
end

Instance Attribute Details

#binary_nameObject (readonly)

Returns the value of attribute binary_name.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def binary_name
  @binary_name
end

#output_ioObject (readonly)

Returns the value of attribute output_io.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def output_io
  @output_io
end

#rubyObject (readonly)

Returns the value of attribute ruby.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def ruby
  @ruby
end

#skipped_ruby_functionsObject (readonly)

Returns the value of attribute skipped_ruby_functions.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def skipped_ruby_functions
  @skipped_ruby_functions
end

#valgrindObject (readonly)

Returns the value of attribute valgrind.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def valgrind
  @valgrind
end

#valgrind_generate_suppressionsObject (readonly) Also known as: valgrind_generate_suppressions?

Returns the value of attribute valgrind_generate_suppressions.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def valgrind_generate_suppressions
  @valgrind_generate_suppressions
end

#valgrind_optionsObject (readonly)

Returns the value of attribute valgrind_options.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def valgrind_options
  @valgrind_options
end

#valgrind_suppressions_dirObject (readonly)

Returns the value of attribute valgrind_suppressions_dir.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def valgrind_suppressions_dir
  @valgrind_suppressions_dir
end

#valgrind_xml_dirObject (readonly)

Returns the value of attribute valgrind_xml_dir.



34
35
36
# File 'lib/ruby_memcheck/configuration.rb', line 34

def valgrind_xml_dir
  @valgrind_xml_dir
end

Instance Method Details

#command(*args) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ruby_memcheck/configuration.rb', line 72

def command(*args)
  [
    # On some Rubies, not setting the stack size to be ulimited causes
    # Valgrind to report the following error:
    #   Invalid write of size 1
    #     reserve_stack (thread_pthread.c:845)
    #     ruby_init_stack (thread_pthread.c:871)
    #     main (main.c:48)
    "ulimit -s unlimited && ",
    valgrind,
    valgrind_options,
    get_valgrind_suppression_files(valgrind_suppressions_dir).map { |f| "--suppressions=#{f}" },
    valgrind_generate_suppressions ? "--gen-suppressions=all" : "",
    ruby,
    args,
  ].flatten.join(" ")
end