Skip to content

Instantly share code, notes, and snippets.

@DavidEichmann
Created July 15, 2020 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidEichmann/28822a8e580a26e12481bfa0c954b169 to your computer and use it in GitHub Desktop.
Save DavidEichmann/28822a8e580a26e12481bfa0c954b169 to your computer and use it in GitHub Desktop.
import typing
from typing import List, Optional, Tuple, TypeVar, Callable, NamedTuple, Set, Dict, Iterator, Any
from . import ghc_heap
from .types import *
from . import closure
from .utils import CommandWithArgs, get_num_generations
from .block import get_bdescr_val, format_bdescr, heap_start, heap_end, BlockFlags
from .mut_list import collect_mut_list
import gdb
def find_blocks(sampleFreq: int = 4000) -> Iterator[Any]:
for p in range(heap_start.addr(), heap_end.addr(), sampleFreq):
bdVal = get_bdescr_val(Ptr(p))
if bdVal is not None: # Block found
bd = bdVal.dereference()
start = int(bd['start'])
if start != 0: # Is a valid block. Filters out memory that has been zeroed out.
if int(bd['free']) != -1: # Is a live block. Filters out dead blocks.
yield bdVal
class DumpHeapCmd(CommandWithArgs):
""" Dump the heap """
command_name = "ghc dump"
def build_parser(self, parser):
pass
def run(self, opts, from_tty) -> None:
pass
class DumpBlocksCmd(CommandWithArgs):
""" Dump all heap blocks """
command_name = "ghc blocks"
def build_parser(self, parser):
parser.add_argument('-s', '--sample',
action='store', type=int, help='sample every <sample> bytes',
default=(4000))
parser.add_argument('-p', '--pinned',
action='store_true', help='Show only pinned and large object blocks',
default=False)
def run(self, opts, from_tty) -> None:
# try to sample the heap and find blocks are ?4000bytes? so sample more frequently than that.
count = 0
for bdVal in find_blocks(opts.sample):
bd = bdVal.dereference()
flags = int(bd['flags'])
# Check for pinned/large object if necessary.
if (not opts.pinned) or flags & (BlockFlags.BF_PINNED | BlockFlags.BF_LARGE):
print(format_bdescr(bdVal))
count += 1
print('Found %d blocks' % count)
DumpHeapCmd()
DumpBlocksCmd()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment