Reputation: 93
I have a debug kernel running in QEMU/KVM with GDB attached. I am attempting to debug the ioctl
calls of an LKM I am developing. My LKM registers a character device with a major number. I am noticing that the major number printed by GDB and ones reported in dmesg / procfs / sysfs are different.
I am storing the major number statically:
static char lainmemu_major;
My driver is acquiring a dynamic major number with:
lainmemu_major = (char) register_chrdev(0, MEMU_DEVICE_NAME, &file_ops);
The major number is then printed to dmesg
with:
printk(KERN_INFO
"[lainmemu][OK] registered with major device number %d.\n", (unsigned char) lainmemu_major);
I have a sysfs attribute that stores the major number. The show()
function for it is here:
static ssize_t lainmemu_major_show(const struct class * class,
const struct class_attribute * attr, char * buf) {
return sprintf(buf, "%d\n", (unsigned char) lainmemu_major);
}
dmesg
:
[lainmemu][OK] registered with major device number 246.
/proc/devices
:
[...]
246 lainmemu
[...]
sysfs
attribute:
# cat /sys/class/lainko/lainmemu_major
246
# hex 246
0xf6
# xxd /sys/class/lainko/lainmemu_major
00000000: 3234 360a 246.
However, when viewed with GDB:
(gdb) p lainmemu_major
$1 = 243 '\363'
(gdb) p/x lainmemu_major
$2 = 0xf3
As you can see the difference is only 3. I'm looking for ideas as to what could be causing this. I am confident the VM and my host GDB are running/looking at the exact same kernel and module.
I have tried restarting the VM, my host machine, recompiling the LKM. Problem always persists.
The fact that procfs
reports '246' makes me think its not a formatting problem caused by printf()
.
I am running Linux v6.10 using the default Debian config with various debug options enabled. Thanks for your time.
This appears to be a problem with GDB, although I have no idea what is causing it:
(gdb) p/x &lainmemu_major
$1 = 0xffffffffc0a89740
(gdb) p/x *0xffffffffc0a89740
$2 = 0xf6
(gdb) p/x lainmemu_major
$3 = 0xf3
QEMU invocation:
# kaslr disabled in GRUB config
exec qemu-system-x86_64 -s -S\
-enable-kvm \
-cpu host \
-drive file=debug_image.qcow2,format=qcow2 \
-m 2G \
-monitor stdio \
-name "debug_vm" \
-virtfs local,path=/home/vykt/projects/kernel/debug_vm/shared,mount_tag=hostshare,security_model=mapped-xattr \
"$@"
GDB invocation:
add-auto-load-safe-path /home/vykt/projects/kernel/linux-source-6.10/scripts/gdb/vmlinux-gdb.py
file ./vmlinux
target remote :1234
cont
[after kernel is running]
lx-symbols
LKM Makefile:
obj-m += lainko.o
all:
make -C /home/vykt/linux-source-6.10/ M=$(PWD) modules
clean:
make -C /home/vykt/linux-source-6.10/ M=$(PWD) clean
All global variables have incorrect addresses. Only function addresses are resolved correctly by GDB. /proc/kallsyms
and GDB do not match. I'm not sure why I thought they were the same when I checked this the first time.
While this problem looks much easier to fix, I am not sure why I got the GDB output that I did in my previous attempt.
Upvotes: 3
Views: 77