Created
July 15, 2020 19:26
-
-
Save DavidEichmann/28822a8e580a26e12481bfa0c954b169 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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