1.. _gdbstub: 2 3GDB stub 4######## 5 6.. contents:: 7 :local: 8 :depth: 2 9 10Overview 11******** 12 13The gdbstub feature provides an implementation of the GDB Remote 14Serial Protocol (RSP) that allows you to remotely debug Zephyr 15using GDB. 16 17The protocol supports different connection types: serial, UDP/IP and 18TCP/IP. Zephyr currently supports only serial device communication. 19 20The GDB program acts as a client while the Zephyr gdbstub acts as a 21server. When this feature is enabled, Zephyr stops its execution after 22:c:func:`gdb_init` starts gdbstub service and waits for a GDB 23connection. Once a connection is established it is possible to 24synchronously interact with Zephyr. Note that currently it is not 25possible to asynchronously send commands to the target. 26 27Features 28******** 29 30The following features are supported: 31 32* Add and remove breakpoints 33* Continue and step the target 34* Print backtrace 35* Read or write general registers 36* Read or write the memory 37 38Enabling GDB Stub 39***************** 40 41GDB stub can be enabled with the :kconfig:option:`CONFIG_GDBSTUB` option. 42 43Using Serial Backend 44==================== 45 46The serial backend for GDB stub can be enabled with 47the :kconfig:option:`CONFIG_GDBSTUB_SERIAL_BACKEND` option. 48 49Since serial backend utilizes UART devices to send and receive GDB commands, 50 51* If there are spare UART devices on the board, set ``zephyr,gdbstub-uart`` 52 property of the chosen node to the spare UART device so that :c:func:`printk` 53 and log messages are not being printed to the same UART device used for GDB. 54 55* For boards with only one UART device, :c:func:`printk` and logging 56 must be disabled if they are also using the same UART device for output. 57 GDB related messages may interleave with log messages which may have 58 unintended consequences. Usually this can be done by disabling 59 :kconfig:option:`CONFIG_PRINTK` and :kconfig:option:`CONFIG_LOG`. 60 61Debugging 62********* 63 64Using Serial Backend 65==================== 66 67#. Build with GDB stub and serial backend enabled. 68 69#. Flash built image onto board and reset the board. 70 71 * Execution should now be paused at :c:func:`gdb_init`. 72 73#. Execute GDB on development machine and connect to the GDB stub. 74 75 .. code-block:: bash 76 77 target remote <serial device> 78 79 For example, 80 81 .. code-block:: bash 82 83 target remote /dev/ttyUSB1 84 85#. GDB commands can be used to start debugging. 86 87Example 88******* 89 90There is a test application :zephyr_file:`tests/subsys/debug/gdbstub` with one of its 91test cases ``debug.gdbstub.breakpoints`` demonstrating how the Zephyr GDB stub can be used. 92The test also has a case to connect to the QEMU's GDB stub implementation (at a custom 93port ``tcp:1235``) as a reference to validate the test script itself. 94 95Run the test with the following command from your :envvar:`ZEPHYR_BASE` directory: 96 97 .. code-block:: console 98 99 ./scripts/twister -p qemu_x86 -T tests/subsys/debug/gdbstub 100 101The test should run successfully, and now let's do something similar step-by-step 102to demonstrate how the Zephyr GDB stub works from the GDB user's perspective. 103 104In the snippets below use and expect your appropriate directories instead of 105``<SDK install directory>``, ``<build_directory>``, ``<ZEPHYR_BASE>``. 106 107 108#. Open two terminal windows. 109 110#. On the first terminal, build and run the test application: 111 112 .. zephyr-app-commands:: 113 :zephyr-app: tests/subsys/debug/gdbstub 114 :host-os: unix 115 :board: qemu_x86 116 :gen-args: '-DCONFIG_QEMU_EXTRA_FLAGS="-serial tcp:localhost:5678,server"' 117 :goals: build run 118 119 Note how we set :kconfig:option:`CONFIG_QEMU_EXTRA_FLAGS` to direct QEMU serial 120 console port to the ``localhost`` TCP port ``5678`` to wait for a connection 121 from the GDB ``remote`` command we are going to do on the next steps. 122 123#. On the second terminal, start GDB: 124 125 .. code-block:: bash 126 127 <SDK install directory>/x86_64-zephyr-elf/bin/x86_64-zephyr-elf-gdb 128 129 #. Tell GDB where to look for the built ELF file: 130 131 .. code-block:: text 132 133 (gdb) symbol-file <build directory>/zephyr/zephyr.elf 134 135 Response from GDB: 136 137 .. code-block:: text 138 139 Reading symbols from <build directory>/zephyr/zephyr.elf... 140 141 #. Tell GDB to connect to the Zephyr gdbstub serial backend which is exposed 142 earlier as a server through the TCP port ``-serial`` redirection at QEMU. 143 144 .. code-block:: text 145 146 (gdb) target remote localhost:5678 147 148 Response from GDB: 149 150 .. code-block:: text 151 152 Remote debugging using localhost:5678 153 arch_gdb_init () at <ZEPHYR_BASE>/arch/x86/core/ia32/gdbstub.c:252 154 252 } 155 156 GDB also shows where the code execution is stopped. In this case, 157 it is at :zephyr_file:`arch/x86/core/ia32/gdbstub.c`, line 252. 158 159 #. Use command ``bt`` or ``backtrace`` to show the backtrace of stack frames. 160 161 .. code-block:: text 162 163 (gdb) bt 164 #0 arch_gdb_init () at <ZEPHYR_BASE>/arch/x86/core/ia32/gdbstub.c:252 165 #1 0x00104140 in gdb_init () at <ZEPHYR_BASE>/zephyr/subsys/debug/gdbstub.c:852 166 #2 0x00109c13 in z_sys_init_run_level (level=INIT_LEVEL_PRE_KERNEL_2) at <ZEPHYR_BASE>/kernel/init.c:360 167 #3 0x00109e73 in z_cstart () at <ZEPHYR_BASE>/kernel/init.c:630 168 #4 0x00104422 in z_prep_c (arg=0x1245bc <x86_cpu_boot_arg>) at <ZEPHYR_BASE>/arch/x86/core/prep_c.c:80 169 #5 0x001000c9 in __csSet () at <ZEPHYR_BASE>/arch/x86/core/ia32/crt0.S:290 170 #6 0x001245bc in uart_dev () 171 #7 0x00134988 in z_interrupt_stacks () 172 #8 0x00000000 in ?? () 173 174 #. Use command ``list`` to show the source code and surroundings where 175 code execution is stopped. 176 177 .. code-block:: text 178 179 (gdb) list 180 247 __asm__ volatile ("int3"); 181 248 182 249 #ifdef CONFIG_GDBSTUB_TRACE 183 250 printk("gdbstub:%s GDB is connected\n", __func__); 184 251 #endif 185 252 } 186 253 187 254 /* Hook current IDT. */ 188 255 _EXCEPTION_CONNECT_NOCODE(z_gdb_debug_isr, IV_DEBUG, 3); 189 256 _EXCEPTION_CONNECT_NOCODE(z_gdb_break_isr, IV_BREAKPOINT, 3); 190 191 #. Use command ``s`` or ``step`` to step through program until it reaches 192 a different source line. Now that it finished executing :c:func:`arch_gdb_init` 193 and is continuing in :c:func:`gdb_init`. 194 195 .. code-block:: text 196 197 (gdb) s 198 gdb_init () at <ZEPHYR_BASE>/subsys/debug/gdbstub.c:857 199 857 return 0; 200 201 .. code-block:: text 202 203 (gdb) list 204 852 arch_gdb_init(); 205 853 206 854 #ifdef CONFIG_GDBSTUB_TRACE 207 855 printk("gdbstub:%s exit\n", __func__); 208 856 #endif 209 857 return 0; 210 858 } 211 859 212 860 #ifdef CONFIG_XTENSA 213 861 /* 214 215 #. Use command ``br`` or ``break`` to setup a breakpoint. For this example 216 set up a breakpoint at :c:func:`main`, and let code execution continue 217 without any intervention using command ``c`` (or ``continue``). 218 219 .. code-block:: text 220 221 (gdb) break main 222 Breakpoint 1 at 0x10064d: file <ZEPHYR_BASE>/tests/subsys/debug/gdbstub/src/main.c, line 27. 223 224 .. code-block:: text 225 226 (gdb) continue 227 Continuing. 228 229 Once code execution reaches :c:func:`main`, execution will be stopped 230 and GDB prompt returns. 231 232 .. code-block:: text 233 234 Breakpoint 1, main () at <ZEPHYR_BASE>/tests/subsys/debug/gdbstub/src/main.c:27 235 27 printk("%s():enter\n", __func__); 236 237 Now GDB is waiting at the beginning of :c:func:`main`: 238 239 .. code-block:: text 240 241 (gdb) list 242 22 243 23 int main(void) 244 24 { 245 25 int ret; 246 26 247 27 printk("%s():enter\n", __func__); 248 28 ret = test(); 249 29 printk("ret=%d\n", ret); 250 30 return 0; 251 31 } 252 253 #. To examine the value of ``ret``, the command ``p`` or ``print`` 254 can be used. 255 256 .. code-block:: text 257 258 (gdb) p ret 259 $1 = 1273788 260 261 Since ``ret`` has not been initialized, it contains some random value. 262 263 #. If step (``s`` or ``step``) is used here, it will continue execution 264 skipping the interior of :c:func:`test`. 265 To examine code execution inside :c:func:`test`, 266 a breakpoint can be set for :c:func:`test`, or simply using 267 ``si`` (or ``stepi``) to execute one machine instruction, where it has 268 the side effect of going into the function. The GDB command ``finish`` 269 can be used to continue execution without intervention until the function 270 returns. 271 272 .. code-block:: text 273 274 (gdb) finish 275 Run till exit from #0 test () at <ZEPHYR_BASE>/tests/subsys/debug/gdbstub/src/main.c:17 276 0x00100667 in main () at <ZEPHYR_BASE>/tests/subsys/debug/gdbstub/src/main.c:28 277 28 ret = test(); 278 Value returned is $2 = 30 279 280 #. Examine ``ret`` again which should have the return value from 281 :c:func:`test`. Sometimes, the assignment is not done until another 282 ``step`` is issued, as in this case. This is due to the assignment 283 code is done after returning from function. The assignment code is 284 generated by the toolchain as machine instructions which are not 285 visible when viewing the corresponding C source file. 286 287 .. code-block:: text 288 289 (gdb) p ret 290 $3 = 1273788 291 (gdb) step 292 29 printk("ret=%d\n", ret); 293 (gdb) p ret 294 $4 = 30 295 296 #. If ``continue`` is issued here, code execution will continue indefinitely 297 as there are no breakpoints to further stop execution. Breaking execution 298 in GDB via :kbd:`Ctrl-C` does not currently work as the Zephyr gdbstub does 299 not support this functionality yet. Switch to the first console with QEMU 300 running the Zephyr image and stop it manually with :kbd:`Ctrl+a x`. 301 When the same test is executed by Twister, it automatically takes care of 302 stopping the QEMU instance. 303