For types obtained from DWARF, we determine it from the language of the
CU. For other types, it can be specified manually or fall back to the
default (C). Then, we can use the language for operations where the type
is available.
This way, languages can be identified by an index, which will be useful
for adding Python bindings for drgn_language and for adding a language
field to drgn_type.
While we're here, make generate_dwarf_constants.py use the bundled
dwarf.h, generate code that black is happy with, and use the keyword
list from the standard library.
String annotations (i.e., forward references) need to be parsed into an
ast node. Do it as a transformation step immediately after parsing the
source. We can also squash the constant node transformation into this
one.
I've been wanting to add type hints for the _drgn C extension for
awhile. The main blocker was that there is a large overlap between the
documentation (in docs/api_reference.rst) and the stub file, and I
really didn't want to duplicate the information. Therefore, it was a
requirement that the the documentation could be generated from the stub
file, or vice versa. Unfortunately, none of the existing tools that I
could find supported this very well. So, I bit the bullet and wrote my
own Sphinx extension that uses the stub file as the source of truth (and
subsumes my old autopackage extension and gen_docstrings script).
The stub file is probably incomplete/inaccurate in places, but this
should be a good starting point to improve on.
Closes#22.
I thought I'd be able to avoid adding a separate API for register values
and reuse dwfl_frame_eval_expr(), but this doesn't work if the frame is
missing debug information but has known register values (e.g., if the
program crashed with an invalid instruction pointer).
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.