Our internal Buck build of drgn doesn't use -I$(srcdir) like automake
does, so #include "drgn.h" and #include "symbol.h" in
libdrgn/python/symbol.c don't work. "drgn.h" is included by "drgnpy.h",
so we can drop that one and use a relative path for "symbol.h" instead.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
identify_address() won't find anything useful for a directly mapped
address for a page that is actually being used by vmap. There doesn't
seem to be a great way to translate a directly mapped address to a vmap
address other than walking every vmap area.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
This requires rearranging a couple of things: symbols from modules are
also vmap addresses, so we need to check for symbols first, and we need
to open-code slab_object_info to avoid some redundant operations.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
This is similar to print_annotated_stack() except that it works on an
arbitrary memory range. It's useful for trying to find some context in
mystery memory.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
pool_index in depot_stack_handle_t was changed to be offset by 1, which
broke stack_depot_fetch(). We can hack around it with trial and error.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
This reverts commit 07ae81df91. The build
should be fixed by Linux stable commit cc6ddd6fa93e ("x86/paravirt: Fix
build due to __text_gen_insn() backport") (in v5.10.214).
Signed-off-by: Omar Sandoval <osandov@osandov.com>
This is super useful as a last ditch effort to find what is referencing
a kernel object, for example.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
We currently only have one test resource file, sample.coredump.zst, but
the tests for #332 will add more. Create a package, tests.resources, to
contain test resources and a function, get_resource(), to decompress
them. It can also be used on the command line:
python3 -m tests.resources $resource_name
Signed-off-by: Omar Sandoval <osandov@osandov.com>
v6.5 moved irq descriptors into a maple tree,
earlier they used to exist in a radix tree.
Change contrib/irq.py to accomodate this change.
Signed-off-by: Imran Khan <imran.f.khan@oracle.com>
Specify a "fake" symbol finder and then test that its results are
plumbed through the API successfully. While this is a contrived test, it
helps build confidence in the plumbing of the API.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
Expose the Symbol finder API so that Python code can be used to lookup
additional symbols by name or address.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
Previously, Symbol objects could not be constructed in Python. However,
in order to allow Python Symbol finders, this needs to be changed.
Unfortunately, Symbol name lifetimes are tricky to manage. We introduce
a lifetime enumeration to handle this. The lifetime may be "static",
i.e. longer than the life of the program; "external", i.e. longer than
the life of the symbol, but no guarantees beyond that; or "owned", i.e.
owned by the Symbol itself.
Symbol objects constructed in Python are "external". The Symbol struct
owns the pointer to the drgn_symbol, and it holds a reference to the
Python object keeping the name valid (either the program, or a PyUnicode
object).
The added complexity is justified by the fact that most symbols are from
the ELF file, and thus share a lifetime with the Program. It would be a
waste to constantly strdup() these strings, just to support a small
number of Symbols created by Python code.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
Now that the symbol finder API is created, we can move the ELF symbol
implementation into the debug_info.c file, where it more logically
belongs. The only change to these functions in the move is to declare
elf_symbols_search as static.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
The drgn_program_find_symbol_by_address_internal() function is used when
libdrgn itself may want to lookup a symbol: in particular, when
formatting stack traces or objects. It does less work by possibly
already having a Dwfl_Module looked up, and by avoiding memory
allocation of a symbol, and it's more convenient because it doesn't
return any errors, including on lookup failure.
Unfortunately, the new symbol finder API breaks all of these properties:
the returned symbol is now allocated via malloc() which needs cleanup on
error, and errors can be returned by any finder via the lookup API.
What's more, the finder API doesn't allow specifying an already-known
module. Thankfully, error handling can be improved using the cleanup
API, and looking up a module for an address is usually a reasonably
cheap binary tree operation.
Switch the internal method over to the new finder API. The major
difference now is simply that lookup failures don't result in an error:
they simply result in a NULL symbol.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
The following commit will modify it to use
drgn_program_symbols_search(), a static function declared below. Move it
underneath in preparation. No changes to the function.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
Symbol lookup is not yet modular, like type or object lookup. However,
making it modular would enable easier development and prototyping of
alternative Symbol providers, such as Linux kernel module symbol tables,
vmlinux kallsyms tables, and BPF function symbols. To begin with, create
a modular Symbol API within libdrgn, and refactor the ELF symbol search
to use it.
For now, we leave drgn_program_find_symbol_by_address_internal() alone.
Its conversion will require some surgery, since the new API can return
errors, whereas this function cannot.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
By using __attribute__((__packed__)), we shrink each enum from the
default integer size of four bytes, down to the minimum size of one.
This reduces the size of drgn_symbol from 32 bytes down to 26, with 6
bytes of padding. It doesn't have a practical benefit yet, but adding
fields to struct drgn_symbol in the future may not increase the size.
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
We haven't kept up the maintenance of this tool, which goes against the
goal that the tools directory contains maintained, tested tools. Move it
to contrib. If it gets some love, we can always move it back.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Simply printing dmesg currently requires something like
print(get_dmesg().decode()), which is quite verbose. Josef Bacik
complained about this, so let's add a shortcut helper.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The next change will use an annotation from _typeshed, which looks ugly
in the generated documentation. Let's strip it when appropriate.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
print_annotated_stack() assumes a generally well-formed stack trace, but
in practice, stack traces can be very messy: there can be frames on
separate stacks without being marked as interrupted and all sorts of
garbage at the end of the stack trace. Let's try to handle a couple of
cases of suspicious stack pointers.
Fixes#305.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
This test is too slow to run with full system emulation.
It might be worth using pytest marks [1] to mark slow tests more
generally, but for now, this is the only one problematic enough.
1: https://docs.pytest.org/en/stable/how-to/mark.html
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Before Linux kernel commit 4e57a4ddf6b0 ("ARM: 9107/1: syscall: always
store thread_info->abi_syscall") (in v5.15), on Arm, the syscall number
in /proc/<pid>/syscall is unreliable unless the process is being traced.
fork_and_sigwait() relies on this to detect when the created process has
scheduled out for good. Instead, we can have the created process raise
SIGSTOP and wait for it to be stopped. This is simpler and also doesn't
require us to care about the sigwait syscall numbers. While we're
reworking it, let's also consolidate it with fork_and_call().
test_task_state_to_char() can't use the new function because it wants
the function to sleep, then stop, then die, but it's easy enough to
open-code that one special case.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
elfutils commit c1c1c06e30f0 ("libebl: Add ebl_func_addr_mask plus ARM
backend implementation.") has a bug that I haven't gotten around to
fixing: it masks the least significant bit of all symbol values, not
just function symbol values. This breaks the get_kconfig() helper: if
the kernel_config_data_end symbol value is odd, then the length of the
compressed config data is truncated by one byte and gzip decompression
fails. Disable the test on Arm until we get it fixed.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
The drgn_test module build started failing on Linux 4.9 on AArch64 again
(maybe because of the new config options?). Add more arch/arm headers
that were being referenced from arch/arm64.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
A few older kernel versions are missing the .debug_frame section because
the compiler is generating .eh_frame instead, only for it to get
discarded by the linker script. Backport a patch to disable .eh_frame
generation to the kernel versions that we care about.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
If an exception is raised after QEMU is started, then the
subprocess.Popen context manager waits for the QEMU process to exit,
which it likely never will. If vmtest.vm gets killed with SIGTERM, the
QEMU process continues running. Fix both of these issues by terminating
the QEMU process if there is an exception and adding a signal handler
for SIGTERM to exit gracefully.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
It can be confusing and misleading to see a FaultError for a strange
address that is actually physical.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Like fork_and_sigwait(), but returns the called function's return value,
and only waits for the function to return, not sigwait.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
In this mode, we print the paths of the referenced files. Now that we
have multiple "checks" we're doing, also add an option to enable or
disable specific checks.
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Apparently the kernel starts the init process with stdin and stdout set
to /dev/console, which cannot be a controlling tty, which is required
for stuff like Ctrl-C and shell job control to work. This can apparently
be worked around with setsid -c; see
https://github.com/systemd/systemd/issues/1431#issuecomment-393347607.
Signed-off-by: Omar Sandoval <osandov@osandov.com>