Implementing the OS awareness API
The OS awareness API consists of callbacks that the debugger makes at specific times. For each callback, the debugger provides a means for the implementation to retrieve information about the target and resolve variables and pointers, through an expression evaluator.
The API exists primarily as a set of Java interfaces since the debugger itself is written in Java. However, the debugger provides a Python interpreter and bindings to translate calls between Python and Java, allowing the Java interfaces to be implemented by Python scripts. This section and the next ones refer to the Java interfaces but explain how to implement the extension in Python.
NoteA Python implementation does not require any particular build or compilation environment, as opposed to a Java implementation. On the other hand, investigating problems within Python code is more difficult, and you are advised to read the Programming advice and noteworthy information section before starting to write your own Python implementation.
The detailed Java interfaces to implement are available in the DS-5 installation folder under sw/eclipse/dropins/plugins, within the com.arm.debug.extension.source_<version>.jar file.
NoteYou are encouraged to read the Javadoc documentation on Java interfaces as it contains essential information that is not presented here.
The Java interface of immediate interest at this point is
IOSProvider, in the package
com.arm.debug.extension.os. This interface must be implemented
by the provider instance that was left out with a
todo comment in
First, add the simplest implementation to the configuration database entry:
<some folder> /mydb /OS /myos /extension.xml /messages.properties /provider.py
<?xml version="1.0" encoding="UTF-8"?> <os id="myos" version="5.15" xmlns="http://www.arm.com/os_extension"> <name>myos.title</name> <description>myos.desc</description> <provider>provider.py</provider> </os>
# this script implements the Java interface IOSProvider def areOSSymbolsLoaded(debugger): return False def isOSInitialised(debugger): return False def getOSContextProvider(): return None def getDataModel(): return None
This is enough to make the OS awareness implementation valid. A debug configuration with this OS awareness selected works, although this does not add anything on top of a plain bare-metal connection. However, this illustrates the logical lifecycle of the OS awareness:
- Ensure debug information for the OS is available. On loading symbols, the
areOSSymbolsLoaded();the implementation returns true if it recognizes symbols as belonging to the OS, enabling the next callback.
- Ensure the OS is initialized. Once the symbols for the OS are available, the
isOSInitialised(),immediately if the target is stopped or whenever the target stops next. This is an opportunity for the awareness implementation to check that the OS has reached a state where threads and other data structures are ready to be read, enabling the next two callbacks.
- Retrieve information about threads and other data structures. Once the OS is
initialized, the debugger calls out to
getDataModel()to read information from the target. In reality, the debugger may call out to
getDataModel()earlier on, but does not use the returned objects to read from the target until