...
 
Commits (4)
......@@ -58,8 +58,8 @@ with nixpkgs; rec {
src = fetchFromGitHub {
owner = "mozilla";
repo = "rr";
rev = "47f13a8ce92fd1dfba45bd4f9faed8f0b202f4ee";
sha256 = "1x6l1xsdksnhz9v50p4r7hhmr077cq20kaywqy1jzdklvkjqzf64";
rev = "42bf5814f990fca61c743013041d02a84d383926";
sha256 = "0pqlcwy9smdjcmfghqlm8zp5p8rnsxa6xl2pr3a8x7bzgs9471ri";
};
});
......
......@@ -3,30 +3,19 @@ from enum import IntFlag
from typing import Optional, Any
from .utils import CommandWithArgs
from .types import *
from .ghc_heap import heap_alloced
Bdescr = gdb.lookup_type('bdescr')
BdescrPtr = Bdescr.pointer()
# This is a terrible hack but it's better than searching through 1TB of address space.
# Unfortunately while gdb's `find` command seems to be smart enough to only search
# mapped memory, the same can't be said of Python's search_memory.
heap_start = Ptr(0x4200000000)
heap_end = Ptr(0x4210000000)
def block_chain_elems(bd):
assert bd.type == BdescrPtr
while int(bd) != 0:
yield bd
bd = bd['link']
def is_heap_alloced(ptr: Ptr):
return heap_start <= ptr and ptr < heap_end
#return gdb.parse_and_eval('HEAP_ALLOCED(%d)' % ptr.addr)
def get_bdescr(ptr: Ptr) -> Optional[Any]:
if ptr < heap_start: return None # XXX
if is_heap_alloced(ptr):
if heap_alloced(ptr):
try:
# _bdescr is only provided by the debug RTS
return gdb.parse_and_eval('_bdescr(%d)' % ptr.addr()).dereference()
......
......@@ -4,7 +4,8 @@ from . import ghc_heap
from .types import *
from . import closure
from .utils import CommandWithArgs, get_num_generations
from .block import get_bdescr, heap_start, heap_end
from .block import get_bdescr
from .ghc_heap import heap_alloced, heap_bounds
from .mut_list import collect_mut_list
import gdb
......@@ -59,6 +60,7 @@ def find_refs(closure_ptr: Ptr, include_static=True) -> Iterator[Ptr]:
""" Find all references to a closure. """
inf = gdb.selected_inferior()
closure_ptr = closure_ptr.untagged()
heap_start, heap_end = heap_bounds()
for tag in range(0,7):
val = closure_ptr.tagged(tag).pack() # type: bytes
......@@ -205,7 +207,8 @@ def refs_dot(edges: List[Edge], roots: Set[Ptr], mut_list_reachables: Dict[int,
seg_blkIdx = get_nonmoving_segment(ref.referring_field)
if seg_blkIdx is not None:
seg, blk = seg_blkIdx
snap = int(seg['next_free_snap'])
#snap = int(seg['next_free_snap'])
snap = 0
mark = seg['bitmap'][blk]
if mark != 0:
color = 'blue'
......
import gdb
import gdb.printing
from typing import Tuple
from collections import namedtuple
import traceback
from .types import Ptr
from .pretty import *
from .closure import ClosureType
from .utils import CommandWithArgs
from .utils import CommandWithArgs, memoized
bits = 64
showSpAddrs = False
......@@ -195,10 +197,17 @@ def build_closure_printers():
closurePrinters = build_closure_printers()
closureTypeDict = { v: str(ty) for ty, v in ClosureType.__dict__.items() }
@memoized
def heap_bounds() -> Tuple[Ptr, Ptr]:
aspace = gdb.parse_and_eval('mblock_address_space')
begin = Ptr(aspace['begin'])
end = Ptr(aspace['end'])
return (begin, end)
def heap_alloced(ptr):
w = ptr.cast(StgWord)
aspace = gdb.parse_and_eval('mblock_address_space')
return (w >= aspace['begin']) and (w < aspace['end'])
begin, end = heap_bounds()
return (w >= begin) and (w < end)
def print_addr(ptr):
ptr = ptr.cast(StgPtr)
......
import gdb
from typeable import TypeVar, Callable
class CommandWithArgs(gdb.Command):
def __init__(self):
......@@ -31,3 +32,15 @@ def get_num_capabilities():
def get_num_generations():
return int(gdb.parse_and_eval('RtsFlags.GcFlags.generations'))
A = TypeVar('A')
def memoized(f: Callable[A]) -> Callable[A]:
""" a decorator to memoize a nullary function """
f._cache = None
def g():
if f._cache is None:
f._cache = f()
return f._cache
return g
......@@ -2,31 +2,35 @@
set -e
args=
if [ "$1" = "-e" ]; then
emacs=1
out=TAGS
ctags=etags
else
out=tags
ctags=etags
fi
build_tags() {
local args
if [ -n "$emacs" ]; then args="-e"; fi
d=$1
if [ -d $d ]; then
echo "generating tags for $d..."
pushd $d
hasktags -x -o TAGS -e .
popd
args="$args --include $d/TAGS"
#hasktags -x --append -o $out $HASKTAGS_FLAGS $args $d
fasttags -x --append -o $out $HASKTAGS_FLAGS $args $d
fi
}
rm -f TAGS
rm -f $out
build_tags compiler
build_tags ghc
build_tags libraries/base
build_tags libraries/ghc-boot
build_tags libraries/ghc-prim
build_tags libraries/ghci
build_tags libraries/hoopl
build_tags iserv
#build_tags ghc
#build_tags libraries/base
#build_tags libraries/ghc-boot
#build_tags libraries/ghc-prim
#build_tags libraries/ghci
#build_tags libraries/hoopl
#build_tags iserv
pushd rts
etags $(find -iname '*.h') $(find -iname '*.c')
args="$args --include rts/TAGS"
popd
#$ctags --append -o $out $(find -iname '*.h') $(find -iname '*.c')
etags $args
......@@ -37,20 +37,24 @@ distros =
, fedora "28"
, fedora "29"
, fedora "30"
, fedora "31"
, fedora "32"
, centos "6"
, centos "7"
, centos "8"
, ubuntu "16.04" "xenial"
, ubuntu "18.04" "bionic"
, ubuntu "18.10" "cosmic"
, ubuntu "19.04" "disco"
, ubuntu "19.10" "eoan"
, ubuntu "20.04" "focal"
, debian "oldstable"
, debian "stable"
, debian "testing"
, debian "unstable"
-- , alpine
, alpine "3_11"
-- , freebsd "11"
]
where
......@@ -80,6 +84,12 @@ distros =
, distroSubRepo = SubRepoName $ ver <> "/main"
, distroLibc = Glibc
}
alpine ver =
Distro { distroName = "Alpine " <> ver
, distroRepo = RepoName $ "alpine_" <> ver
, distroSubRepo = SubRepoName "/main"
, distroLibc = Musl
}
truncateVersion :: Int -> Version -> Version
truncateVersion n (Version xs _) = Version (take n xs) []
......
......@@ -46,7 +46,7 @@ instance FromJSON Package where
Package <$> o .: "repo"
<*> o .:? "subrepo" .!= SubRepoName ""
<*> (parseVersion' =<< (o .: "version"))
<*> o .: "name"
<*> o .: "visiblename"
where
parseVersion' s
| (v, _) : _ <- sortBy (comparing $ length . snd) $ readP_to_S parseVersion s = pure v
......
......@@ -57,6 +57,8 @@ def list_submodules(repo: Path) -> List[Tuple[Path, str]]:
return result
def main() -> None:
diff = True
#subprocess.run(['git', 'submodule', 'foreach', 'git', 'remote', 'update', 'upstream'], check=True)
for path, rev in list_submodules('.'):
if path in non_released \
......@@ -71,6 +73,12 @@ def main() -> None:
version = f'version {version}' if version is not None else f'*todo* (on `{tag}`)'
))
if diff and not version:
real_tag = subprocess.check_output(['git', '-C', path, 'describe', '--abbrev=0', 'HEAD'], encoding='UTF-8').strip()
commit = subprocess.check_output(['git', '-C', path, 'rev-parse', 'HEAD'], encoding='UTF-8').strip()
print(f'# {real_tag}..{commit}')
subprocess.run(['git', '--no-pager', '-C', path, 'diff', '--stat', f'{real_tag}..HEAD'])
print()
if __name__ == '__main__':
main()
......@@ -31,11 +31,11 @@ Example:
import re
import sys
import ast
import json
import typing
def read_rts_stats(f: typing.TextIO) -> dict:
import ast
f.readline()
raw = ast.literal_eval(re.sub('^ +', '', f.read()))
parsed = { key: float(value) for key, value in raw }
......