## 20 GDB and OpenOCD ¶

OpenOCD complies with the remote gdbserver protocol and, as such, can be used to debug remote targets. Setting up GDB to work with OpenOCD can involve several components:

- The OpenOCD server support for GDB may need to be configured. See GDB Configuration.
- GDB’s support for OpenOCD may need configuration, as shown in this chapter.
- If you have a GUI environment like Eclipse, that also will probably need to be configured.

Of course, the version of GDB you use will need to be one which has been built to know about the target CPU you’re using. It’s probably part of the tool chain you’re using. For example, if you are doing cross-development for ARM on an x86 PC, instead of using the native x86 `gdb` command you might use `arm-none-eabi-gdb` if that’s the tool chain used to compile your code.

### 20.1 Connecting to GDB ¶

Use GDB 6.7 or newer with OpenOCD if you run into trouble. For instance GDB 6.3 has a known bug that produces bogus memory access errors, which has since been fixed; see http://osdir.com/ml/gdb.bugs.discuss/2004-12/msg00018.html

OpenOCD can communicate with GDB in two ways:

1. A socket (TCP/IP) connection is typically started as follows:

       target extended-remote localhost:3333

   This would cause GDB to connect to the gdbserver on the local pc using port 3333.

   The extended remote protocol is a super-set of the remote protocol and should be the preferred choice. More details are available in GDB documentation https://sourceware.org/gdb/onlinedocs/gdb/Connecting.html

   To speed-up typing, any GDB command can be abbreviated, including the extended remote command above that becomes:

       tar ext :3333

   Note: If any backward compatibility issue requires using the old remote protocol in place of the extended remote one, the former protocol is still available through the command:

       target remote localhost:3333

2. A pipe connection is typically started as follows:

       target extended-remote | \
              openocd -c "gdb_port pipe; log_output openocd.log"

   This would cause GDB to run OpenOCD and communicate using pipes (stdin/stdout). Using this method has the advantage of GDB starting/stopping OpenOCD for the debug session. log_output sends the log output to a file to ensure that the pipe is not saturated when using higher debug level outputs.

To list the available OpenOCD commands type `monitor help` on the GDB command line.

### 20.2 Sample GDB session startup ¶

With the remote protocol, GDB sessions start a little differently than they do when you’re debugging locally. Here’s an example showing how to start a debug session with a small ARM program. In this case the program was linked to be loaded into SRAM on a Cortex-M3. Most programs would be written into flash (address 0) and run from there.

    $ arm-none-eabi-gdb example.elf
    (gdb) target extended-remote localhost:3333
    Remote debugging using localhost:3333
    ...
    (gdb) monitor reset halt
    ...
    (gdb) load
    Loading section .vectors, size 0x100 lma 0x20000000
    Loading section .text, size 0x5a0 lma 0x20000100
    Loading section .data, size 0x18 lma 0x200006a0
    Start address 0x2000061c, load size 1720
    Transfer rate: 22 KB/sec, 573 bytes/write.
    (gdb) continue
    Continuing.
    ...

You could then interrupt the GDB session to make the program break, type `where` to show the stack, `list` to show the code around the program counter, `step` through code, set breakpoints or watchpoints, and so on.

### 20.3 Configuring GDB for OpenOCD ¶

OpenOCD supports the gdb `qSupported` packet, this enables information to be sent by the GDB remote server (i.e. OpenOCD) to GDB. Typical information includes packet size and the device’s memory map. You do not need to configure the packet size by hand, and the relevant parts of the memory map should be automatically set up when you declare (NOR) flash banks.

However, there are other things which GDB can’t currently query. You may need to set those up by hand. As OpenOCD starts up, you will often see a line reporting something like:

    Info : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints

You can pass that information to GDB with these commands:

    set remote hardware-breakpoint-limit 6
    set remote hardware-watchpoint-limit 4

With that particular hardware (Cortex-M3) the hardware breakpoints only work for code running from flash memory. Most other ARM systems do not have such restrictions.

Rather than typing such commands interactively, you may prefer to save them in a file and have GDB execute them as it starts, perhaps using a `.gdbinit` in your project directory or starting GDB using `gdb -x filename`.

### 20.4 Programming using GDB ¶

By default the target memory map is sent to GDB. This can be disabled by the following OpenOCD configuration option:

    gdb_memory_map disable

For this to function correctly a valid flash configuration must also be set in OpenOCD. For faster performance you should also configure a valid working area.

Informing GDB of the memory map of the target will enable GDB to protect any flash areas of the target and use hardware breakpoints by default. This means that the OpenOCD option `gdb_breakpoint_override` is not required when using a memory map. See gdb_breakpoint_override.

To view the configured memory map in GDB, use the GDB command `info mem`. All other unassigned addresses within GDB are treated as RAM.

GDB 6.8 and higher set any memory area not in the memory map as inaccessible. This can be changed to the old behaviour by using the following GDB command

    set mem inaccessible-by-default off

If `gdb_flash_program enable` is also used, GDB will be able to program any flash memory using the vFlash interface.

GDB will look at the target memory map when a load command is given, if any areas to be programmed lie within the target flash area the vFlash packets will be used.

If the target needs configuring before GDB programming, set target event gdb-flash-erase-start:

    $_TARGETNAME configure -event gdb-flash-erase-start BODY

See Target Events, for other GDB programming related events.

To verify any flash programming the GDB command `compare-sections` can be used.

### 20.5 Using GDB as a non-intrusive memory inspector ¶

If your project controls more than a blinking LED, let’s say a heavy industrial robot or an experimental nuclear reactor, stopping the controlling process just because you want to attach GDB is not a good option.

OpenOCD does not support GDB non-stop mode (might be implemented in the future). Though there is a possible setup where the target does not get stopped and GDB treats it as it were running. If the target supports background access to memory while it is running, you can use GDB in this mode to inspect memory (mainly global variables) without any intrusion of the target process.

Remove default setting of gdb-attach event. See Target Events. Place following command after target configuration:

    $_TARGETNAME configure -event gdb-attach {}

If any of installed flash banks does not support probe on running target, switch off gdb_memory_map:

    gdb_memory_map disable

Ensure GDB is configured without interrupt-on-connect. Some GDB versions set it by default, some does not.

    set remote interrupt-on-connect off

If you switched gdb_memory_map off, you may want to setup GDB memory map manually or issue `set mem inaccessible-by-default off`

Now you can issue GDB command `target extended-remote ...` and inspect memory of a running target. Do not use GDB commands `continue`, `step` or `next` as they synchronize GDB with your target and GDB would require stopping the target to get the prompt back.

Do not use this mode under an IDE like Eclipse as it caches values of previously shown variables.

It’s also possible to connect more than one GDB to the same target by the target’s configuration option `-gdb-max-connections`. This allows, for example, one GDB to run a script that continuously polls a set of variables while other GDB can be used interactively. Be extremely careful in this case, because the two GDB can easily get out-of-sync.

### 20.6 RTOS Support ¶

OpenOCD includes RTOS support, this will however need enabling as it defaults to disabled. It can be enabled by passing `-rtos` arg to the target. See RTOS Type.

See Debugging Programs with Multiple Threads in GDB manual, for details about relevant GDB commands.

An example setup is below:

    $_TARGETNAME configure -rtos auto

This will attempt to auto detect the RTOS within your application.

Currently supported rtos’s include:

- `eCos`
- `ThreadX`
- `FreeRTOS`
- `linux`
- `ChibiOS`
- `embKernel`
- `mqx`
- `uCOS-III`
- `nuttx`
- `RIOT`
- `hwthread` (This is not an actual RTOS. See Using OpenOCD SMP with GDB.)
- `Zephyr`

At any time, it’s possible to drop the selected RTOS using:

    $_TARGETNAME configure -rtos none

Before an RTOS can be detected, it must export certain symbols; otherwise, it cannot be used by OpenOCD. Below is a list of the required symbols for each supported RTOS.

`eCos symbols`

  Cyg_Thread::thread_list, Cyg_Scheduler_Base::current_thread.

`ThreadX symbols`

  _tx_thread_current_ptr, _tx_thread_created_ptr, _tx_thread_created_count.

`FreeRTOS symbols`

  pxCurrentTCB, pxReadyTasksLists, xDelayedTaskList1, xDelayedTaskList2, pxDelayedTaskList, pxOverflowDelayedTaskList, xPendingReadyList, uxCurrentNumberOfTasks, uxTopUsedPriority.

`linux symbols`

  init_task.

`ChibiOS symbols`

  rlist, ch_debug, chSysInit.

`embKernel symbols`

  Rtos::sCurrentTask, Rtos::sListReady, Rtos::sListSleep, Rtos::sListSuspended, Rtos::sMaxPriorities, Rtos::sCurrentTaskCount.

`mqx symbols`

  _mqx_kernel_data, MQX_init_struct.

`uC/OS-III symbols`

  OSRunning, OSTCBCurPtr, OSTaskDbgListPtr, OSTaskQty.

`nuttx symbols`

  g_readytorun, g_tasklisttable.

`RIOT symbols`

  sched_threads, sched_num_threads, sched_active_pid, max_threads, _tcb_name_offset.

`Zephyr symbols`

  _kernel, _kernel_openocd_offsets, _kernel_openocd_size_t_size

For most RTOS supported the above symbols will be exported by default. However for some, eg. FreeRTOS, uC/OS-III and Zephyr, extra steps must be taken.

Zephyr must be compiled with the DEBUG_THREAD_INFO option. This will generate some symbols with information needed in order to build the list of threads.

FreeRTOS and uC/OS-III RTOSes may require additional OpenOCD-specific file to be linked along with the project:

`FreeRTOS`

  contrib/rtos-helpers/FreeRTOS-openocd.c

`uC/OS-III`

  contrib/rtos-helpers/uCOS-III-openocd.c

### 20.7 Using OpenOCD SMP with GDB ¶

OpenOCD includes a pseudo RTOS called hwthread that presents CPU cores ("hardware threads") in an SMP system as threads to GDB. With this extension, GDB can be used to inspect the state of an SMP system in a natural way. After halting the system, using the GDB command `info threads` will list the context of each active CPU core in the system. GDB’s `thread` command can be used to switch the view to a different CPU core. The `step` and `stepi` commands can be used to step a specific core while other cores are free-running or remain halted, depending on the scheduler-locking mode configured in GDB.