The debugger needs access to the debug symbols

Debug symbols are generated during the compilation process and contain information about the program's executable code and data, such as function and variable names, types, and memory addresses. They help the debugger map the program's machine code back to the original source code and provide meaningful debugging information.

When the debugger is instructed to set a breakpoint on e.g. a function foo, it needs to look up which address corresponds to that symbol. This and some further information is encoded into the compile output artifact, no matter if it is an executable, a shared library/object, the Linux kernel, or a kernel module.

The compiler can be instructed to add debug info by adding the compile flag -g or even better for debugging with GDB with -ggdb adds some more GDB-specific debug info.

Further, the debug info doesn’t need to be included to just execute the above-stated artifacts without debugging. Moreover, for Linux BSPs, it’s a common practice to compile the whole BSP with -g first and then remove that symbols before installation on the target system to reduce memory footprint drastically while keeping an untouched copy inside the BSP and/or the SDK on the development host for debugging purposes. Otherwise, the debug symbols consume a lot of disk space on the target device. This process is known as stripping and it is done by a tool called <compiler-prefix>-strip. So it’s reasonable, that native debugging on the target device is not possible without further steps to make the symbols available to the debugger.