Commit Graph

399 Commits

Author SHA1 Message Date
Omar Sandoval
ec9a963571 tests: use symbol from test module instead of __schedule for identify_symbol() test
__schedule tends to end up aliased with other special symbols because
it's placed in the .sched.text section. We're handling
__sched_text_start, but on ppc64, I also saw __cpuidle_text_end. Use
drgn_test_function from the test kernel module instead.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-06-27 18:57:43 -07:00
Omar Sandoval
b47152a6e7 tests: remove unused IDR from test kernel module
The test kernel module has several -Woverflow warnings when compiled for
Arm:

  /home/osandov/repos/drgn/build/vmtest/arm/tmp9g8977mn/drgn_test.c:785:9: warning: unsigned conversion from 'long long int' to 'long unsigned int' changes value from '6221254864074593878' to '1448498774' [-Woverflow]
    785 |         0x5656565656565656,
        |         ^~~~~~~~~~~~~~~~~~
  /home/osandov/repos/drgn/build/vmtest/arm/tmp9g8977mn/drgn_test.c:786:9: warning: unsigned conversion from 'long long int' to 'long unsigned int' changes value from '1311768465173141112' to '305419896' [-Woverflow]
    786 |         0x1234567812345678,
        |         ^~~~~~~~~~~~~~~~~~
  /home/osandov/repos/drgn/build/vmtest/arm/tmp9g8977mn/drgn_test.c:787:9: warning: unsigned conversion from 'long long int' to 'long unsigned int' changes value from '1311768467294899695' to '2427178479' [-Woverflow]
    787 |         0x1234567890abcdef,
        |         ^~~~~~~~~~~~~~~~~~

drgn_test_idr_dense and drgn_test_idr_ptrs aren't actually used by the
tests, so remove them.

Fixes: 4f2c8f0735 ("tests: idr: add test cases for idr.")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-06-27 17:31:23 -07:00
Omar Sandoval
104a14781d tests: test compressed debug sections
Test both .zdebug_* sections and SHF_COMPRESSED .debug_* sections.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-06-20 13:45:04 -07:00
Omar Sandoval
95c7d9ab63 tests: add better test for kernel Program.crashed_thread()
Instead of simply checking whether the thread ID is non-zero, write a
specific task name to /proc/self/comm before crashing and check that.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-06-15 09:57:18 -07:00
Omar Sandoval
772492838f drgn.helpers.linux.mm: add arbitrary address translation helpers
follow_{page,pfn,phys}() translate the virtual address by walking the
page table for a given mm_struct (built on top of the existing page
table iterator interface). vmalloc_to_page() and vmalloc_to_pfn() are
special cases for vmalloc addresses.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-06-02 23:40:38 -07:00
Sven Schnelle
73e451d588 tests: enable MM tests on s390x
s390x now has full mm support, so enable the tests for it.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
2023-03-22 15:24:11 -07:00
Omar Sandoval
3a4480289c tests: remove @skip_unless_have_full_mm_support from page <-> pfn <-> phys helper tests
The phys <-> pfn helpers only need PAGE_SHIFT, which is always
available, the page <-> pfn helpers only need vmemmap or mem_map, which
is independent of virtual address translation, and the page <-> phys
helpers are built on top of those.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-22 16:12:33 -08:00
Omar Sandoval
101639caaf tests: don't compare values of reference objects in assertIdentical()
The value can change between two reads. This caused test failures in the
previous commit 18a8f69ad8 ("libdrgn: linux_kernel: add object finder
for jiffies"). The important thing is that the addresses are the same.

Fixes: 75c3679147 ("Rewrite drgn core in C")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-22 13:33:47 -08:00
Omar Sandoval
18a8f69ad8 libdrgn: linux_kernel: add object finder for jiffies
We have a lot of examples that use jiffies, but they stopped working
long ago on x86-64 (since Linux kernel commit d8ad6d39c35d ("x86_64: Fix
jiffies ODR violation") (in v5.8 and backported to stable releases)) and
never worked on other architectures. This is because jiffies is defined
in the Linux kernel's linker script. #277 proposed updating the examples
to use jiffies_64, but I would guess that most kernel developers are
familiar with jiffies and many have never seen jiffies_64. jiffies is
also a nicer name to type in live demos. Let's add a case to the Linux
kernel object finder to get the jiffies variable.

Reported-by: Martin Liska <mliska@suse.cz>
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-22 11:15:37 -08:00
Omar Sandoval
69f5352cb6 tests: replace mmap with test kernel module for test_read_physical()
tests.linux_kernel.helpers.test_mm.TestMm.test_read_physical() fails on
Arm when the user page is mapped from high memory. Replace it with a
test case that uses the test physical address from the test kernel
module and asserts the expected PRNG data. (We will probably run into
more tests that fail with high memory once #244 is merged.)

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-22 10:07:55 -08:00
Omar Sandoval
dc38822e6c tests: use PRNG to generate data for tests
This replaces the multiples of a prime sequence used for the per-CPU
helper tests with a slightly more self-documenting PRNG interface in
both the test kernel module and Python test scaffolding. It will be used
more in upcoming tests.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-22 02:10:03 -08:00
Jay Kamat
08cb38cc2f Expand DW_AT_upper_bound quirk on zero size arrays
GCC appears to use data8 at -1 when reporting zero length arrays when
comping c++ code, this patch adds support and a test for that behavior.

dwarf_info.c: Remove check for sdata on quirk for array length == 0

Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
2023-02-21 16:44:20 -08:00
Omar Sandoval
58664bedfb tests: allow test_identify_unrecognized() to pass on s390x
When testing #245, I encountered this error:

======================================================================
ERROR: test_identify_unrecognized (tests.linux_kernel.helpers.test_common.TestIdentifyAddress)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/host/home/osandov/repos/drgn/tests/linux_kernel/helpers/test_common.py", line 57, in test_identify_unrecognized
    self.assertIsNone(identify_address(self.prog, start_addr - 1))
  File "/host/home/osandov/repos/drgn/drgn/helpers/common/memory.py", line 99, in identify_address
    symbol = prog.symbol(addr)
OverflowError: can't convert negative int to unsigned

This is because the lowest kernel address in s390x is 0, so we're
passing -1 to identify_address(). Work around that in the test.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-21 14:44:53 -08:00
Omar Sandoval
cfda1942f8 tests: only run stack tracing tests on implemented architectures
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-18 01:42:38 -08:00
Martin Liska
93cd8ee0b3 mm: introduce new helper function totalram_pages
Signed-off-by: Martin Liska <mliska@suse.cz>
Co-authored-by: Omar Sandoval <osandov@osandov.com>
2023-02-08 08:07:56 -08:00
Martin Liska
53a639ce70 Introduce loadavg helper.
The helper function returns a tuple with load
averaged over last 1, 5 and 15 minutes.

Signed-off-by: Martin Liska <mliska@suse.cz>
Co-authored-by: Omar Sandoval <osandov@osandov.com>
2023-02-07 14:04:49 -08:00
Omar Sandoval
b05e02d4ec tests: add @skip_unless_have_test_kmod to test_print_annotated_stack()
The test case checks `drgn_test_slob` from the test kmod.

Fixes: 975255f209 ("tests: handle cases without slab support in print_annotated_stack() test")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-03 11:51:08 -08:00
Omar Sandoval
b51f5a3c31 drgn.helpers.common.format: add number_to_binary_units()
Martin Liška added something like this for PR #257. As he pointed out,
it'd be nice to have this available in general. I copied my
implementation from
https://github.com/osandov/osandov-linux/blob/master/scripts/xfs_rt_debug.py.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-02-01 13:18:16 -08:00
Martin Liska
55e098b560 tests: add test for sock_cgroup_ptr function
Related to: #253.

Signed-off-by: Martin Liska <mliska@suse.cz>
Co-authored-by: Omar Sandoval <osandov@osandov.com>
2023-01-31 07:42:52 -08:00
Imran Khan
4f2c8f0735 tests: idr: add test cases for idr.
So far idr support was available for only radix-tree based idrs.
Thus radix-tree tests were implicity covering idr test as well.
Now as we are supporting non radix-tree based idrs as well, so
add explicit test cases for idr testing.
The test are applicable for both new (i.e radix-tree based) and
old implementation of idrs.

Signed-off-by: Imran Khan <imran.f.khan@oracle.com>
2023-01-23 17:32:17 -08:00
Kevin Svetlitski
7e6efe6649 Add support for looking up types in namespaces
Looking up objects in namespaces is already well-supported by `drgn`.
These changes bring the same to functionality type lookup, so that
`prog.type('struct A::B::C::MyType')` works in an analogous fashion to
`prog['A::B::C::MyVar']`.

Signed-off-by: Kevin Svetlitski <svetlitski@meta.com>
2023-01-19 10:19:36 -08:00
Omar Sandoval
3ec91c723a tests: kmod: stop using crash_setup_regs()
ppc64's crash_setup_regs() calls ppc_save_regs(), which isn't exported.
So, we need to provide our own implementation. At this point, we might
as well just copy the implementations of crash_setup_regs() for x86-64
and AArch64 and stop trying to use crash_setup_regs().

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-01-04 16:35:51 -08:00
Omar Sandoval
975255f209 tests: handle cases without slab support in print_annotated_stack() test
When the architecture is missing virtual address translation or the
kernel is configured with SLOB, print_annotated_stack() will not
identify slab objects.

Fixes: 05041423c7 ("drgn.helpers.common.stack: add print_annotated_stack helper function")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-01-04 15:10:16 -08:00
Omar Sandoval
e860a6e077 tests: use #ifdef __s390x__ instead of #if
The Linux kernel apparently enables -Wundef, so although #if is correct,
it results in a warning. Use #ifdef instead.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-12-19 16:25:05 -08:00
Sven Schnelle
44648ae139 tests: add drgn_test_get_pt_regs() for s390
s390 doesn't implement crash_setup_regs(). Add an alternative
implementation instead.

Suggested-by: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
2022-12-19 13:48:44 -08:00
Omar Sandoval
7b64aee4dd tests: add a real test case for unwinding from struct pt_regs
The current test case only checks that getting a stack trace succeeds.
By having the test kernel module create a struct pt_regs, we can
actually test that we get a reasonable stack trace.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-12-15 17:44:22 -08:00
Kevin Svetlitski
454e6e8197 Add test cases for parsing C++ identifiers with template parameters
Signed-off-by: Kevin Svetlitski <svetlitski@meta.com>
2022-12-14 20:55:03 -08:00
Kevin Svetlitski
4213bea149 libdrgn: add limited support for looking up types with template arguments
Currently, looking up a type with template arguments results in an
"invalid character" syntax error on the "<" character. The DWARF index
includes template arguments in indexed names, so we need to do lookups
including the template arguments. Full support for this would require
parsing the template argument list syntax and normalizing it or looking
it up as an AST in some way. For now, it's at least an improvement to
pass the user's string verbatim. To do so, kludge it by adding a token
containing everything from "<" to the matching ">" to the C++ lexer and
appending that to the identifier.

Co-authored-by: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Kevin Svetlitski <svetlitski@meta.com>
2022-12-14 20:55:03 -08:00
Omar Sandoval
7ce84a3f1f drgn.helpers.linux: add proper XArray helpers
Commit 89eb868e95 ("helpers: make find_task() work on recent kernels")
made radix_tree_lookup() and radix_tree_for_each() work for basic
XArrays. However, it doesn't handle a couple of more advanced features:
multi-index entries (which old radix trees actually also supported) and
zero entries. It has also been really confusing to explain to people
unfamiliar with the radix tree -> XArray transition that they should use
helpers named radix_tree for a structure named xarray.

So, let's finally add xa_load(), xa_for_each(), and some additional
auxiliary helpers. The non-recursive xa_for_each() implementation is
based on Kevin Svetlitski's C implementation from commit 2b47583c73
("Rewrite linux helper iterators in C"). radix_tree_lookup() and
radix_tree_for_each() share the implementation with xa_load() and
xa_for_each(), respectively, so they are mostly interchangeable.

Fixes: #61

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-12-13 17:46:37 -08:00
Alastair Robertson
7180304c88 libdrgn: dwarf_info: Support DW_TAG_GNU_template_parameter_pack
This DWARF tag is used by C++ classes which take a variable number
of template parameters, such as std::variant and std::tuple.

Signed-off-by: Alastair Robertson <ajor@meta.com>
2022-12-05 15:33:46 -08:00
Omar Sandoval
32dc31aaca tests: fix rmmod of test kmod
Thanks to commit c08f6be52a ("vmtest: kbuild: add
CONFIG_MODULE_UNLOAD=y"), I was finally able to try unloading the test
kernel module and found a trivial copy-and-paste error. Fix it.

Fixes: 42e7d474d1 ("drgn.helpers.linux.mm: add compound page helpers")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-12-02 14:42:57 -08:00
Nhat Pham
05041423c7 drgn.helpers.common.stack: add print_annotated_stack helper function
This helper function shows the content of the stack trace, optionally
annotating each entry with the appropriate tag. Currently, it only
annotates symbols and slab cache objects.

Signed-off-by: Nhat Pham <nphamcs@gmail.com>
2022-11-29 17:08:30 -08:00
Omar Sandoval
0fad8a591a libdrgn: fix finding types beginning in size_t or ptrdiff_t
c_parse_specifier_qualifier_list() checks whether an identifier starts
with "size_t" or "ptrdiff_t" to decide whether to return the size_t or
ptrdiff_t type. This incorrectly matches stuff like like "size_tea" and
"ptrdiff_tee". Fix this by making it an exact comparison.

Fixes: 75c3679147 ("Rewrite drgn core in C")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-28 16:21:56 -08:00
Omar Sandoval
222680b47a Add StackFrame.sp
We have some generic helpers that we'd like to add (for example, #210)
that need to know the stack pointer of a frame. These shouldn't need to
hard-code register names for different architectures. Add a generic
shortcut, StackFrame.sp.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-22 18:47:16 -08:00
Omar Sandoval
fefa613a69 drgn.helpers.common.memory: add more slab object information to identify_address()
Now that we have slab_object_info(), use it to identify the offset of an
address in a slab object and whether the object is allocated.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-21 01:12:31 -08:00
Omar Sandoval
c38801fc10 drgn.helpers.linux.slab: add slab_object_info()
find_containing_slab_cache() is very useful, but there are two
additional pieces of information I've found myself wanting: the offset
of the pointer in the slab object and whether the slab object is
allocated or free. Add a new helper, slab_object_info(), which provides
that information.

The implementation was a challenge because we want to share as much code
as we can between slab_object_info() and
slab_cache_for_each_allocated_object(), but there are a multitude of
slab allocator configuration options and version differences requiring
unique handling. Stephen Brennan provided some code that I stole several
ideas from.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-21 01:04:18 -08:00
Omar Sandoval
a45603a884 tests: use test kmod for more stack trace tests
Rather than the fuzzy guesses we do with a task in sigwait, take
Stephen's idea from commit 5f3a91f80d ("Add StackFrame.locals()
method") further and use the test kmod to set up some precise stack
frames that we can test. Also use kthread_park() to make sure we can't
race with the thread not being scheduled out (unlikely as that may be).

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-06 23:24:22 -08:00
Stephen Brennan
5f3a91f80d Add StackFrame.locals() method
The StackFrame's __getitem__() method allows looking up names in the
scope of a stack frame, which is an incredibly useful tool for
debugging. However, the names are not discoverable -- you must already
be looking at the source code or some other source to know what names
can be queried. To fix this, add a locals() method to StackFrame, which
lists names that can be queried in the scope. Since this method is named
locals(), it stops at the function scope and doesn't include globals or
class members.

Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
2022-11-02 22:40:33 -07:00
Omar Sandoval
87b7292aa5 Relicense drgn from GPLv3+ to LGPLv2.1+
drgn is currently licensed as GPLv3+. Part of the long term vision for
drgn is that other projects can use it as a library providing
programmatic interfaces for debugger functionality. A more permissive
license is better suited to this goal. We decided on LGPLv2.1+ as a good
balance between software freedom and permissiveness.

All contributors not employed by Meta were contacted via email and
consented to the license change. The only exception was the author of
commit c4fbf7e589 ("libdrgn: fix for compilation error"), who did not
respond. That commit reverted a single line of code to one originally
written by me in commit 640b1c011d ("libdrgn: embed DWARF index in
DWARF info cache").

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-01 17:05:16 -07:00
Omar Sandoval
84b0c087d4 License tests/linux_kernel/kmod/drgn_test.c under GPL-2.0-or-later
According to
https://www.kernel.org/doc/html/latest/process/license-rules.html,
MODULE_LICENSE("GPL") means GPL version 2.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-01 16:57:00 -07:00
Omar Sandoval
d465071651 libdrgn: replace copies of elfutils headers with generated files
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-01 15:41:53 -07:00
Stephen Brennan
369e2343c4 helpers: slab: Add get_slab_aliases()
When SLUB is in use, and the CONFIG_SYSFS is enabled (a very common
situation), we are able to identify which slab caches have been merged.
Provide a helper to expose this information so that users can lookup the
correct cache name, or identify all other caches which have been merged
with a given cache.

Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
2022-10-21 12:05:43 -07:00
Omar Sandoval
e6f1aa563f tests: make get_kconfig() test case more thorough
Instead of just checking that CONFIG_IKCONFIG_PROC exists, let's parse
/proc/config.gz.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-18 16:23:02 -07:00
Omar Sandoval
7d286f15a9 tests: skip ORC unwinding test unless on x86-64
Only x86-64 has ORC, so it's a waste of time to run
tests.linux_kernel.test_stack_trace.TestStackTrace.test_by_pid_orc() on
other architectures.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-11 21:40:45 -07:00
Omar Sandoval
5539015945 tests: enable MM tests on AArch64
AArch64 has full MM support, but I forgot to add it to
@skip_unless_have_full_mm_support.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-11 16:01:13 -07:00
Omar Sandoval
bcbac26346 Use NORMALIZED_MACHINE_NAME instead of platform.machine() everywhere
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-11 16:00:35 -07:00
Omar Sandoval
856eb18291 tests: move SYS to util.py and define NORMALIZED_MACHINE_NAME
The syscall table will be useful outside of the test cases themselves.
Additionally, definining it in terms of the "normalized" machine name is
a little easier. The normalized machine name will be useful elsewhere,
too.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-11 15:57:08 -07:00
Omar Sandoval
98ae4d4479 tests: skip identify_address() tests when needed
tests.linux_kernel.helpers.test_common.TestIdentifyAddress.test_identify_unrecognized()
is missing @skip_unless_have_full_mm_support and
@skip_unless_have_test_kmod.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-11 12:47:41 -07:00
Omar Sandoval
0b7ac5b046 Fix vmcore stack traces on Linux < 4.9 or >= 5.16 and add drgn.helpers.linux.task_cpu()
task->cpu was moved to task->thread_info.cpu in Linux 5.16, which causes
drgn_get_initial_registers() to think that the kernel is !SMP and use
CPU 0 instead, producing incorrect stack traces. This has also always
been wrong for Linux < 4.9 and on architectures that don't enable
CONFIG_THREAD_INFO_IN_TASK; in those cases, it should be
((struct thread_info *)task->stack)->cpu.

Fix it by factoring out a new task_cpu() helper that handles all of the
above cases. Also add a test case for task_cpu() in case this changes
again.

Fixes: eea5422546 ("libdrgn: make Linux kernel stack unwinding more robust")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-03 16:21:12 -07:00
Omar Sandoval
2f9b274257 tests: fix race in tests using fork_and_pause()+proc_blocked()
Every once in awhile, a tests.linux_kernel.test_stack_trace test fails
with a "cannot unwind stack of running task" error or without being able
to find pause or ppoll in the trace. I previously attempted to fix this
in commit a5845e63d4 ("tests: fix race condition in stack trace
tests"). However, now I'm seeing the forked process try to open
/etc/ld.so.cache before pausing for some reason. Since this can block,
proc_blocked() might return true before the process is actually in
pause(). If we get a stack trace while the process is in the wrong
syscall or in between calling another syscall and pause(), we will fail
as mentioned above.

Fix it in a few parts:

1. Use sigwait() instead of pause(), which I doubt is used anywhere else
   while forking and won't get woken up by stray signals.
2. Wait until /proc/$pid/syscall shows that we're blocked in
   rt_sigtimedwait or rt_sigtimedwait_time64 specifically.
3. Replace the manual fork_and_pause(), wait_until(proc_blocked, pid),
   os.kill(pid, signal.SIGKILL), os.waitpid(pid, 0) sequence with a
   context manager that takes care of all of that, fork_and_sigwait().

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-03 15:56:00 -07:00