Page MenuHomeFreeBSD

libexec/kgdb: Add a new VNET function and add more scaffolding
Changes PlannedPublic

Authored by markj on Thu, Jun 12, 9:01 PM.
Tags
None
Referenced Files
F122398103: D50825.id.diff
Sat, Jul 5, 12:17 AM
F122393860: D50825.diff
Fri, Jul 4, 11:18 PM
Unknown Object (File)
Thu, Jul 3, 1:13 PM
Unknown Object (File)
Wed, Jul 2, 7:53 AM
Unknown Object (File)
Wed, Jul 2, 1:07 AM
Unknown Object (File)
Mon, Jun 30, 11:39 PM
Unknown Object (File)
Mon, Jun 30, 11:39 PM
Unknown Object (File)
Mon, Jun 30, 11:39 PM
Subscribers

Details

Reviewers
jhb
avg
Summary
- Add a gdb helper function which can be used to easily print VNET
  variables from kgdb.  See the docstring for some usage hints.
- Introduce a little module of useful python functions.
- Install a kernel-gdb.py in /usr/lib/debug/boot/kernel.  This sources
  all of our commands and functions so that they're automatically
  available.

I'm open to other ways of organizing these modules. It'd also be nice
to have a list of all the custom functions and commands we have, but I'm
not sure yet how best to go about that.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 64831
Build 61714: arc lint + arc unit

Event Timeline

markj requested review of this revision.Thu, Jun 12, 9:01 PM

I guess installing these scripts to /usr/libexec/kgdb is not really right--we might want different versions of those scripts for different kernels. So, we could probably install them to /usr/lib/debug/boot/${kernel}/kernel-gdb/ instead. But, where in the src tree should the python libraries live? sys/tools/kgdb maybe?

While testing I found that this has issues with vnet variables in kernel modules.

For a test I added a panic() call in pf_test(), and tried to print V_pf_status.

The kernel and module were loaded at:

0xffffffff80200000  217bc18 kernel
0xffffffff836dd000    52b48 pf.ko

The kernel shows these addresses:

curvnet 0xfffff804a6a76bc0
curvnet->vnet_data_base 0xfffffe02c7d4aa20
&VNET_NAME(pf_status) 0xffffffff81b8fac8
&V_pf_status = 0xfffffe02498da4e8

Debugging the vnet.py script I found that it had the correct vnet: 0xfffff804a6a76bc0, and the correct vnet_data_base 0xfffffe02c7d4aa20, but it thought that the address of vnet_entry_pf_status (== &VNET_NAME(pf_status)) was 0xffffffff8372c390.

It looks like the vnet,py code thinks the pf.ko vnet variables live in the module's address range, while the kernel actually puts those in the kernel's vnet address range. I'm not sure how we can teach vnet.py to get the correct address for kernel module vnet variables.

In D50825#1160523, @kp wrote:

While testing I found that this has issues with vnet variables in kernel modules.

For a test I added a panic() call in pf_test(), and tried to print V_pf_status.

The kernel and module were loaded at:

0xffffffff80200000  217bc18 kernel
0xffffffff836dd000    52b48 pf.ko

The kernel shows these addresses:

curvnet 0xfffff804a6a76bc0
curvnet->vnet_data_base 0xfffffe02c7d4aa20
&VNET_NAME(pf_status) 0xffffffff81b8fac8
&V_pf_status = 0xfffffe02498da4e8

Debugging the vnet.py script I found that it had the correct vnet: 0xfffff804a6a76bc0, and the correct vnet_data_base 0xfffffe02c7d4aa20, but it thought that the address of vnet_entry_pf_status (== &VNET_NAME(pf_status)) was 0xffffffff8372c390.

It looks like the vnet,py code thinks the pf.ko vnet variables live in the module's address range, while the kernel actually puts those in the kernel's vnet address range. I'm not sure how we can teach vnet.py to get the correct address for kernel module vnet variables.

I think we can loop over the loaded linker files, find each one's VNET base, compare that with the pointer to see if the object lives in the corresponding module, and if so use the correct base. Certainly more complicated than what's there now, but I think it's doable. Let's see.

Thanks, the vnet function is indeed too simplistic. I believe, though I'm not totally certain, that I'll need to modify link_elf_obj.c a bit to preserve the original base address for the VNET variable section. Otherwise the debugger doesn't have a good way to figure out which VNET section a given variable belongs to. I have some WIP to address this but I need a bit of time.

The other problem is that we probably want to install a copy of these modules with each kernel, e.g., under /usr/lib/debug/boot/${kernel}/kernel-gdb/. I'll fix that too.