> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kernel debugger (KGDB)

KGDB (Kernel GNU Debugger) provides live source-level debugging of a running
Qualcomm<sup>®</sup> 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:

```text theme={null}
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:

```bash theme={null}
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`:

```text theme={null}
kgdboc=ttyMSM0,115200n8 kgdbwait nokaslr
```

| **Parameter**             | **Effect**                                                                                                                                         |
| :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------- |
| `kgdboc=ttyMSM0,115200n8` | Register `ttyMSM0` at 115200 baud as the KGDB I/O channel                                                                                          |
| `kgdbwait`                | Pause 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. |
| `nokaslr`                 | Disable 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:

```bash theme={null}
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:

```text theme={null}
[    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:

```bash theme={null}
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:

```c theme={null}
#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:

```bash theme={null}
echo c > /proc/sysrq-trigger   # kernel panic → enters KGDB
```

## **Connect GDB from the host**

Install `gdb-multiarch` on the host machine:

```bash theme={null}
# Debian / Ubuntu
sudo apt install gdb-multiarch

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

### Linux host

```bash theme={null}
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:

```text theme={null}
gdb-multiarch.exe -b 115200 <path_to_vmlinux>
(gdb) target remote \\.\com17
```

Expected output after connecting:

```text theme={null}
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**

| **Command**           | **Description**                                           |
| :-------------------- | :-------------------------------------------------------- |
| `bt`                  | Print 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 break`          | List all current breakpoints                              |
| `info reg`            | Display 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             |
| `s`                   | Step one source line (step into function calls)           |
| `n`                   | Next source line (step over function calls)               |
| `c`                   | Continue execution until the next breakpoint or interrupt |
| `finish`              | Run until the current function returns                    |
| `detach`              | Detach from the target (kernel continues running)         |

### Load module symbols

To debug a dynamically loaded kernel module, retrieve the `.text` section
address from the target:

```bash theme={null}
# On the target device
cat /sys/module/<module_name>/sections/.text
# Example output: 0xffff800008800000
```

Then load the symbol file in GDB:

```gdb theme={null}
(gdb) add-symbol-file <path_to_module.ko> 0xffff800008800000
```

Example:

```gdb theme={null}
(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](https://docs.kernel.org/process/debugging/gdb-kernel-debugging.html).
