Commit Graph

385 Commits

Author SHA1 Message Date
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
Omar Sandoval
115f4ee263 tests: move bpf syscall numbers to tests.linux_kernel
The next commit will some more syscall numbers that we need, so let's
settle on one place where we define syscall numbers.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-10-03 15:45:40 -07:00
Nhat Pham
15cc473ec2 drgn.helpers.common.memory: add identify_address helper function
This helper function identifies the type of the address (slab allocated
or symbol) and returns a string representation of the address
accordingly. This will be useful for another helper function which
prints the stack trace with more information about each item on the
stack.

Signed-off-by: Nhat Pham <nphamcs@gmail.com>
2022-09-14 17:08:39 -07:00
Omar Sandoval
c2c75e5d17 Move top-level drgn.helpers helpers into drgn.helpers.common submodules
This is a better place to put all of these generic helpers now. I think
these are all uncommon enough that it shouldn't be too much trouble to
move them.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-09-14 17:08:39 -07:00
Omar Sandoval
30c9ad452d libdrgn: linux_kernel: fix global per-CPU variables in kernel modules
The .data..percpu section is excluded from /sys/module and struct
module::sect_attrs, which means that we default its address to 0. This
results in global per-CPU variables in kernel modules being relocated
starting from 0 rather than the offset of the per-CPU allocation made
for the module, which in turn causes those variables to appear to
contain the wrong data. Fix it by manually getting the per-CPU address
from struct module.

Closes #185.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-09-12 16:27:28 -07:00
Omar Sandoval
a52016c4cb libdrgn: linux_kernel: always use module list from core
For the next fix, we need the address of the .data..percpu section,
which is only available directly from the struct module and not from
anywhere in /proc or /sys. Get rid of the /proc/modules fast path (and
update the name of the testing environment variable from
DRGN_USE_PROC_AND_SYS_MODULES to DRGN_USE_SYS_MODULE).

This has some small overhead (~20ms longer startup time in my
benchmarks) and means that we no longer determine the loaded modules if
vmlinux is missing, but fixing the per-CPU issue is more important.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-09-12 16:11:59 -07:00
Omar Sandoval
e5c7acb4fb drgn.helpers.linux.slab: handle compound pages in find_containing_slab_cache()
Some slab caches for large objects (like task_struct) allocate slabs as
compound pages. Only the head page is marked as PageSlab(), so if
find_containing_slab_cache() gets an address that was allocated out of a
tail page, it will incorrectly return NULL. Fix it by always getting the
compound_head, and add a test case with large slab objects.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-09-09 16:35:28 -07:00
Omar Sandoval
42e7d474d1 drgn.helpers.linux.mm: add compound page helpers
I had these helpers lying around from a couple of bugs related to
compound pages that I debugged.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-09-09 15:54:43 -07:00
Peilin Ye
517d4bea18 tests: Add missing tags for test_find_containing_slab_cache_invalid()
Running test_find_containing_slab_cache_invalid() without the drgn_test
Linux kernel module gives a KeyError:

  Traceback (most recent call last):
    File ".../tests/linux_kernel/helpers/test_slab.py", line 169, in test_find_containing_slab_cache_invalid
      find_containing_slab_cache(self.prog, self.prog["drgn_test_va"]),
  KeyError: 'drgn_test_va'

Use the @skip_unless_have_test_kmod tag.  The test also needs a
@skip_unless_have_full_mm_support tag as pointed out by Omar, so add it
while we are at it.

Fixes: 79ea6589c2 ("drgn.helpers.linux.slab: add find_containing_slab_cache helper")
Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
2022-08-29 15:01:18 -07:00
Shung-Hsi Yu
e8d0c85811 test: add test for _repr_pretty_() method
Since _repr_pretty_() uses output of str(), and the latter is already
heavily tested in tests/test_language_c.py, we can simply test whether
p.text() is called instead of duplicating all the test cases.

Signed-off-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
2022-08-25 13:52:28 -07:00
Omar Sandoval
d14f751475 drgn.helpers.linux.mm: add simple PageFlag() getters
There are a bunch of page flag getters in the kernel like
PageUptodate(), PageLocked(), etc., that kernel developers are
accustomed to using. Most of them are simple bit tests. Let's add
helpers for all of those. These are generated from
include/linux/page-flags.h in the Linux kernel source tree as of Linux
v6.0-rc1.

More complicated getters that need to do more than a simple flag check
(e.g., PageCompound()) will need to be added manually.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-08-18 15:50:15 -07:00
Nhat Pham
79ea6589c2 drgn.helpers.linux.slab: add find_containing_slab_cache helper
This helper function identifies the slab cache (if any) the object at
the given address belongs to. This will be useful for a future helper
function which prints the stack trace with more information about each
item on the stack.

Signed-off-by: Nhat Pham <nphamcs@gmail.com>
2022-08-16 15:52:21 -07:00
Nhat Pham
93f8d07bcf tests: directly allocate the test page in test kernel module
Modify how the test page is allocated to ensure we have a directly
mapped address which is not slab allocated for testing the negative case
of find_containing_slab_cache.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Nhat Pham <nphamcs@gmail.com>
2022-08-16 15:52:21 -07:00
Omar Sandoval
faaf01ad1b Add drgn.StackTrace.prog and drgn_stack_trace_program()
If we only have the stack trace available, it's useful to get the
program it came from. This'll be used eventually for helpers that take a
stack trace.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-08-11 14:45:54 -07:00
Imran Khan
4296653090 tests: add test cases for Linux llist helpers.
Use the test kernel module to setup tests and add test_llist.py to
carry out testing.

Signed-off-by: Imran Khan <imran.f.khan@oracle.com>
2022-08-08 08:22:32 -07:00