Rebase on master, add the improved
dwfl_frame_module/dwfl_frame_dwarf_frame patch, and add the
dwfl_frame_register patch.
Based on:
889edd912 PR25365: debuginfod-client: restrict cleanup to client-pattern files
With the following patches:
configure: Add --disable-programs
configure: Add --disable-shared
libdwfl: add interface for attaching to/detaching from threads
libdwfl: add interface for getting Dwfl_Module and Dwarf_Frame for Dwfl_Frame
libdwfl: export __libdwfl_frame_reg_get as dwfl_frame_register
libdwfl: add interface for evaluating DWARF expressions in a frame
UTS_RELEASE is currently only accessible once debug info is loaded with
prog.load_debug_info(main=True). This makes it difficult to get the
release, find the appropriate vmlinux, then load the found vmlinux. We
can add vmcoreinfo_object_find as part of set_core_dump(), which makes
it possible to do the following:
prog = drgn.Program()
prog.set_core_dump(core_dump_path)
release = prog['UTS_RELEASE'].string_()
vmlinux_path = find_vmlinux(release)
prog.load_debug_info([vmlinux_path])
The only downside is that this ends up using the default definition of
char rather than what we would get from the debug info, but that
shouldn't be a big problem.
The osrelease is accessible via init_uts_ns.name.release, but we can
also get it straight out of vmcoreinfo, which will be useful for the
next change. UTS_RELEASE is the name of the macro defined in the kernel.
This continues the conversion from the last commit. Members and
parameters are basically the same, so we can do them together. Unlike
enumerators, these don't make sense to unpack or access as sequences.
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`.