vykt
vykt

Reputation: 93

Linux driver major number appears different across dmesg and gdb

PROBLEM:

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.

LKM CODE:

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 / PROCFS / SYSFS / GDB OUTPUT:

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

QUESTION:

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.

EDIT:

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

EDIT 2:

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

Answers (0)

Related Questions