Commit Graph

1071 Commits

Author SHA1 Message Date
Omar Sandoval
40357b9d9e libdrgn: debug_info: don't use strlen() in drgn_debug_info_find_object()
The length of the name was passed, and the name may not be
null-terminated.

Fixes: 565e0343ef ("libdrgn: make symbol index pluggable with callbacks")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-17 18:06:43 -08:00
Omar Sandoval
64c4afa298 libdrgn: type: fix hash table insertion error check
table_insert_searched() returns -1 when insertion fails.

Fixes: a97f6c4fa2 ("Associate types with program")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-17 18:04:57 -08:00
Omar Sandoval
4b3eec40df libdrgn: dwarf_index: fix hash table insertion error check
table_insert_searched() returns -1 when insertion fails.

Fixes: d1beb0184a ("libdrgn: add support for objects in C++ namespaces")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-17 18:04:52 -08:00
Omar Sandoval
abc3ee4da0 libdrgn: dwarf_index: clean up index_die()
index_die() can only fail if it's out of memory, so return a bool
instead of a struct drgn_error. Also clean up the declarations.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-17 18:03:49 -08:00
Omar Sandoval
d1745755f1 Fix some include-what-you-use warnings
Also:

* Rename struct string to struct nstring and move it to its own header.
* Fix scripts/iwyu.py, which was broken by commit 5541fad063 ("Fix
  some flake8 errors").
* Add workarounds for a few outstanding include-what-you-use issues.

There is still a false positive for
include-what-you-use/include-what-you-use#970, but hopefully that is
fixed soon.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-10 15:09:29 -08:00
Omar Sandoval
794ffc22e8 libdrgn: kdump: fix leak in leak fix
The previous fix still leaks the vmcoreinfo buffer if parse_vmcoreinfo()
fails.

Fixes: bc85c2da08 ("libdrgn: kdump: fix kdump_vmcoreinfo_raw() memory leak")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-04 14:43:15 -07:00
Omar Sandoval
bc85c2da08 libdrgn: kdump: fix kdump_vmcoreinfo_raw() memory leak
Commit dd503c975ab3 ("Fix kdump_vmcoreinfo_raw()") in libkdumpfile
changed the buffer returned by kdump_vmcoreinfo_raw() to be dynamically
allocated. We need to free it on versions containing that change.

Closes #76.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-04 14:39:13 -07:00
Omar Sandoval
a5845e63d4 tests: fix race condition in stack trace tests
Stephen Brennan reported a flaky test while working on #121:

======================================================================
ERROR: test_by_task_struct (tests.helpers.linux.test_stack_trace.TestStackTrace)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/drgn/drgn/tests/helpers/linux/test_stack_trace.py", line 22, in test_by_task_struct
    self.assertIn("pause", str(self.prog.stack_trace(find_task(self.prog, pid))))
ValueError: cannot unwind stack of running task

The problem is that the stack trace tests wait for the thread state to
change to "S". However, the state is updated while the thread is still
technically running. For example, the pause() system call is implemented
as:

SYSCALL_DEFINE0(pause)
{
	while (!signal_pending(current)) {
		__set_current_state(TASK_INTERRUPTIBLE);
		schedule();
	}
	return -ERESTARTNOHAND;
}

If Program.stack_trace() accesses the thread after the state is changed
but before the thread has actually been scheduled out (namely, before
task_struct::on_cpu is set to 0), it will fail.

Instead, let's check /proc/$pid/syscall, which contains "running" until
the thread is completely scheduled out.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-04 14:13:55 -07:00
Omar Sandoval
d36b12c682 CI: add Python 3.10
Python 3.10 was released in October. No changes to drgn are required.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-03 17:38:31 -07:00
Omar Sandoval
1b7badad0a docs: expand and reorganize installation instructions
* Mention installing drgn using a package manager on Fedora/EPEL.
  Closes #103.
* Mention that pip installs a binary wheel by default.
* Include instructions for installing from source in README.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-03 16:18:22 -07:00
Omar Sandoval
d9192b7245 docs: remove outdated comment about helper types
As of commit 0cf3320a89 ("Add type annotations to helpers"), helpers
have type annotations instead of C signatures.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-03 16:01:27 -07:00
Omar Sandoval
e5021952c8 docs: disable sphinx.ext.viewcode
viewcode works by importing modules. This doesn't actually work on Read
the Docs because we don't build and install the C extension. It looks
like there are workarounds (viewcode-find-source), but let's disable it
for now.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-03 15:58:11 -07:00
Omar Sandoval
bc2d5333c0 README: update link to crash
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-03 11:48:34 -07:00
Omar Sandoval
8358c31d26 docs: document how to get debugging symbols
I couldn't find any good summaries of how to get debugging symbols on
various distros, so I guess we'll have to maintain our own.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-11-02 17:48:36 -07:00
Omar Sandoval
9c54083830 libdrgn: pp: make PP_CAT not variadic
The overloaded version is slower to compile, and we don't actually need
it. We can add a variadic version if we need to in the future. Also add
the script used to generate the macros.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-29 18:38:49 -07:00
Omar Sandoval
568f4f9c2b libdrgn: debug_info: remove dies and length out parameters to drgn_dwarf_die_iterator_next()
These are already available in it->dies.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-29 18:38:49 -07:00
Omar Sandoval
198499e74b libdrgn: debug_info: optimize drgn_find_die_ancestors()
Jay pointed out that when finding the ancestors for a DIE, we should use
DW_AT_sibling to skip over subtrees that can't contain the target DIE.
So, let's check each DIE that we encounter for a DW_AT_sibling
attribute. dwarf_attr() also returns the end of the DIE if it doesn't
find the attribute, which we can use to avoid parsing DIEs redundantly.
This doesn't fit very well into drgn_dwarf_iterator, so let's just
hand-roll this special type of iteration. In my measurements, this made
drgn_find_die_ancestors() ~6x as fast on average.

Closes #124.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-29 18:38:40 -07:00
Omar Sandoval
6150935e96 Fix some cosmetic nits in Packit config and .gitignore
Fix .gitignore alphabetical order and indent YAML consistently.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-29 13:19:32 -07:00
Davide Cavalca
7e6082707d Add initial Packit config
Signed-off-by: Davide Cavalca <dcavalca@fb.com>
2021-10-28 15:13:05 -07:00
Omar Sandoval
3c52b18baa tests: skip PID memory read test if /proc/$pid/mem doesn't work
This works around a QEMU bug
(https://gitlab.com/qemu-project/qemu/-/issues/698) which causes Packit
build failures on 32-bit ARM. This should unblock #126.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-28 14:41:44 -07:00
Jay Kamat
8bf26fafbb dwarf_index.c: lazily allocate shards to save memory on unused ns
Previously shards were allocated as soon as a namespace was
encountered, which means that we had a large array sitting around for
every ns we saw. By allocating them lazily, we can reduce this usage.

Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
2021-10-26 02:07:26 -07:00
Omar Sandoval
1339dc6a2f libdrgn: hash_table: move entry_to_key to DEFINE_HASH_TABLE_FUNCTIONS()
DEFINE_HASH_TABLE_TYPE() doesn't actually need to know the key type.
Move that argument (and some of the derived constants) to
DEFINE_HASH_TABLE_FUNCTIONS(). This will allow recursive hash table
types. As a nice side effect, it also reduces the size of common header
files.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-23 00:52:23 -07:00
Omar Sandoval
802d6cc9ff libdrgn: rename drgn_program::_dbinfo to dbinfo
The underscore was meant to discourage direct access in favor of using
drgn_program_get_dbinfo(), but it turns out that it's more normal to
access it directly.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-23 00:52:23 -07:00
Omar Sandoval
c1e16ae3ec libdrgn: fold drgn_program_get_dbinfo() into only caller
The only time that we want to create the drgn_debug_info is when we're
loading debugging information. Everywhere else, we fail fast if there is
no debugging information.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-23 00:40:57 -07:00
Omar Sandoval
1d4dbc2b69 libdrgn: python: remove unused declaration
drgnpy_linux_helper_task_state_to_char() was removed by commit
ff96c75da0 ("helpers: translate task_state_to_char() to Python"), but
I left behind the declaration.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-10-12 18:01:42 -07:00
Omar Sandoval
734cbe5c7b libdrgn: dwarf_index: free pending DIEs after indexing namespace
Once we've cleared the pending DIEs vector, we won't use the vector
again (unless we load more debugging information), so we can free it.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-28 13:56:52 -07:00
Omar Sandoval
b4a82c30ab Add GitHub action to check for DCO sign-off on pull requests
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-28 12:32:15 -07:00
Jake Hillion
b0ae2867d5 splay_tree.c: Rename splay_tree to avoid conflicts with splay-tree.h
When linking libdrgn as a static library, the name 'splay_tree' can
conflict with splay-tree.h in libiberty (namely splay_tree_splay).

Rename relevant functions to have a 'drgn_' prefix

Signed-off-by: Jake Hillion <jakehillion@fb.com>
2021-09-27 12:56:47 -07:00
Jay Kamat
2baee6fe16 dwarf_index.c: Shrink abbrev tables before saving them in CUs
In larger binaries, there can be a large number of CUs, and since we
store an abbrev table for each CU the extra space starts to add up.
The simplest way to mitigate this is to shrink the vectors before
saving them.

On a large binary, I noticed a memory reduction from 20.4G RES to
18.6G RES (on initial load-in).
2021-09-27 12:08:25 -07:00
Omar Sandoval
c64d87e41a setup.py: add 5.15 to vmtest kernels
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-13 09:59:22 -07:00
Omar Sandoval
801f9d645c tests: improve cgroup helper tests
These haven't been running in vmtest since they were added. Enable
cgroup2 in vmtest and rework the cgroup tests to create cgroups that we
can test with.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-02 16:05:46 -07:00
Peilin Ye
f82273749d helpers: Add qdisc_lookup()
Add a helper, qdisc_lookup(), to get a Qdisc (struct Qdisc *) from a
network device and a major handle number.  As an example:

	>>> eth0 = netdev_get_by_name(prog, "eth0")
	>>> tbf = qdisc_lookup(eth0, 0x20)
	>>> tbf.ops.id.string_().decode()
	tbf
	>>> ingress = qdisc_lookup(eth0, 0xffff)
	>>> ingress.ops.id.string_().decode()
	ingress

Testing depends on pyroute2.  `TestTc` is skipped if pyroute2 is not
found; test_qdisc_lookup() is skipped if the kernel is not built with the
following options:

	CONFIG_DUMMY
	CONFIG_NET_SCH_PRIO
	CONFIG_NET_SCH_SFQ
	CONFIG_NET_SCH_TBF
	CONFIG_NET_SCH_INGRESS

Suggested-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
2021-09-02 11:03:00 -07:00
Peilin Ye
a01131483d helpers: Add netdev_for_each_tx_queue()
Add a helper, netdev_for_each_tx_queue(), to iterate over all TX queues of
a network device.  As an example:

	>>> eth0 = netdev_get_by_name(prog, "eth0")
	>>> for txq in netdev_for_each_tx_queue(eth0):
	...     print(txq.qdisc.ops.id.string_().decode())
	...
	sfq
	tbf
	prio
	pfifo_fast

Set up `net` in setUpClass(), since now several tests use it.  Also use
it in test_netdev_get_by_{index,name}(), instead of assuming `init_net`.

Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
2021-09-02 11:03:00 -07:00
Omar Sandoval
62efd2aab3 vmtest: use virtio-rng
Now that the kernel module is enabled, let's enable the device and load
the module.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-02 09:31:47 -07:00
Omar Sandoval
ce845ad340 vmtest: add virtio-rng and cgroup Kconfig options
We're seeing some hangs waiting for entropy when running tests, so let's
enable the virtio-rng module. While we're doing a rebuild, we might as
well enable cgroups so that we can finally run those tests.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-02 09:12:19 -07:00
Omar Sandoval
3c68b25215 CI: install pyroute2
This is needed to test #117.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-01 15:11:25 -07:00
Omar Sandoval
6ee7ba4cb1 vmtest: add some Traffic Control config options
We need these to test #117.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-09-01 14:13:34 -07:00
Omar Sandoval
77b9d3ad98 tests: change LinuxHelperTestCase.setUp to setUpClass
This already caches class variables, and it's shared across all Linux
helper test cases, so it makes more sense as setUpClass. This will also
allow subclasses to use cls.prog in their own setUpClass.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-31 17:43:18 -07:00
Omar Sandoval
fba5947fec libdrgn: add array_for_each()
And use it in a few appropriate places. This should hopefully make it
harder to make iteration mistakes like the one fixed by commit
4755cfac7c ("libdrgn: dwarf_index: increment correct variable when
rolling back"). While we're doing this, move ARRAY_SIZE() into a new
header file with array_for_each() and make it lowercase.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-23 17:32:00 -07:00
Omar Sandoval
4755cfac7c libdrgn: dwarf_index: increment correct variable when rolling back
We need to increment to the next DIE, not the next shard here.

Fixes: 1c9ab2e7d1 ("libdrgn: dwarf_index: fix leak of DWARF index entries on failure")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-23 17:06:24 -07:00
Omar Sandoval
84f6142879 libdrgn: dwarf_index: remove any_name functionality from dwarf_index_iterator
This hasn't been used since commit 06960f591c ("libdrgn: look up
primitive types on demand").

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-23 17:06:15 -07:00
Stephen Brennan
207ca0e16b tests: Add Symbol test
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
2021-08-20 18:16:57 -07:00
Stephen Brennan
1744d8d93c libdrgn: python: Add binding, kind to drgn.Symbol
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
2021-08-20 18:16:57 -07:00
Stephen Brennan
3d8db22c47 libdrgn: Add kind and binding fields to drgn_symbol
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
2021-08-20 18:16:57 -07:00
Omar Sandoval
8d383fb89a libdrgn: fix alphabetization in gen_constants.py
PlatformFlags obviously comes before PrimitiveType.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-20 15:02:31 -07:00
Omar Sandoval
27906d0cf1 libdrgn: python: cast enums when wrapping with Python call
The "k" format expects an unsigned long, so make sure we cast C enums to
the proper type. This probably doesn't matter for x86 in practice, but
it's better to be safe.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-20 14:58:33 -07:00
Peilin Ye
242d1484f9 helpers: Add get_net_ns_by_{inode,fd}()
Add a helper, get_net_ns_by_inode(), to get the network namespace
("netns") descriptor (struct net *) given an netns NSFS pseudo-file
inode (struct inode *) e.g. "/proc/$PID/ns/net" or "/run/netns/$NAME".
As an example:

	>>> inode = path_lookup(prog, "/run/netns/foo").dentry.d_inode
	>>> net = get_net_ns_by_inode(inode)
	>>> netdev = netdev_get_by_name(net, "eth3")
	>>> netdev.ifindex.value_()
	5

Conventionally ip netns files can be found under "/var/run/netns/",
while Docker netns files can be found under "/var/run/docker/netns".
However, as pointed out by Omar, path_lookup() doesn't know how to
deal with symlinks; resolve it using something like "pwd -P" before
passing it to path_lookup().

Also add a get_net_ns_by_fd() wrapper around it as suggested by Omar.
Example:

	>>> import os
	>>> pid = os.getpid()
	>>> task = find_task(prog, pid)
	>>> file = open(f"/proc/{pid}/ns/net")
	>>> net = get_net_ns_by_fd(task, file.fileno())

Add a test for get_net_ns_by_inode().

Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
2021-08-20 11:39:56 -07:00
Omar Sandoval
c9cb28b649 docs: set required Sphinx version for Read the Docs
Read the Docs defaults to Sphinx 1.8.5. This version was released in
2019 and doesn't know about the :classmethod: option, so the
documentation for Object.from_bytes_() is missing from
drgn.readthedocs.io. Set the required version to the current latest
version as recommended by Read the Docs:
https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html#pinning-dependencies.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-17 15:01:14 -07:00
Peilin Ye
cf06be1813 helpers: Add for_each_net()
Add a helper to iterate over all network namespaces in the system.  As
an example:

	>>> for net in for_each_net(prog):
	...     if netdev_get_by_name(net, "enp0s3"):
	...         print(net.ipv4.sysctl_ip_early_demux.value_())
	...
	1

Also add a test for this new helper to tests/helpers/linux/test_net.py.

Suggested-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
2021-08-16 16:48:25 -07:00
Omar Sandoval
5977dcc1e8 vmtest: use larger msize for 9pfs mounts
QEMU warns about the default 8k msize
(https://wiki.qemu.org/Documentation/9psetup#msize). I wasn't able to
measure any performance difference, but bump it to 1MiB to silence the
warning.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-08-16 12:47:05 -07:00