Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge branch 'master' into '6.0/stage' #8

Merged
merged 87 commits into from
May 16, 2020
Merged

Merge branch 'master' into '6.0/stage' #8

merged 87 commits into from
May 16, 2020

Conversation

github-actions[bot]
Copy link

No description provided.

osandov and others added 30 commits March 27, 2020 17:13
Currently, the kernel config is embedded inside of manage.py. This is
inconvenient when building kernels manually for testing. Move it to a
separate file so that, e.g., it can be copied into the build tree
easily.
About half (!) of vmlinux comes from relocation sections (~130M out of
~250M). But, vmlinux is an ET_EXEC file, so relocations don't even apply
to it. We can massively shrink vmlinux by removing the unnecessary
sections.
And add docstrings to the functions with more complex signatures.
These will be shared with vmtest.
This should just be executed as python3 -m vmtest.manage now.
--build-kernel-org needs the token to get the available releases even if
we're not uploading.
If the path doesn't exist, there are no available releases. Otherwise,
we need to check for other errors.
Any changes of the vmtest kernel config will require a rebuild of all
kernels and a way to distinguish the rebuild. Add CONFIG_LOCALVERSION
which we will bump each time the config changes.
Add an verrevcmp() function based on the coreutils implementation (which
comes from gnulib, which is derived from the implementation in dpkg).
This will be used by vmtest.
The current implementation of vmtest has a few issues:

1. Building drgn for each kernel version on Travis is slow, mostly
   because they don't all run in parallel.
2. For local, incremental testing, recreating the filesystem image and
   rebuilding drgn is slow, and syncing the code to the filesystem image
   is brittle.
3. The filesystem image is the only communication channel, and reading
   the exit status from the filesystem image is awkward and fragile.
4. Creating and accessing the filesystem image requires root.

This reworks vmtest to use the build on the host via VirtFS with a
simple agent on the guest that can execute arbitrary commands and return
the exit status. This has a few more moving parts but is faster and
saner overall.
disable drgn testing when constructing debian package
Currently, drgn_language_from_die() returns the default language when it
encounters an unknown DW_LANG because the dwarf_info_cache always wants
a language. The next change will want to detect the unknown language
case, so make drgn_language_from_die() return NULL if the language is
unknown, move it to language.c, and fold drgn_language_from_dw_lang()
into it.
Jay reported that the default language detection was happening too early
and not finding "main". We need to make sure to do it after the DWARF
index is actually populated. The problem with that is that it makes
error reporting much harder, as we don't want to return a fatal error
from drgn_program_set_language_from_main() if we actually succeeded in
loading debug info. That means we probably need to ignore errors in
drgn_program_set_language_from_main(). To reduce the surface area where
we'd be failing, let's get the language directly from the DWARF index.
This also allows us to avoid setting the language if it's actually
unknown (information which is lost by the time we convert it to a
drgn_object in the current code).
The vmtest rework missed a few new files.
elfutils 0.179 was just released, and it includes my fix for vmcores
with >= 2^16 phdrs.

Based on:

3a7728808 Prepare for 0.179

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
The configure script allows the user to not use any openmp
implementation but dwarf_index.c uses the locking APIs unconditionally.
This compiles but fails at runtime.

Adding simple stubs for the locking API. This is useful when debugging
crashes in dwarf indexing during development.
A few recent changes weren't formatted with black.
drgn may be compiled with some CPU-specific features (e.g.,
-march=native), so make sure that we support those features inside of
the VM, too.
The internal _page_offset() helper gets the value of PAGE_OFFSET, but
the fallback when KASLR is disabled has been out of date since Linux
v4.20 and never handled 5-level page tables. Additionally, it makes more
sense as part of the Linux kernel (formerly vmcoreinfo) object finder so
that it's cleanly accessible outside of drgn internals.
Similarly to PAGE_OFFSET, vmemmap makes more sense as part of the Linux
kernel object finder than an internal helper.

While we're here, let's fix the definition for 5-level page tables. This
only matters for kernels with commit 77ef56e4f0fb ("x86: Enable 5-level
paging support via CONFIG_X86_5LEVEL=y") but without eedb92abb9bb
("x86/mm: Make virtual memory layout dynamic for CONFIG_X86_5LEVEL=y")
(namely, v4.14, v4.15, and v4.16); since v4.17, 5-level page table
support enables KASLR.
osandov and others added 26 commits May 4, 2020 13:20
This isn't used anymore. Remove it and simplify the loop adding file
segments.
Before Linux v4.11, /proc/kcore didn't have valid physical addresses, so
it's currently not possible to read from physical memory on old kernels.
However, if we can figure out the address of the direct mapping, then we
can determine the corresponding physical addresses for the segments and
add them.
This hasn't been used since commit 417a6f0 ("libdrgn: make memory
reader pluggable with callbacks").
DRGN_UNREACHABLE() currently expands to abort(), but assert() provides
more information. If NDEBUG is defined, we can use
__builtin_unreachable() instead.

DRGN_UNREACHABLE() isn't drgn-specific, so this renames it to
UNREACHABLE(). It's also not really related to errors, so this moves it
to internal.h.
Program_load_debug_info() is the last user of the
resize_array()/realloc_array() utility functions. We can clean it up by
using a vector and finally get rid of those functions.

This also happens to fix three bugs in Program_load_debug_info(): we
weren't setting a Python exception if we couldn't allocate the path_args
array, we weren't zeroing path_args after resizing the array, and we
weren't freeing the path_args array. Shame on whoever wrote this.
internal.h includes both drgn-specific helpers and generic utility
functions. Split the latter into their own util.h header and use it
instead of internal.h in the generic data structure code. This makes it
easier to copy the data structures into other projects/test programs.
fls() can be implemented with __bitop(), and we can get rid of clz() since
it's only used by fls().
c_integer_literal() has an open-coded equivalent of fls() that assumes
that unsigned long long is 64 bits. Use fls() instead.
-fsanitize=undefined reports that the read_u* helpers rely on unaligned
loads. Use memcpy() instead.
UNARY_OP_SIGNED_2C() uses a union of int64_t and uint64_t to avoid
signed integer overflow... except that there's a typo and the uint64_t
is actually an int64_t. Fix it and add a test that would catch it with
-fsanitize=undefined.
There are a few big use cases for this in drgn:

* Helpers for accessing memory in the virtual address space of userspace
  tasks.
* Removing the libkdumpfile dependency for vmcores.
* Handling gaps in the virtual address space of /proc/kcore (cf. #27).

I dragged my feet on implementing this because I thought it would be
more complicated, but the page table layout on x86-64 isn't too bad.
This commit implements page table walking using a page table iterator
abstraction. The first thing we'll add on top of this will be a helper
for reading memory from a virtual address space, but in the future it'd
also be possible to export the page table iterator directly.
Now that we can walk page tables, we can finally read memory from
userspace tasks.

Closes #53.
These are two of the most common use cases for reading a process's
memory.
I originally wanted to avoid depending on another vmcoreinfo field, but
an the next change is going to depend on swapper_pg_dir in vmcoreinfo
anyways, and it ends up being simpler to use it.
Now that we can walk page tables, we can use it in a memory reader that
reads kernel memory via the kernel page table. This means that we don't
need libkdumpfile for ELF vmcores anymore (although I'll keep the
functionality around until this code has been validated more).
5.7 is up to rc4 (oops). Better late than never.
The automake/libtool compilation output is obnoxiously verbose. Switch
on automake's silent mode, and make the custom rules honor it.
Rebase on master and fix dwfl_frame_module/dwfl_frame_dwarf_frame to
decrement the program counter when necessary.

Based on:

a8493c12a libdw: Skip imported compiler_units in libdw_visit_scopes walking DIE tree

With the following patches:

configure: Add --disable-programs
configure: Add --disable-shared
libdwfl: simplify activation frame logic
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
For functions that call a noreturn function, the compiler may omit code
after the call instruction. This means that the return address may not
lie in the caller's symbol. dwfl_frame_pc() returns whether a frame is
an "activation", i.e., its program counter is guaranteed to lie within
the caller. This is only the case for the initial frame, frames
interrupted by a signal, and the signal trampoline frame. For everything
else, we need to decrement the program counter before doing any lookups.
Sync "6.0/stage" with "master" via GitHub Actions
@prakashsurya prakashsurya merged commit bf4c45c into 6.0/stage May 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants