diff options
author | Frederic Leger | 2014-03-13 16:36:27 +0000 |
---|---|---|
committer | Frederic Leger | 2014-03-13 16:36:27 +0000 |
commit | 34de87f4906037fde2d08d1cdaaf2777359e647d (patch) | |
tree | 954a5deeaf0d0cdaed76c9fcf7591fe1ff4c445e /python | |
parent | 75dcef0657bb5665d447821195d0b644e8a9204f (diff) | |
download | org.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')
-rw-r--r-- | python/src/tcf/services/stacktrace.py | 360 |
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) |