kctl defines its own kdi_dmods (GCC 14 -fno-common), so the kernel's copy stays NULL and ::findleaks misses kmdb dmods #14
Summary
kmdb keeps its own copy of kdi_dmods, so the kernel's copy stays NULL and
mdb's ::findleaks cannot see kmdb's debugger-module list.
The pointer is meant to be shared: genunix defines it
(uts/common/os/kdi.c:34, declared extern in uts/common/sys/kdi.h:62) and
kctl publishes its dmod list through it
(cmd/mdb/common/kmdb/kctl/kctl_dmod.c:435, kdi_dmods = &kctl_dmods). But
kctl_dmod.c:44 also defines it:
struct modctl *kdi_dmods;
GCC 14 defaults to -fno-common and the build never passes -fcommon, so that
line is a strong .bss definition rather than a common symbol. kmdbmod
therefore binds its own references to its own copy.
Measured (alpha12, rev 501, -k boot, kmdb active)
genunix kdi_dmods: 0
kmdbmod kmdbmod`kdi_dmods: fffffffffc08dce0 (= &kctl_dmods, 8 dmods loaded)
Symbol table, same build:
kctl_dmod.o kdi_dmods OBJT GLOB .bss
kmdbmod kdi_dmods OBJT GLOB .bss
genunix kdi_dmods OBJT GLOB .bss
gcc -Q --help=common: -fcommon [disabled]
Impact
Low. Nothing in uts reads kdi_dmods. Its one consumer is mdb's genunix
dmod, cmd/mdb/common/modules/genunix/leaky_subr.c:465:
/* If kmdb is loaded, we need to walk it's module list, since kmdb
* modctl structures can reference kmem allocations. */
if ((mdb_readvar(&dmods, "kdi_dmods") != -1) && (dmods != 0))
(void) mdb_pwalk("modctl", (mdb_walk_cb_t)leaky_modctl, NULL, dmods);
With the kernel copy NULL, ::findleaks skips kmdb's modctls, so on a system
with kmdb loaded, allocations referenced only from them can be reported as
leaks. Not measured.
Not caused by the GNU ld conversion: the definition is strong in the object
file before any link. Not checked against upstream illumos.
Fix sketch
Delete the definition at kctl_dmod.c:44 so kctl uses the extern from
<sys/kdi.h> (include it directly if kmdb/kmdb_kdi.h does not already).
kmdbmod then carries kdi_dmods as GLOB UNDEF, bound to genunix's copy by
krtld, both for a -k primary load and for a later module load.
Gate
elfdump -s kmdbmod:kdi_dmodsisGLOB UNDEF, and no definition remains.- After a
-kboot:echo kdi_dmods/K | mdb -kis non-zero and equals the
address of kmdbmod'skctl_dmods. - Negative control: the current build reads 0 at step 2.
-kboot still activates kmdb with 0 traps; both boot matrices.
Assignees
No assignees
Labels
No labels
Severity
Low