[riot-notifications] [RIOT-OS/RIOT] tools/iotlab-testbed: add support for remote debugger (#16510)

Alexandre Abadie notifications at github.com
Fri May 28 19:47:24 CEST 2021


<!--
The RIOT community cares a lot about code quality.
Therefore, before describing what your contribution is about, we would like
you to make sure that your modifications are compliant with the RIOT
coding conventions, see https://github.com/RIOT-OS/RIOT/wiki/Coding-conventions.
-->

### Contribution description

This PR extends the IoT-LAB tooling support with the remote debugging facility provided by the testbed. The tools are wrapped inside the `debug` and `debug-server` make targets when the IOTLAB_NODE variable is used.

To start/stop the GDB server the nodes of an experiment, IoT-LAB cli-tools provide the `iotlab-node --debug-start` and `iotlab-node --debug-stop` commands and the GDB server can be reached on port 3333, either directly from the SSH frontend or via an SSH tunnel from the local computer.
This PR supports both use case.

All boards exceptt firefly, zigduino and iotlab-a8-m3 can use this feature.

<!--
Put here the description of your contribution:
- describe which part(s) of RIOT is (are) involved
- if it's a bug fix, describe the bug that it solves and how it is solved
- you can also give more information to reviewers about how to test your changes
-->


### Testing procedure

- Start an experiment on IoT-LAB:
```
$ iotlab-experiment submit -d 120 -l saclay,m3,2 -l saclay,nrf52dk,1 -l saclay,st-lrwan1,2
$ iotlab-experiment wait
```

- Start a debug session from your local computer:
```
$ BUILD_IN_DOCKER=1 make BOARD=nrf52dk -C examples/hello-world flash debug IOTLAB_NODE=auto --no-print-directory 
Launching build container using image "riot/riotbuild:latest".
docker run --rm --tty --user $(id -u) -v '/usr/share/zoneinfo/Europe/Paris:/etc/localtime:ro' -v '/work/riot/RIOT:/data/riotbuild/riotbase:delegated' -e 'RIOTBASE=/data/riotbuild/riotbase' -e 'CCACHE_BASEDIR=/data/riotbuild/riotbase' -e 'BUILD_DIR=/data/riotbuild/riotbase/build' -e 'RIOTPROJECT=/data/riotbuild/riotbase' -e 'RIOTCPU=/data/riotbuild/riotbase/cpu' -e 'RIOTBOARD=/data/riotbuild/riotbase/boards' -e 'RIOTMAKE=/data/riotbuild/riotbase/makefiles'      -e 'BOARD=nrf52dk'  -w '/data/riotbuild/riotbase/examples/hello-world/' 'riot/riotbuild:latest' make 'BOARD=nrf52dk'    
Building application "hello-world" for "nrf52dk" with MCU "nrf52".

"make" -C /data/riotbuild/riotbase/boards/nrf52dk
"make" -C /data/riotbuild/riotbase/boards/common/nrf52xxxdk
"make" -C /data/riotbuild/riotbase/core
"make" -C /data/riotbuild/riotbase/cpu/nrf52
"make" -C /data/riotbuild/riotbase/cpu/cortexm_common
"make" -C /data/riotbuild/riotbase/cpu/cortexm_common/periph
"make" -C /data/riotbuild/riotbase/cpu/nrf52/periph
"make" -C /data/riotbuild/riotbase/cpu/nrf52/vectors
"make" -C /data/riotbuild/riotbase/cpu/nrf5x_common
"make" -C /data/riotbuild/riotbase/cpu/nrf5x_common/periph
"make" -C /data/riotbuild/riotbase/drivers
"make" -C /data/riotbuild/riotbase/drivers/periph_common
"make" -C /data/riotbuild/riotbase/sys
"make" -C /data/riotbuild/riotbase/sys/auto_init
"make" -C /data/riotbuild/riotbase/sys/malloc_thread_safe
"make" -C /data/riotbuild/riotbase/sys/newlib_syscalls_default
"make" -C /data/riotbuild/riotbase/sys/stdio_uart
   text	   data	    bss	    dec	    hex	filename
   8380	    108	   2320	  10808	   2a38	/data/riotbuild/riotbase/examples/hello-world/bin/nrf52dk/hello-world.elf
iotlab-node --jmespath='keys(@)[0]' --format='lambda ret: exit(int(ret))'  --list saclay,nrf52dk,1 --flash /work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.bin
/work/riot/RIOT/dist/testbed-support/iotlab-debug.sh "nrf52dk-1" "--list saclay,nrf52dk,1" "abadie at saclay.iot-lab.info" "" "/work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.elf"
Reading symbols from /work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.elf...
Remote debugging using localhost:3333
cortexm_init_fpu () at /data/riotbuild/riotbase/cpu/cortexm_common/include/cpu.h:104
104	/data/riotbuild/riotbase/cpu/cortexm_common/include/cpu.h: No such file or directory.
(gdb) load
Loading section .text, size 0x20bc lma 0x0
Loading section .relocate, size 0x6c lma 0x20bc
Start address 0x00000670, load size 8488
Transfer rate: 10 KB/sec, 4244 bytes/write.
(gdb) b main
Breakpoint 1 at 0xdc: file /data/riotbuild/riotbase/examples/hello-world/main.c, line 26.
Note: automatically using hardware breakpoints for read-only addresses.
(gdb) c
Continuing.

Breakpoint 1, main () at /data/riotbuild/riotbase/examples/hello-world/main.c:26
26	    puts("Hello World!");
(gdb) l
21	
22	#include <stdio.h>
23	
24	int main(void)
25	{
26	    puts("Hello World!");
27	
28	    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
29	    printf("This board features a(n) %s MCU.\n", RIOT_MCU);
30	
quit) 
A debugging session is active.

	Inferior 1 [Remote target] will be detached.

EOF [assumed Y] or n) 
Detaching from program: /work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.elf, Remote target
Ending remote debugging.
[Inferior 1 (Remote target) detached]
```

- After a debug session is finished, verify that the node can be reflashed (to verify that the GDB server is stopped):
```
$ BUILD_IN_DOCKER=1 make BOARD=nrf52dk -C examples/hello-world flash-only IOTLAB_NODE=auto --no-print-directory 
iotlab-node --jmespath='keys(@)[0]' --format='lambda ret: exit(int(ret))'  --list saclay,nrf52dk,1 --flash /work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.bin
$ echo $?
0
```

- Start a debug-server and in a second terminal, use gdb manually:
```
$ make BOARD=nrf52dk -C examples/hello-world debug-server IOTLAB_NODE=auto --no-print-directory /work/riot/RIOT/dist/testbed-support/iotlab-debug.sh "nrf52dk-1" "--list saclay,nrf52dk,1" "abadie at saclay.iot-lab.info" "" "" "1"
...
$ arm-none-eabi-gdb /work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.elf
GNU gdb (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 8.3.0.20190709-git
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.elf...
(gdb) target remote :3333
Remote debugging using :3333
cortexm_init_fpu () at /work/riot/RIOT/cpu/cortexm_common/include/cpu.h:104
104	    SCB->CPACR |= (uint32_t)CORTEXM_SCB_CPACR_FPU_ACCESS_FULL;
(gdb) load
Loading section .text, size 0x20bc lma 0x0
Loading section .relocate, size 0x6c lma 0x20bc
Start address 0x670, load size 8488
Transfer rate: 10 KB/sec, 4244 bytes/write.
(gdb) b main
Breakpoint 1 at 0xdc: file /work/riot/RIOT/examples/hello-world/main.c, line 26.
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, main () at /work/riot/RIOT/examples/hello-world/main.c:26
26	    puts("Hello World!");
(gdb) l
21	
22	#include <stdio.h>
23	
24	int main(void)
25	{
26	    puts("Hello World!");
27	
28	    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
29	    printf("This board features a(n) %s MCU.\n", RIOT_MCU);
30	
(gdb) quit
A debugging session is active.

	Inferior 1 [Remote target] will be detached.

Quit anyway? (y or n) EOF [assumed Y]
Detaching from program: /work/riot/RIOT/examples/hello-world/bin/nrf52dk/hello-world.elf, Remote target
Ending remote debugging.
[Inferior 1 (Remote target) detached]
```

The same procedure also works from an IoT-LAB frontend (didn't try with `BUILD_IN_DOCKER=1` though).

<!--
Details steps to test your contribution:
- which test/example to compile for which board and is there a 'test' command
- how to know that it was not working/available in master
- the expected success test output
-->


### Issues/PRs references

Tick the debugger item in #9694

<!--
Examples: Fixes #1234. See also #5678. Depends on PR #9876.

Please use keywords (e.g., fixes, resolve) with the links to the issues you
resolved, this way they will be automatically closed when your pull request
is merged. See https://help.github.com/articles/closing-issues-using-keywords/.
-->

You can view, comment on, or merge this pull request online at:

  https://github.com/RIOT-OS/RIOT/pull/16510

-- Commit Summary --

  * tools/iotlab-testbed: add support for remote debugging

-- File Changes --

    A dist/testbed-support/iotlab-debug.sh (67)
    M dist/testbed-support/makefile.iotlab.single.inc.mk (20)

-- Patch Links --

https://github.com/RIOT-OS/RIOT/pull/16510.patch
https://github.com/RIOT-OS/RIOT/pull/16510.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/16510
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20210528/245af105/attachment-0001.htm>


More information about the notifications mailing list