Python API for supplying thread information?

Freddie Chopin
2017-03-22T09:43:22Z

Hello!

The idea I'm asking about is related to the Pretty Printing API in
Python, which allows one to extend behaviour of GDB completely on
"client side" - there's absolutely no need to modify any component of
the toolchain to print your own types in any way you like.

It would be really great if something like this existed for _supplying_
thread information to GDB. I'm not talking about the Python API to
_query_ GDB about threads.
( https://sourceware.org/gdb/onlinedocs/gdb/Threads-In-Python.html ).

Such feature may seem completely unimportant if you work with PC only,
as there are just a few "old" operating systems and they are all
handled perfectly fine by GDB and the toolchains, so there's no need to
add/extend/modify anything here.

But the situation looks completely different on deeply embedded
platforms and I'm talking about microcontrollers here (like chips with
ARM Cortex-M3 core). There are hundreds of RTOSes for that platforms
and each is slightly different, so it's not possible to handle them all
(or even some part of them) with some common tool in a generic way.

Currently for RTOSes running on ARM the "solution" is provided by
OpenOCD project. OpenOCD is a "GDB server" which communicates with the
embedded target via JTAG interface and allows debugging such devices
with GDB. Some time ago this project got support for a few popular
RTOSes, so that when GDB queries OpenOCD for threads it supplies the
info read from the target memory. Currently OpenOCD supports just a few
(8) RTOSes.

Although adding such support to OpenOCD is not "rocket science" it
requires some effort and poses some challenges.

1. OpenOCD has slow release cycle - usually one can expect a release no
more than once a year. With that in mind even if support for particular
RTOS is added to OpenOCD, some platforms would have to wait years to
actually get that. For example "stable" Debian has OpenOCD that is 3
years old, while "backports", "testing" and "unstable" have release
from 2015 with some patches.

2. Once support is added to OpenOCD, the layout and naming of some RTOS
structures has to be "frozen", as any change in that will break that
support (the code to handle RTOS in OpenOCD is using internal knowledge
about ABI of the RTOS). Obviously when these parameters change, they
can (and should!) be updated in OpenOCD, but see item 1 above - some
users would have to wait years to see that. Then it causes problems
when you want to debug some new and old projects - they may need very
specific versions of tools to work correctly. This may not be such a
big deal for projects which actively participate with OpenOCD team, but
some code for RTOS handling was written by people unrelated to the
team/company of the RTOS, so it's not possible to expect them to keep
everything up to date. Do note that such handling code can be made more
generic by not hardcoding any offsets/addresses/etc., but it has to
hardcode something anyway (at least the names of some objects, the
assumptions of how a system arranges the threads, the stacking of
registers)...

3. Above requirement is a big problem in case of developing your own
RTOS, where you need good debugging tools to catch all the possible
errors, but due to early stage of development the concept of freezing
the layout/naming/configs is not very tempting.

4. The code to handle RTOS in OpenOCD is kind of a "middle man" - it
has to query both GDB and target to get the whole picture. GDB has the
info about symbols and their addresses, OpenOCD has access to the
target. You need both to actually get something useful, as you have to
read and interpret data from the addresses where some specific symbols
were placed by linker. Then OpenOCD fills the info about existing
threads and when GDB wants to know something about particular thread it
asks OpenOCD to get that from the memory.

For an example how such RTOS support code looks in OpenOCD, see here:
http://repo.or.cz/openocd.git/blob/HEAD:/src/rtos/ChibiOS.c
or more generally the files in this folder:
http://repo.or.cz/openocd.git/tree/HEAD:/src/rtos

Yesterday while writing my own pretty printer, I got an idea that this
RTOS support could be done just like "pretty printers" are done. User
would load his/her own Python script which would do the same thing
OpenOCD is doing right now. As this would again be completely "client
side", there would be no problem of incompatible versions of slow rate
of releases. Such Python support script could easily be made part of
the RTOS project or be automatically generated (to match current
configuration).

Would that be even possible to implement in GDB? Maybe something like
that is possible even now, but not documented?

Thanks for any info!

Regards,
FCh