Class: HeapInfo::ProcessInfo

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

Overview

For Process to record basic process information.

Process has a process_info object iff the process exists (pid not nil). Mainly records segments' base.

Constant Summary collapse

EXPORT =

Methods to be transparent to process. e.g. process.libc alias to process.info.libc.

%i[libc ld heap program elf stack bits auxv].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(process) ⇒ ProcessInfo

Instantiate a HeapInfo::ProcessInfo object.

Parameters:


33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/heapinfo/process_info.rb', line 33

def initialize(process)
  @pid = process.pid
  options = process.instance_variable_get(:@options)
  maps = load_maps
  @bits = bits_of(Helper.exe_of(@pid))
  @program = Segment.find(maps, File.readlink("/proc/#{@pid}/exe"))
  # well.. stack is a strange case because it will grow in runtime..
  # should i detect stack base growing..?
  @stack = Segment.find(maps, '[stack]')
  @auxv = parse_auxv(Helper.auxv_of(@pid))
  ld_seg = maps.find { |m| m[0] == @auxv[:ld_base] } # nil if static-linked elf
  @ld = ld_seg.nil? ? Nil.new : Segment.new(@auxv[:ld_base], ld_seg.last)
  @libc = Libc.find(maps, match_maps(maps, options[:libc]), @bits, @ld.name, ->(*args) { process.dump(*args) })
end

Instance Attribute Details

#auxvHash{Symbol => Integer} (readonly)

Returns The parsed auxv hash.

Examples:

auxv
#=> {:ld_base => 4152033280, :random => 4294374299}

Returns:

  • (Hash{Symbol => Integer})

    The parsed auxv hash.


27
28
29
# File 'lib/heapinfo/process_info.rb', line 27

def auxv
  @auxv
end

#bitsInteger (readonly)

Returns 32 or 64.

Returns:

  • (Integer)

    32 or 64.


14
15
16
# File 'lib/heapinfo/process_info.rb', line 14

def bits
  @bits
end

#ldHeapInfo::Segment (readonly)

Returns:


22
23
24
# File 'lib/heapinfo/process_info.rb', line 22

def ld
  @ld
end

#libcHeapInfo::Libc (readonly)

Returns:


20
21
22
# File 'lib/heapinfo/process_info.rb', line 20

def libc
  @libc
end

#programHeapInfo::Segment (readonly) Also known as: elf

Returns:


16
17
18
# File 'lib/heapinfo/process_info.rb', line 16

def program
  @program
end

#stackHeapInfo::Segment (readonly)

Returns:


18
19
20
# File 'lib/heapinfo/process_info.rb', line 18

def stack
  @stack
end

Instance Method Details

#heapHeapInfo::Segment

Heap will not be mmapped if the process not use heap yet, so create a lazy loading method. Will re-read maps when heap segment not found yet.

Special handling here because heap might not be initialized in the beginning.

Returns:


54
55
56
# File 'lib/heapinfo/process_info.rb', line 54

def heap
  @heap ||= Segment.find(load_maps, '[heap]')
end

#segmentsHash{Symbol => Segment}

Return segemnts load currently.

Returns:

  • (Hash{Symbol => Segment})

    The segments in hash format.


60
61
62
63
64
65
# File 'lib/heapinfo/process_info.rb', line 60

def segments
  EXPORT.map do |sym|
    seg = __send__(sym)
    [sym, seg] if seg.is_a?(Segment)
  end.compact.to_h
end