## 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 remote localhost:3333

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

2. A pipe connection is typically started as follows:

                 target 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 examples 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 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.

Another example of useful GDB configuration came from a user who found that single stepping his Cortex-M3 didn't work well with IRQs and an RTOS until he told GDB to disable the IRQs while stepping:

         define hook-step
         mon cortex_m3 maskisr on
         end
         define hookpost-step
         mon cortex_m3 maskisr off
         end

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, an event script can be executed:

         $_TARGETNAME configure -event EVENTNAME BODY

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

### 20.5 Using openocd SMP with GDB

For SMP support following GDB serial protocol packet have been defined :

- j - smp status request
- J - smp set request

OpenOCD implements :

- `jc` packet for reading core id displayed by GDB connection. Reply is `XXXXXXXX` (8 hex digits giving core id) or `E01` for target not smp.
- `JcXXXXXXXX` (8 hex digits) packet for setting core id displayed at next GDB continue (core id -1 is reserved for returning to normal resume mode). Reply `E01` for target not smp or `OK` on success.

Handling of this packet within GDB can be done :

- by the creation of an internal variable (i.e `_core`) by mean of function allocate_computed_value allowing following GDB command.

                set $_core 1
                #Jc01 packet is sent
                print $_core
                #jc packet is sent and result is affected in $

- by the usage of GDB maintenance command as described in following example (2 cpus in SMP with core id 0 and 1 see Define CPU targets working in SMP).

                # toggle0 : force display of coreid 0
                define toggle0
                maint packet Jc0
                continue
                main packet Jc-1
                end
                # toggle1 : force display of coreid 1
                define toggle1
                maint packet Jc1
                continue
                main packet Jc-1
                end