Skip to main content
KGDB (Kernel GNU Debugger) provides live source-level debugging of a running Qualcomm® Linux kernel. A host machine running GDB connects to the target device over a serial port and can set breakpoints, inspect registers, and step through kernel code, including for dynamically loaded modules.

Required kernel configuration

Enable the following Kconfig options and rebuild the kernel:
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_CONSOLE_POLL=y
CONFIG_MAGIC_SYSRQ=y
Verify on a running system:
zcat /proc/config.gz | grep -E "CONFIG_KGDB|CONFIG_MAGIC_SYSRQ|CONFIG_FRAME_POINTER"

Serial setup

KGDB communicates over a serial port using the kgdboc (KGDB over console) driver.

Kernel command-line parameters

Add the following to KERNEL_CMDLINE_EXTRA in meta-qcom/conf/machine/include/qcom-<SoC>.conf:
kgdboc=ttyMSM0,115200n8 kgdbwait nokaslr
ParameterEffect
kgdboc=ttyMSM0,115200n8Register ttyMSM0 at 115200 baud as the KGDB I/O channel
kgdbwaitPause the kernel during boot and wait for a GDB connection before proceeding. Omit this if you prefer to connect GDB at a later point using SysRq.
nokaslrDisable kernel address-space layout randomisation. Required for GDB symbol matching.

Disable the watchdog

The Qualcomm SoC watchdog resets the device if the kernel stops responding. Disable it before starting a KGDB session to prevent unexpected resets:
echo 1 > /sys/bus/platform/devices/hypervisor:qcom,gh-watchdog/disable

Enter debug mode

Choose one of the following methods to pause the kernel and activate the KGDB stub.

Method 1: kgdbwait (boot-time)

When kgdbwait is present on the kernel command line, the kernel stops during boot and prints the following message on the serial console:
[    0.239669] printk: console [ttyMSM0] enabled
[    1.541411] KGDB: Registered I/O driver kgdboc
[    2.224804] KGDB: Waiting for connection from remote gdb...
Connect GDB from the host before the kernel proceeds.

Method 2: Magic SysRq (runtime)

From a shell on the target:
echo g > /proc/sysrq-trigger
The kernel immediately suspends and waits for GDB.

Method 3: Compile-time breakpoint

Insert a hard breakpoint in driver source code:
#include <linux/kgdb.h>
kgdb_breakpoint();   /* kernel breaks here when this line is reached */
Rebuild and flash the kernel. The breakpoint fires when the code path executes.

Method 4: Kernel panic (exception-driven)

The kernel automatically enters KGDB mode when an unhandled exception or panic occurs. To deliberately trigger a crash for testing:
echo c > /proc/sysrq-trigger   # kernel panic → enters KGDB

Connect GDB from the host

Install gdb-multiarch on the host machine:
# Debian / Ubuntu
sudo apt install gdb-multiarch

# MSYS2 (Windows)
pacman -S mingw-w64-x86_64-gdb-multiarch

Linux host

gdb-multiarch -b 115200 <path_to_vmlinux>
(gdb) target remote /dev/ttyUSB0

Windows host

On Windows, set the COM port number above 16 in Device Manager and use the \\.\comN path syntax:
gdb-multiarch.exe -b 115200 <path_to_vmlinux>
(gdb) target remote \\.\com17
Expected output after connecting:
Remote debugging using \\.\com17
[Switching to Thread -2]
arch_kgdb_breakpoint () at arch/arm64/include/asm/kgdb.h:21

GDB debug session

Essential GDB commands

Table: GDB command reference
CommandDescription
btPrint a backtrace of the current call stack
break <function>Set a breakpoint at the start of a function
break <file>:<line>Set a breakpoint at a specific source line
info breakList all current breakpoints
info regDisplay all CPU registers
x/<n>x <addr>Examine n words of memory at address addr in hex
p <expression>Print the value of a C expression or variable
sStep one source line (step into function calls)
nNext source line (step over function calls)
cContinue execution until the next breakpoint or interrupt
finishRun until the current function returns
detachDetach from the target (kernel continues running)

Load module symbols

To debug a dynamically loaded kernel module, retrieve the .text section address from the target:
# On the target device
cat /sys/module/<module_name>/sections/.text
# Example output: 0xffff800008800000
Then load the symbol file in GDB:
(gdb) add-symbol-file <path_to_module.ko> 0xffff800008800000
Example:
(gdb) add-symbol-file drivers/net/ethernet/my_driver.ko 0xffff800008800000
(gdb) break my_driver_probe
(gdb) c
For the full upstream KGDB documentation, see Debugging kernel and modules via gdb.