Currently, type members, enumerators, and parameters are all represented
by tuples in the Python bindings. This is awkward to document and
implement. Instead, let's replace these tuples with proper types,
starting with the easiest one, TypeEnumerator. This one still makes
sense to treat as a sequence so that it can be unpacked as (name,
value).
It makes more sense semantically for __all__ to be immutable (except for
drgn.helpers.linux.__all__, which is built dynamically). While we're
here, sort the names, too.
Currently, we print:
>>> prog.symbol(prog['init_task'])
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: cannot convert 'struct task_struct' to index
It's not obvious what it means to convert to an index. Instead, let's
use the error message raised by operator.index():
TypeError: 'struct task_struct' object cannot be interpreted as an integer
v5.6-rc1 was released today, and 5.3 was recently EOL'd. (It might be
worthwhile to continue testing EOL kernels, but for now I don't want
Travis runs to take forever).
Decouple some of the responsibilities of FaultError to
OutOfBoundsError so consumers can differentiate between
invalid memory accesses and running out of bounds in
drgn Objects which may be based on valid memory address.
According to PEP 440, developmental releases sort before their
corresponding final release. We want them to sort after the release, as
they are a previous release plus some number of commits. Move the commit
count to the local version, as well.
The "my_" prefix shows up as the command name in --help, which is a bit
confusing. Do what setuptools does and import the original command under
another name so the custom class can have the original name.
Add example to print basic info about bpf programs and maps (id, type,
name).
Example output:
# python36 -m drgn examples/linux/bpf.py
Usage: examples/linux/bpf.py { prog | map }
# python36 -m drgn examples/linux/bpf.py p | head
9: BPF_PROG_TYPE_CGROUP_SKB name
10: BPF_PROG_TYPE_CGROUP_SKB name
23368: BPF_PROG_TYPE_CGROUP_SOCK_ADDR name tw_ipt_bind
23369: BPF_PROG_TYPE_CGROUP_SOCK_ADDR name tw_ipt_connect
23370: BPF_PROG_TYPE_SOCK_OPS name tw_ipt_listen
23371: BPF_PROG_TYPE_CGROUP_SOCK_ADDR name tw_ipt_sendmsg
59538: BPF_PROG_TYPE_CGROUP_SYSCTL name tw_sysctl
97104: BPF_PROG_TYPE_SCHED_CLS name fbflow_egress
97105: BPF_PROG_TYPE_SCHED_CLS name fbflow_ingress
97106: BPF_PROG_TYPE_KPROBE name fbflow_tcp_conn
# python36 -m drgn examples/linux/bpf.py m | head
8: BPF_MAP_TYPE_LPM_TRIE name
9: BPF_MAP_TYPE_LPM_TRIE name
12: BPF_MAP_TYPE_PERCPU_ARRAY name fbflow_pkt_info
16305: BPF_MAP_TYPE_ARRAY name tw_ipt_cfg
16306: BPF_MAP_TYPE_ARRAY name tw_tcp_ports_ma
16307: BPF_MAP_TYPE_LRU_HASH name tw_ipt_lo_sk
42606: BPF_MAP_TYPE_HASH name tw_sysctl_ro
55338: BPF_MAP_TYPE_HASH name hash_min
55341: BPF_MAP_TYPE_HASH name hash_8k_1
55342: BPF_MAP_TYPE_HASH name hash_8k_8
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Add helpers to iterate over bpf programs and maps.
The map iteration code was used in debugging real-world problem that
turned out to be a kernel bug in memlock accounting in perf. Saving it
as helpers to use in future investigations.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
At Facebook, we link OpenMP code with libomp instead of libgomp. We have
an internal patch to drgn to do this, as it can't be done by setting
CFLAGS/LDFLAGS. Let's add a way to specify the OpenMP library at
configure time so that we can drop the internal patch.
This breaks autodoc on Read the Docs because it builds the documentation
without creating the distribution. I have something in the works to stop
using autodoc, but for now, we can just get the version in the CLI code.
When investigating a reported bug, it's important to know which exact
version of drgn is being used. Let's include the git revision in the
version printed by the CLI in PEP440 format. This commit will also serve
as the 0.0.1 release.
The next change will make non-git builds depend on a fully-formed source
distribution. So, let's copy in everything from SOURCES.txt, which
should include the egg metadata and anything else setuptools decides is
important.
Support additional argument `bpf` in `cgroup.py` that, if specified,
prints only cgroups with attached BPF programs in a way similar to
`bpftool cgroup tree`. W/o the `bpf` argument the tool works as before.
For example:
# python36 -m drgn examples/linux/cgroup.py /sys/fs/cgroup/workload.slice/ bpf
/workload.slice
98761 BPF_CGROUP_SOCK_OPS 2 ned_cgrp_dctcp
/workload.slice/workload-tw.slice/nc_0.58_dev082.prn2_598fe2e810bc4_2.task
93488 BPF_CGROUP_INET_INGRESS 0 tw_ingress
93487 BPF_CGROUP_INET_EGRESS 0 tw_egress
93482 BPF_CGROUP_SOCK_OPS 2 tw_ipt_listen
93480 BPF_CGROUP_INET6_BIND 0 tw_ipt_bind
93481 BPF_CGROUP_INET6_CONNECT 0 tw_ipt_connect
93483 BPF_CGROUP_UDP6_SENDMSG 0 tw_ipt_sendmsg
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Add a new module `bpf` and a bunch of cgroup-bpf helpers. More bpf
helpers can be added in the future (e.g. iterate over all programs,
maps, etc).
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Add simple example to traverse cgroup v2 hierarchy.
It can be run w/o arguments and in this case root cgroup will be used:
# python36 -m drgn examples/linux/cgroup.py | wc -l
1081
# python36 -m drgn examples/linux/cgroup.py | shuf -n 3
/system.slice/nfs-idmapd.service
/user.slice/user-0.slice/user@0.service/dev-hugepages.mount
/system.slice/crond.service
Or a path in cgroup v2 filesystem can be specified to limit the
traversal by this path:
# python36 -m drgn examples/linux/cgroup.py /sys/fs/cgroup/www.slice
/www.slice
/www.slice/hack.service
/www.slice/flow.service
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Add helpers to iterate over all children and all descendants (pre-order
walk only) of a cgroup given its css.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
After thinking about this some more, I decided that although it makes
sense for scripts to convert a type to an IntEnum class, I'd prefer that
the helpers take and return drgn Objects rather than these classes.
We have a few use cases for converting a drgn.Type to a Python
enum.IntEnum (if I recall correctly, the original Python version of drgn
even did this automatically for enumerated types). Add an
enum_type_to_class() helper which does this conversion.
To make the previous reformatting commit less annoying, add a file
containing the commits to ignore in git blame. To use it, run `git blame
--ignore-revs-file .git-blame-ignore-revs` or `git config
blame.ignoreRevsFile .git-blame-ignore-revs`.
drgn.helpers has a couple of undocumented generic helpers. We might as
well document them. They're using type hints, so we need to use a sphinx
extension that strips the type hints out of the signature and adds them
to the documentation. We can also do the same for execscript().
Hopefully it can be used for the C extension documentation in the
future, too.
In order to make builds slightly more reproducible (and avoid leaking
details about the build machine's directory layout), let's remap the
compilation directory in DW_AT_comp_dir to be empty.
Currently the drgn version number is defined in drgn.h.in, and configure
and setup.py both parse it out of there. However, now that we're
generating drgn.h anyways, it's easier to make configure.ac the source
of truth.