Black 21.4b2 now replaces empty docstrings with a docstring containing a
single space. Apply that formatting.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
FaultError() also takes an error message.
Fixes: 80c9fb35ff ("Add type hint stubs and generate documentation from them")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
I often use examples/load_debug_info to benchmark loading/DWARF
indexing, so add a -T option that prints the time it takes to load debug
info.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
When using type units, skeleton declarations are made instead of
concrete ones. However, these declarations have signature tags attached
that point to the type unit with the definition, so we can simply follow
the signature to get the concrete type.
Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
Adds support for parsing of type units as enabled by
-fdebug-types-section. If a module has both a debug info section and
type unit section, both are read.
Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
If the DIE passed to drgn_type_from_dwarf_internal() is a declaration,
then we overwrite it with dwarf_offdie(). As far as I can tell, this
doesn't break anything at the moment, but it's sketchy to overwrite an
input parameter and may cause issues in the future. Use a temporary DIE
on the stack in this case instead.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
CPython commit fb5db7ec5862 ("bpo-42006: Stop using PyDict_GetItem,
PyDict_GetItemString and _PyDict_GetItemId. (GH-22648)") (in v3.10)
removed _PyDict_GetItemId() because it suppresses errors. Use
_PyDict_GetItemIdWithError() instead (which we should've been using
anyways).
Closes#101.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Using a Python dictionary for this is much more heavyweight than just
using a thread-local variable (with no benefit as far as I can tell).
This also gets rid of a call to _PyDict_GetItem().
Signed-off-by: Omar Sandoval <osandov@osandov.com>
/proc/pid/mem is indexed by address. On 32-bit systems, addresses may be
out of the range of a 32-bit signed off_t. This results in pread()
returning EINVAL in drgn_read_memory_file(). Use AC_SYS_LARGEFILE in
configure.ac so that we use 64-bit off_t by default.
Closes#98.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
With the added Clang tests, apparently vmtest is generating excessive
traffic on Dropbox. Disable it on GitHub Actions until I can work out a
new solution.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
We don't actually want make clean to remove the generated files that are
included in a distribution tarball, because then the user will need to
regenerate them, and they might not have the dependencies installed.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Everytime I try to build drgn with Clang, there are a few things that
need fixing. Let's test it so that it stays in good shape.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
GCC doesn't warn about table##_delete_iterator() being unused because it
is inline, but Clang does, so add the unused attribute.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The folly implementation calls this elsewhere, but we only need it in
table##_chunk_mark_eof(), so it was folded in there.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Clang enables -Wgnu-variable-sized-type-not-at-end by default, which
warns for DRGN_CFI_ROW():
arch_x86_64.c:735:27: warning: field 'row' with variable sized type 'struct drgn_cfi_row' not at the end of a struct or class is a GNU extension
[-Wgnu-variable-sized-type-not-at-end]
.default_dwarf_cfi_row = DRGN_CFI_ROW(
DRGN_CFI_ROW() is gnarly anyways, so instead of having it expand to a
pointer expression relying on this GCC extension, make it expand to an
initializer. Then, we can initialize default_dwarf_cfi_row as a separate
variable rather than directly in the initializer for struct
drgn_architecture_info.
This still relies on a GCC extension for static initialization of
flexible array members, but apparently Clang is okay with that one by
default (-Wgnu-flexible-array-initializer must be enabled explictly or
by -Wgnu or -Wpedantic).
Signed-off-by: Omar Sandoval <osandov@osandov.com>
See commit 0cb77b303c ("libdrgn: work around Clang __muloti4 again")
and commit 2dd14ad522 ("libdrgn: work around "undefined reference to
'__muloti4'" when using Clang"). These keep sneaking in because I don't
have an old enough version of Clang lying around.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
There are a couple of places where we compute `NULL + 0`, which is
undefined behavior. Add a helper to do this safely.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
drgn_object_reinit() and drgn_object_copy() can both load from an
uninitialized little_endian field, causing UBSan errors like:
libdrgn/object.h:105:27: runtime error: load of value 68, which is not a valid value for type '_Bool'
This only happens when little_endian isn't valid for the type and won't
be used anyways, but it's easy enough to work around.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
It's undefined behavior to pass NULL to memcpy() even if the length is
zero. See also commit a17215e984 ("libdrgn: dwarf_index: fix memcpy()
undefined behavior").
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Building drgn from an sdist currently requires autotools and gawk
because libdrgn in the sdist is more or less a git checkout. It's more
user-friendly to include the autotools output and generated code. Do
this by extending the sdist command to include a full libdrgn
distribution with `make distdir`.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The README instructs the user to install with pip, but doesn't actually
mention that pip needs to be installed.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The libelf-dev and libdw-dev packages on Debian Stretch, Ubuntu Xenial,
and older are missing dependencies on liblzma-dev and zlib1g-dev, which
causes pkg-config to fail when running configure. Add them explicitly
for old versions.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The Linux kernel has its own stack unwinding format for x86-64 called
ORC: https://www.kernel.org/doc/html/latest/x86/orc-unwinder.html. It is
essentially a simplified, less complete version of DWARF CFI. ORC is
generated by analyzing machine code, so it is present for all but a few
ignored functions. In contrast, DWARF CFI is generated by the compiler
and is therefore missing for functions written in assembly and inline
assembly (which is widespread in the kernel).
This implements an ORC stack unwinder: it applies ELF relocations to the
ORC sections, adds a new DRGN_CFI_RULE_REGISTER_ADD_OFFSET CFI rule
kind, parses and efficiently stores ORC data, and translates ORC to drgn
CFI rules. This will allow us to stack trace through assembly code,
interrupts, and system calls.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
To support unwinding with ORC, we need to apply relocations to
.orc_unwind_ip, which libdwfl doesn't do. That means that we always need
to apply relocations on x86-64, not just as a fast path when the file's
byte order matches the host's. So, generalize handling of 64- vs 32-bit
and little- vs big-endian relocations, and move the handling of
relocation types to an arch-specific callback.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Linux kernel modules usually contain ELF relocations in DWARF and ORC
sections for symbols in .init sections. Since we ignore .init sections
entirely in cache_kernel_module_sections(), these relocations end up
being based on an address of 0 (so, e.g., a function from .init.text
could be reported as having an address of 0x0). It makes a little more
sense to use the address where the .init section was before it was
freed. So, let's update the sections' sh_addr but continue ignoring them
for determining the module's address range.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Split the two modes into separate tests and move the environment
variable fiddling into a separate helper function.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The oldest LTS version of Ubuntu, 16.04, has elfutils 0.165. This
version is missing some ELF and DWARF definitions used by drgn. Add
copies of elf.h from glibc 2.33 and dwarf.h and elfutils/known-dwarf.h
from elfutils 0.183 to get the latest definitions and drop the minimum
required version of elfutils further to 0.165.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Currently libdrgn requires libelf to be of version 0.175 or
later. This patch allows the library to be compiled with libelf
0.170 (the newest version supported by Ubuntu 18.04 LTS).
Signed-off-by: Serapheim Dimitropoulos <serapheim@delphix.com>
If a member is a bit field, then we should format it with the underlying
Object so that it shows the bit field size.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
There's no reason to use GCC's zero-length array extension for this. Use
a standard flexible array instead.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
I missed this when I removed the code that used it.
Fixes: eec67768aa ("libdrgn: replace elfutils DWARF unwinder with our own")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
We currently bundle a version of elfutils with patches to export
additional stack tracing functionality. This has a few drawbacks:
- Most of drgn's build time is actually building elfutils.
- Distributions don't like packages that bundle verions of other
packages.
- elfutils, and thus drgn, can't be built with clang.
Now that we've replaced the elfutils DWARF unwinder with our own, we
don't need the patches, so we can drop the bundled elfutils and fix
these issues.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The elfutils DWARF unwinder has a couple of limitations:
1. libdwfl doesn't have an interface for getting register values, so we
have to bundle a patched version of elfutils with drgn.
2. Error handling is very awkward: dwfl_getthread_frames() can return an
error even on success, so we have to squirrel away our own errors in
the callback.
Furthermore, there are a couple of things that will be easier with our
own unwinder:
1. Integrating unwinding using ORC will be easier when we're handling
unwinding ourselves.
2. Support for local variables isn't too far away now that we have DWARF
expression evaluation.
Now that we have the register state, CFI, and DWARF expression pieces in
place, stitch them together with the new unwinder, and tweak the public
API a bit to reflect it.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
For DW_CFA_def_cfa_expression, DW_CFA_expression, and
DW_CFA_val_expression, we need to be evaluate a DWARF expression. Add an
interface for this. It doesn't yet support operations that aren't
applicable to CFI or some more exotic operations.
Signed-off-by: Omar Sandoval <osandov@osandov.com>