Class: HeapInfo::Dumper

Inherits:
Object
  • Object
show all
Defined in:
lib/heapinfo/dumper.rb

Overview

Class for memory dump relation works

Constant Summary collapse

DUMP_BYTES =

Default dump length

8

Instance Method Summary collapse

Constructor Details

#initialize(mem_filename, &block) ⇒ Dumper

Instantiate a HeapInfo::Dumper object


13
14
15
16
17
# File 'lib/heapinfo/dumper.rb', line 13

def initialize(mem_filename, &block)
  @filename = mem_filename
  @info = block || ->(*) { HeapInfo::Nil.new }
  need_permission unless dumpable?
end

Instance Method Details

#dump(*args) ⇒ String?

A helper for Process to dump memory.

Examples:

p dump(:elf, 4)
#=> "\x7fELF"

25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/heapinfo/dumper.rb', line 25

def dump(*args)
  return need_permission unless dumpable?
  base, len = base_len_of(*args)
  file = mem_f
  file.pos = base
  mem = file.readpartial len
  file.close
  mem
rescue => e # rubocop:disable Style/RescueStandardError
  raise e if e.is_a? ArgumentError
  nil
end

#dump_chunks(*args) ⇒ HeapInfo::Chunks

Return the dump result as chunks. see Chunks and Chunk for more information.

Note: Same as #dump, need permission of attaching another process.


44
45
46
47
# File 'lib/heapinfo/dumper.rb', line 44

def dump_chunks(*args)
  base = base_of(*args)
  dump(*args).to_chunks(bits: @info[:bits], base: base)
end

#find(pattern, from, length, rel) ⇒ Integer?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Search a specific value/string/regexp in memory. #find only return the first matched address.

Examples:

find(/E.F/, :elf, false)
#=> 4194305
find(0x4141414141414141, 'heap+0x10', 0x1000, false)
#=> 6291472
find('/bin/sh', :libc, true)
#=> 1622391 # 0x18c177

89
90
91
92
93
94
95
96
97
98
99
# File 'lib/heapinfo/dumper.rb', line 89

def find(pattern, from, length, rel)
  from = base_of(from)
  length = 1 << 40 if length.is_a? Symbol
  ret = case pattern
        when Integer then find_integer(pattern, from, length)
        when String then find_string(pattern, from, length)
        when Regexp then find_regexp(pattern, from, length)
        end
  ret -= from if ret && rel
  ret
end

#x(count, address) ⇒ void

This method returns an undefined value.

Show dump results like in gdb's command x.

Details are in Process#x.

Examples:

x 3, 0x400000
# 0x400000:       0x00010102464c457f      0x0000000000000000
# 0x400010:       0x00000001003e0002

59
60
61
62
63
64
65
66
67
68
# File 'lib/heapinfo/dumper.rb', line 59

def x(count, address)
  commands = [address, count * size_t]
  base = base_of(*commands)
  res = dump(*commands).unpack(size_t == 4 ? 'L*' : 'Q*')
  str = res.group_by.with_index { |_, i| i / (16 / size_t) }.map do |round, values|
    Helper.hex(base + round * 16) + ":\t" +
      values.map { |v| Helper.color(format("0x%0#{size_t * 2}x", v)) }.join("\t")
  end.join("\n")
  puts str
end