GDB cannot inherently catch breakpoints on the init and exit functions of a module like it can the other functions that are meant for servicing system calls on a device node (e.g. opening, reading, or writing a device). I suspect it has to do with which portion of the process's address space they are stored in, but I am not sure.
Further complicating the matter is the fact that modules are loaded at randomized addresses each time - regardless of nokaslr or whether they are statically built or dynamically inserted into the kernel (with nokaslr, the core part of the kernel will be loaded into the same address space all the time, but the modules won't). Therefore, you cannot simply load the module, set a breakpoint on the init symbol's current address, and reload the module. However, there is a solution:
Like Ciro says in approach 2 of his answer, you need to set a breakpoint on the kernel core's do_init_module function, which is called every time any module is loaded. Since it is part of that core kernel code I mentioned, gdb will know its correct location. From there, instead of stepping lots of times (possibly hundreds, from my attempt), follow the instructions at this recent webpost I found:
https://sysprogs.com/VisualKernel/documentation/kernelsymbols/