class HeapInfo::Arena

Records status of an arena, including bin(s) and top chunk.

Attributes

fastbin[R]

@return [Array<HeapInfo::Fastbin>] Fastbins in an array.

last_remainder[R]

@return [HeapInfo::Chunk] Current last remainder.

size_t[R]
smallbin[R]

@return [Array<HeapInfo::Smallbin>] Smallbins in an array.

system_mem[R]

@return [Integer] The system_mem in arena.

top_chunk[R]

@return [HeapInfo::Chunk] Current top chunk.

unsorted_bin[R]

@return [Array<HeapInfo::UnsortedBin>] The unsorted bin (array size will always be one).

Public Class Methods

new(base, size_t, dumper) click to toggle source

Instantiate a {HeapInfo::Arena} object.

@param [Integer] base Base address of arena. @param [Integer] size_t Either 8 or 4. @param [Proc] dumper For dumping more data.

# File lib/heapinfo/arena.rb, line 26
def initialize(base, size_t, dumper)
  @base = base
  @size_t = size_t
  @dumper = dumper
  reload!
end

Public Instance Methods

layouts(*args) click to toggle source

Pretty dump of bins layouts.

@param [Symbol] args Bin type(s) you want to see. @return [String] Bin layouts that wrapper with color codes. @example

puts h.libc.main_arena.layouts(:fast, :unsorted, :small)
puts h.libc.main_arena.layouts(:all)
# File lib/heapinfo/arena.rb, line 64
def layouts(*args)
  args.concat(%i[fast unsort small large]) if args.map(&:to_s).include?('all')
  args = args.map(&:to_s).join('|')
  res = ''
  res += fastbin.map(&:inspect).join if args.include?('fast')
  res += unsorted_bin.inspect if args.include?('unsort')
  res += smallbin.map(&:inspect).join if args.include?('small')
  res
end
reload!() click to toggle source

Refresh all attributes. Retrive data using +@dumper+, load bins, top chunk etc. @return [HeapInfo::Arena] self

# File lib/heapinfo/arena.rb, line 36
def reload!
  top_ptr_offset = @base + 8 + size_t * 10
  top_ptr = Helper.unpack(size_t, @dumper.call(top_ptr_offset, size_t))
  @fastbin = []
  return self if top_ptr.zero? # arena not init yet
  @top_chunk = Chunk.new(size_t, top_ptr, @dumper)
  @last_remainder = Chunk.new(size_t, top_ptr_offset + 8, @dumper)
  # this offset diff after 2.23
  @system_mem = Array.new(2) do |off|
    Helper.unpack(size_t, @dumper.call(top_ptr_offset + 258 * size_t + 16 + off * size_t, size_t))
  end.find { |val| val >= 0x21000 && (val & 0xfff).zero? }
  @fastbin = Array.new(7) do |idx|
    Fastbin.new(size_t, @base + 8 - size_t * 2 + size_t * idx, @dumper, head: true).tap { |f| f.index = idx }
  end
  @unsorted_bin = UnsortedBin.new(size_t, top_ptr_offset, @dumper, head: true)
  @smallbin = Array.new(62) do |idx|
    Smallbin.new(size_t, @base + 8 + size_t * (12 + 2 * idx), @dumper, head: true).tap { |s| s.index = idx }
  end
  self
end