Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Leger2014-03-13 16:36:27 +0000
committerFrederic Leger2014-03-13 16:36:27 +0000
commit34de87f4906037fde2d08d1cdaaf2777359e647d (patch)
tree954a5deeaf0d0cdaed76c9fcf7591fe1ff4c445e /python/src/tcf/services
parent75dcef0657bb5665d447821195d0b644e8a9204f (diff)
downloadorg.eclipse.tcf-34de87f4906037fde2d08d1cdaaf2777359e647d.tar.gz
org.eclipse.tcf-34de87f4906037fde2d08d1cdaaf2777359e647d.tar.xz
org.eclipse.tcf-34de87f4906037fde2d08d1cdaaf2777359e647d.zip
Python - StackTrace service update.
The StackTrace service can now be documented using sphinx. Some operators have been added to the StackTraceContext object so that one can compare StackTrace contexts.
Diffstat (limited to 'python/src/tcf/services')
-rw-r--r--python/src/tcf/services/stacktrace.py360
1 files changed, 269 insertions, 91 deletions
diff --git a/python/src/tcf/services/stacktrace.py b/python/src/tcf/services/stacktrace.py
index 682a5c51c..0dca56afb 100644
--- a/python/src/tcf/services/stacktrace.py
+++ b/python/src/tcf/services/stacktrace.py
@@ -9,112 +9,188 @@
# * Wind River Systems - initial API and implementation
#******************************************************************************
+"""TCF stacktrace service interface.
+
+.. |getChildren| replace:: :meth:`~StackTraceService.getChildren`
+.. |getContext| replace:: :meth:`~StackTraceService.getContext`
+.. |runcontrol| replace:: :mod:`~tcf.services.runcontrol`
+.. |DoneGetChildren| replace:: :class:`DoneGetChildren`
+.. |DoneGetContext| replace:: :class:`DoneGetContext`
+
+
+The service implements thread stack back tracing.
+
+Properties
+----------
+
++--------------------------+--------------+-----------------------------------+
+| Name | Type | Description |
++==========================+==============+===================================+
+| PROP_ARGUMENTS_ADDRESS | |int| | Memory address of function |
+| | | arguments. |
++--------------------------+--------------+-----------------------------------+
+| PROP_ARGUMENTS_COUNT | |int| | Number of function arguments. |
++--------------------------+--------------+-----------------------------------+
+| PROP_FRAME_ADDRESS | |int| | Stack frame memory address. |
++--------------------------+--------------+-----------------------------------+
+| PROP_ID | |basestring| | String, stack frame ID. |
++--------------------------+--------------+-----------------------------------+
+| PROP_INSTRUCTION_ADDRESS | |int| | Instruction pointer. |
++--------------------------+--------------+-----------------------------------+
+| PROP_LEVEL | |int| | Stack frame level, starting from |
+| | | stack bottom. |
++--------------------------+--------------+-----------------------------------+
+| PROP_NAME | |basestring| | Human readable name. |
++--------------------------+--------------+-----------------------------------+
+| PROP_PARENT_ID | |basestring| | Stack frame parent ID. |
++--------------------------+--------------+-----------------------------------+
+| PROP_PROCESS_ID | |basestring| | Stack frame process ID. |
++--------------------------+--------------+-----------------------------------+
+| PROP_RETURN_ADDRESS | |int| | Return address. |
++--------------------------+--------------+-----------------------------------+
+| PROP_TOP_FRAME | |bool| | **True** if the frame is top frame|
+| | | on a stack. |
++--------------------------+--------------+-----------------------------------+
+
+Service Methods
+---------------
+.. autodata:: NAME
+.. autoclass:: StackTraceService
+
+getName
+^^^^^^^
+.. automethod:: StackTraceService.getName
+
+getContext
+^^^^^^^^^^
+.. automethod:: StackTraceService.getContext
+
+getChildren
+^^^^^^^^^^^
+.. automethod:: StackTraceService.getChildren
+
+Callback Classes
+----------------
+DoneGetContext
+^^^^^^^^^^^^^^^^^
+.. autoclass:: DoneGetContext
+ :members:
+
+DoneGetChildren
+^^^^^^^^^^^^^^^
+.. autoclass:: DoneGetChildren
+ :members:
+
+
+Helper Classes
+--------------
+StackTraceContext
+^^^^^^^^^^^^^^^^^
+.. autoclass:: StackTraceContext
+ :members:
+"""
+
from .. import services
NAME = "StackTrace"
+"""StackTrace service name."""
-#
-# Stack frame context property names.
-#
-# String, stack frame ID
PROP_ID = "ID"
-
-# String, stack frame parent ID
PROP_PARENT_ID = "ParentID"
-
-# String, stack frame process ID
PROP_PROCESS_ID = "ProcessID"
-
-# String, human readable name
PROP_NAME = "Name"
-
-# Boolean, true if the frame is top frame on a stack
PROP_TOP_FRAME = "TopFrame"
-
-# Integer, stack frame level, starting from stack bottom
PROP_LEVEL = "Level"
-
-# Number, stack frame memory address
PROP_FRAME_ADDRESS = "FP"
-
-# Number, return address
PROP_RETURN_ADDRESS = "RP"
-
-# Number, instruction pointer
PROP_INSTRUCTION_ADDRESS = "IP"
-
-# Integer, number of function arguments
PROP_ARGUMENTS_COUNT = "ArgsCnt"
-
-# Number, memory address of function arguments
PROP_ARGUMENTS_ADDRESS = "ArgsAddr"
+PROP_INDEX = "Index"
+PROP_WALK = "Walk"
class StackTraceService(services.Service):
+ """TCF stacktrace service interface."""
+
def getName(self):
+ """Get this service name.
+
+ :returns: This service name, which is the value of :const:`NAME`
+ """
return NAME
def getContext(self, ids, done):
- """
- Retrieve context info for given context IDs.
+ """Retrieve context info for given context IDs.
- The command will fail if parent thread is not suspended.
- Client can use Run Control service to suspend a thread.
+ The command will fail if parent thread is not suspended. Client can use
+ |runcontrol| service to suspend a thread.
- @param ids - array of context IDs.
- @param done - call back interface called when operation is completed.
+ :param ids: List of context IDs.
+ :type ids: |tuple| or |list|
+ :param done: call back interface called when operation is completed
+ :type done: |DoneGetContext|
"""
raise NotImplementedError("Abstract method")
def getChildren(self, parent_context_id, done):
- """
- Retrieve stack trace context list.
+ """Retrieve stack trace context list.
+
Parent context usually corresponds to an execution thread.
- Some targets have more then one stack. In such case children of a
+
+ Some targets have more than one stack. In such case children of a
thread are stacks, and stack frames are deeper in the hierarchy - they
- can be retrieved with additional getChildren commands.
+ can be retrieved with additional :meth:`getChildren` commands.
- The command will fail if parent thread is not suspended.
- Client can use Run Control service to suspend a thread.
+ The command will fail if parent thread is not suspended. Client can use
+ |runcontrol| service to suspend a thread.
- @param parent_context_id - parent context ID.
- @param done - call back interface called when operation is completed.
+ :param parent_context_id: Parent context ID.
+ :type parent_context_id: |basestring|
+ :param done: call back interface called when operation is completed
+ :type done: |DoneGetChildren|
"""
raise NotImplementedError("Abstract method")
class DoneGetContext(object):
- """
- Client call back interface for getContext().
- """
+ """Client call back interface for |getContext|."""
+
def doneGetContext(self, token, error, contexts):
- """
- Called when context data retrieval is done.
- @param error - error description if operation failed, None if
- succeeded.
- @param contexts - array of context data or None if error.
+ """Called when context data retrieval is done.
+
+ :param error: Error description if operation failed, **None** if
+ succeeded.
+ :param contexts: A list of context data or **None** if error.
+ :type contexts: |tuple| or **None**
"""
pass
class DoneGetChildren(object):
- """
- Client call back interface for getChildren().
- """
+ """Client call back interface for |getChildren|."""
+
def doneGetChildren(self, token, error, context_ids):
- """
- Called when context list retrieval is done.
- @param error - error description if operation failed, None if
- succeeded.
- @param context_ids - array of available context IDs.
- Stack frames are ordered from stack bottom to top.
+ """Called when context list retrieval is done.
+
+ .. note:: Stack frames are ordered from stack bottom to top.
+
+ :param error: error description if operation failed, **None** if
+ succeeded
+ :param context_ids: A list of available context IDs.
+ :type context_ids: |tuple|
"""
pass
class StackTraceContext(object):
- """
- StackTraceContext represents stack trace objects - stacks and stack frames.
+ """StackTrace context class.
+
+ *StackTraceContext* represents stack trace objects : stacks and stack
+ frames.
+
+ :param props: The properties to initialise object with. See `Properties`_.
+ :type props: |dict|
"""
def __init__(self, props):
self._props = props or {}
@@ -122,68 +198,170 @@ class StackTraceContext(object):
def __str__(self):
return "[Stack Trace Context %s]" % self._props
+ def __eq__(self, other):
+ # Two frames are considered equal if they have the same properties
+ if other and isinstance(other, StackTraceContext):
+ return self.getProperties() == other.getProperties()
+ return False
+
+ def __getComparable(self, other):
+ assert isinstance(other, StackTraceContext)
+
+ # levels from bottom to top, but we want top first when sorted
+ levels = (other.getLevel(), self.getLevel())
+ # indexes from top to bottom
+ indexes = (self.getIndex(), other.getIndex())
+
+ # By default, use Level as it is more reliable to perform comparison,
+ # even between frames from successive runcontrol (Level is absolute,
+ # Index is function of the top frame which changes).
+ if -1 not in levels:
+ return levels
+ if -1 not in indexes:
+ return indexes
+
+ return None
+
+ def __ge__(self, other):
+ # Compare frames through their index or levels.
+ if other and isinstance(other, StackTraceContext):
+ comp = self.__getComparable(other)
+ return comp and comp[0] >= comp[1]
+ return False
+
+ def __gt__(self, other):
+ # Compare frames through their index or levels.
+ if other and isinstance(other, StackTraceContext):
+ comp = self.__getComparable(other)
+ return comp and comp[0] > comp[1]
+ return True
+
+ def __le__(self, other):
+ # Compare frames through their index or levels.
+ if other and isinstance(other, StackTraceContext):
+ comp = self.__getComparable(other)
+ return comp and comp[0] <= comp[1]
+ return False
+
+ def __lt__(self, other):
+ # Compare frames through their index or levels.
+ if other and isinstance(other, StackTraceContext):
+ comp = self.__getComparable(other)
+ return comp and comp[0] < comp[1]
+ return False
+
+ def __ne__(self, other):
+ # Two frames are considered equal if they have the same properties
+ if other and isinstance(other, StackTraceContext):
+ return self.getProperties() != other.getProperties()
+ return True
+
def getID(self):
+ """Get Context ID.
+
+ :returns: A |basestring| representing this stack context ID. This is
+ the only mandatory field.
+ """
+ return self._props.get(PROP_ID, '')
+
+ def getIndex(self):
+ """Get stack index.
+
+ :returns: An |int| representing this stack index, 0 being the top
+ frame, or **-1** if unknown.
"""
- Get Context ID.
- @return context ID.
+ return self._props.get(PROP_INDEX, -1)
+
+ def getLevel(self):
+ """Get stack level.
+
+ :returns: An |int| representing this context stack level, or **-1** if
+ unknown.
"""
- return self._props.get(PROP_ID)
+ return self._props.get(PROP_LEVEL, -1)
def getParentID(self):
+ """Get parent context ID.
+
+ :returns: A |basestring| representing parent context ID, or an empty
+ |basestring| if unknown.
"""
- Get parent context ID.
- @return parent context ID.
+ return self._props.get(PROP_PARENT_ID, '')
+
+ def getProcessID(self):
+ """Get process context ID.
+
+ :returns: A |basestring| representing process context ID, or an empty
+ |basestring| if unknown.
"""
- return self._props.get(PROP_PARENT_ID)
+ return self._props.get(PROP_PROCESS_ID, '')
def getName(self):
+ """Get context name - if context represents a stack.
+
+ :returns: A |basestring| representing this stack context name or
+ **None**.
"""
- Get context name - if context represents a stack.
- @return context name or None.
- """
- return self._props.get(PROP_NAME)
+ return self._props.get(PROP_NAME, None)
def getFrameAddress(self):
+ """Get memory address of this frame.
+
+ :returns: An |int| representing this frame address or **None** if not a
+ stack frame.
"""
- Get memory address of this frame.
- @return address or None if not a stack frame.
- """
- return self._props.get(PROP_FRAME_ADDRESS)
+ return self._props.get(PROP_FRAME_ADDRESS, None)
def getReturnAddress(self):
+ """Get program counter saved in this stack frame.
+
+ This return address is the address of instruction to be executed when
+ the function returns.
+
+ :returns: An |int| representing the return address or **None** if not a
+ stack frame.
"""
- Get program counter saved in this stack frame -
- it is address of instruction to be executed when the function returns.
- @return return address or None if not a stack frame.
- """
- return self._props.get(PROP_RETURN_ADDRESS)
+ return self._props.get(PROP_RETURN_ADDRESS, None)
def getInstructionAddress(self):
- """
- Get address of the next instruction to be executed in this stack frame.
+ """Get address of the next instruction to be executed in this stack
+ frame.
+
For top frame it is same as PC register value.
+
For other frames it is same as return address of the next frame.
- @return instruction address or None if not a stack frame.
+
+ :returns: An |int| representing this instruction address or **None** if
+ not a stack frame.
"""
- return self._props.get(PROP_INSTRUCTION_ADDRESS)
+ return self._props.get(PROP_INSTRUCTION_ADDRESS, None)
def getArgumentsCount(self):
+ """Get number of function arguments for this frame.
+
+ :returns: An |int| reprsenting this stack function arguments count.
"""
- Get number of function arguments for this frame.
- @return function arguments count.
- """
- return self._props.get(PROP_ARGUMENTS_COUNT)
+ return self._props.get(PROP_ARGUMENTS_COUNT, 0)
def getArgumentsAddress(self):
+ """Get address of function arguments area in memory.
+
+ :returns: An |int| representing this stack function arguments address
+ or **None** if not available.
"""
- Get address of function arguments area in memory.
- @return function arguments address or None if not available.
- """
- return self._props.get(PROP_ARGUMENTS_ADDRESS, 0)
+ return self._props.get(PROP_ARGUMENTS_ADDRESS, None)
def getProperties(self):
- """
- Get complete map of context properties.
- @return map of context properties.
+ """Get complete map of context properties.
+
+ :returns: A |dict| of context properties. See `Properties`_.
"""
return self._props
+
+ def isTopFrame(self):
+ """Check if this stack frame is the top frame.
+
+ :returns: A |bool| set to **True** if this stack is the toplevel
+ stack frame, **False** else.
+ """
+ return self._props.get(PROP_TOP_FRAME, False)

Back to the top