---
title: "Debug on the board"
---

# Debug on the board

F5 copies the application to the board and debugs it through gdbserver over SSH with the SDK's GDB and sysroot; forks and execs, attach to a running process, and core dumps opened with the build's symbols.

Application debugging uses gdbserver in the image (`tools-debug` in `EXTRA_IMAGE_FEATURES`) and the SDK's cross GDB, through the shared Embedded debug session.

**State:** modelled with gdbserver and GDB 15.1, OpenSSH 9.6p1 and two SSH servers on one Linux machine, an x86_64 stand-in SDK and board: launch with GDB on the build host and locally, exit code, attach and detach, an 8.86 MB core sent as 28.6 KB, a missing gdbserver; fork and exec tests; the board scripts on BusyBox 1.36.1; the running app. Not run on a real board with a cross (aarch64) SDK, on Windows, or against a real build server over a WAN (estimated 0.5 to 1.8 s per step at a 30 ms round trip). Memory, disassembly and instruction breakpoints are off on 64-bit targets, because the shared Embedded session writes 32-bit addresses.

## Debug with F5

1. Select the application (see [SDK applications](https://neuralinverse.com/docs/modules/embedded-linux/sdk-applications/)) and a board in Targets.
2. Set a breakpoint and press **F5** (the configuration **Debug Application on Target**).
3. Confirm the copy: the dialog names the board and the path (`/tmp/ni-debug` by default).
4. gdbserver `--once` starts on the board's loopback, forwarded through the board's SSH session. The SDK's GDB runs on the build host (through a reverse forward) or on this machine, with the SDK's target sysroot, debug folder and substitute-path, and paths mapped to the working copy.
5. Breakpoints, stepping, variables, threads and the call stack work as usual; signals stop as exceptions. **Stop** ends the program and gdbserver.

At the end of a session every debugged process is killed (launch) or detached (attach), and children GDB let run are stopped on the board.

## Launch configurations

The debug type is `ni-embedded-linux`. The snippets are **Embedded Linux: Debug Application on Target** and **Embedded Linux: Attach to Process on Target**. Attributes:

| Attribute | Meaning |
|---|---|
| `application` | The application from `neuralInverse.embeddedLinux.applications`; the selected one by default |
| `target`, `program`, `args`, `cwd`, `environment` | The board, the program and how it runs there |
| `deploy`, `deployDirectory` | Whether and where the program is copied first |
| `gdbserver` | gdbserver on the board |
| `sysroot` | GDB's sysroot; the SDK's target sysroot by default |
| `sourceMap` | GDB's substitute-path; `/usr/src/debug` maps to the sysroot's sources by default |
| `connectCommands` | GDB commands to run once connected |
| `followForkMode` | `parent` (default) or `child`: which process the debugger stays with after a fork; an exec is followed |
| `detachOnFork` | `false` debugs both processes together, threads named per process |
| `runToEntryPoint` | Where the launch stops first (`main`) |
| `processId`, `processName` | The process to attach to |
| `coreFile` | A core dump to open |

With both processes kept after a fork, a worker's exit is reported and the session continues.

## Attach to a running process

**Attach to Process on Target...** lists the board's processes; pick one and confirm. Detaching leaves it running.

## Core dumps

**Open Core Dump...** lists core files on the board (with `kernel.core_pattern`) or takes a path, copies the core (compressed for the copy) after a confirmation, and opens it in GDB with the application's symbols and the SDK sysroot: the signal, the threads and the backtrace.

## Agent tools

Listing debug sessions, processes and core dumps is read-only; starting a session and fetching a core always ask first.

Next: [Kernel configuration and crash reports](https://neuralinverse.com/docs/modules/embedded-linux/kernel/).
