diff options
author | Frederic Leger | 2016-07-07 09:18:03 +0000 |
---|---|---|
committer | Frederic Leger | 2016-07-07 09:18:03 +0000 |
commit | 72c9f8995912207a44d31c82f74056248e882dba (patch) | |
tree | 58e4f7c74b1b3138b6abeffa80d505df8d56bab0 | |
parent | 69846a1fda38662c05543d5b584086cf0fbc8406 (diff) | |
download | org.eclipse.tcf-72c9f8995912207a44d31c82f74056248e882dba.tar.gz org.eclipse.tcf-72c9f8995912207a44d31c82f74056248e882dba.tar.xz org.eclipse.tcf-72c9f8995912207a44d31c82f74056248e882dba.zip |
TCF Python: Python 3 compliance.
The whole TCF python code should now be python 2 AND python 3
compatible.
As there are few tests, I made sure this works by running the
BasicTests.py and ProcessStart.py using both a python2 or python3
interpreter.
49 files changed, 1075 insertions, 621 deletions
diff --git a/python/src/tcf/EventQueue.py b/python/src/tcf/EventQueue.py index a9647ebb2..90b118897 100644 --- a/python/src/tcf/EventQueue.py +++ b/python/src/tcf/EventQueue.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -38,7 +38,7 @@ class EventQueue(object): self.__lock.notifyAll() self.__thread.join() except Exception as e: - import protocol # as protocol import this module too + from . import protocol # as protocol import this module too protocol.log("Failed to shutdown TCF event dispatch thread", e) def isShutdown(self): @@ -46,8 +46,9 @@ class EventQueue(object): return self.__is_shutdown def __error(self, x): - import protocol # as protocol import this module too - protocol.log("Unhandled exception in TCF event dispatch", x) + if not self.isShutdown(): + from . import protocol # as protocol import this module too + protocol.log("Unhandled exception in TCF event dispatch", x) def __call__(self): while True: @@ -79,8 +80,8 @@ class EventQueue(object): def getCongestion(self): with self.__lock: job_cnt = 0 - l0 = job_cnt / 10 - 100 - l1 = len(self.__queue) / 10 - 100 + l0 = int(job_cnt / 10) - 100 + l1 = int(len(self.__queue) / 10) - 100 if l1 > l0: l0 = l1 if l0 > 100: diff --git a/python/src/tcf/__init__.py b/python/src/tcf/__init__.py index 5385da877..7e3c32c64 100644 --- a/python/src/tcf/__init__.py +++ b/python/src/tcf/__init__.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -15,7 +15,7 @@ TCF - Target Communication Framework import types -from . import protocol, peer, channel +from . import compat, protocol, peer, channel from .util import task __all__ = ('connect', 'peers') @@ -25,9 +25,9 @@ def connect(params, wait=True): """Connect to peer. Argument is a string of the form <transport>:<host>:<port>, e.g. "TCP:127.0.0.1:1534". """ - if type(params) is types.StringType: + if isinstance(params, compat.strings): params = _parse_params(params) - elif type(params) is not types.DictType: + elif isinstance(params, dict): raise TypeError("Expected string or dict") p = peer.TransientPeer(params) if wait: diff --git a/python/src/tcf/channel/AbstractChannel.py b/python/src/tcf/channel/AbstractChannel.py index 8cb2b3e7b..312896021 100644 --- a/python/src/tcf/channel/AbstractChannel.py +++ b/python/src/tcf/channel/AbstractChannel.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2015-2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -12,9 +12,8 @@ import sys import threading import time -import types -from .. import protocol, transport, services, peer, errors +from .. import compat, protocol, transport, services, peer, errors from ..services import locator from ..channel import STATE_CLOSED, STATE_OPEN, STATE_OPENING from ..channel import Token, fromJSONSequence, toJSONSequence @@ -25,7 +24,7 @@ EOM = -2 # End Of Message class Message(object): def __init__(self, typeCode): - if type(typeCode) is types.IntType: + if isinstance(typeCode, int): typeCode = chr(typeCode) self.type = typeCode self.service = None @@ -63,7 +62,7 @@ class ReaderThread(threading.Thread): if n == EOM: raise IOError("Unexpected end of message") if n < 0: - raise IOError("Communication channel is closed by " + \ + raise IOError("Communication channel is closed by " + "remote peer") buf.append(n) return buf @@ -256,7 +255,7 @@ class AbstractChannel(object): services.onChannelCreated(self, self.local_service_by_name) self.__makeServiceByClassMap(self.local_service_by_name, self.local_service_by_class) - args = self.local_service_by_name.keys() + args = list(self.local_service_by_name.keys()) self.sendEvent(protocol.getLocator(), "Hello", toJSONSequence((args,))) except IOError as x: @@ -280,7 +279,7 @@ class AbstractChannel(object): @param peer_attrs - peer that will become new remote communication endpoint of this channel. """ - if isinstance(peer_attrs, str): + if isinstance(peer_attrs, compat.strings): # support for redirect(peerId) attrs = {} attrs[peer.ATTR_ID] = peer_attrs @@ -370,7 +369,7 @@ class AbstractChannel(object): self.terminate(x) def __makeServiceByClassMap(self, by_name, by_class): - for service in by_name.values(): + for service in list(by_name.values()): for clazz in service.__class__.__bases__: if clazz == services.Service: continue @@ -498,7 +497,7 @@ class AbstractChannel(object): x = Exception(error) else: x = IOError("Channel is closed") - for msg in channel.out_tokens.values(): + for msg in list(channel.out_tokens.values()): try: s = str(msg) if len(s) > 72: @@ -549,17 +548,17 @@ class AbstractChannel(object): def getLocalServices(self): assert protocol.isDispatchThread() assert self.state != STATE_OPENING - return self.local_service_by_name.keys() + return list(self.local_service_by_name.keys()) def getRemoteServices(self): assert protocol.isDispatchThread() assert self.state != STATE_OPENING - return self.remote_service_by_name.keys() + return list(self.remote_service_by_name.keys()) def getLocalService(self, cls_or_name): assert protocol.isDispatchThread() assert self.state != STATE_OPENING - if type(cls_or_name) == types.StringType: + if isinstance(cls_or_name, compat.strings): return self.local_service_by_name.get(cls_or_name) else: return self.local_service_by_class.get(cls_or_name) @@ -567,7 +566,7 @@ class AbstractChannel(object): def getRemoteService(self, cls_or_name): assert protocol.isDispatchThread() assert self.state != STATE_OPENING - if type(cls_or_name) == types.StringType: + if isinstance(cls_or_name, compat.strings): return self.remote_service_by_name.get(cls_or_name) else: return self.remote_service_by_class.get(cls_or_name) @@ -787,7 +786,7 @@ class AbstractChannel(object): level = protocol.getCongestionLevel() if level == self.local_congestion_level: return - i = (level - self.local_congestion_level) / 8 + i = int((level - self.local_congestion_level) / 8) if i != 0: level = self.local_congestion_level + i self.local_congestion_time = timeVal diff --git a/python/src/tcf/channel/ChannelTCP.py b/python/src/tcf/channel/ChannelTCP.py index 8f7b19a2c..75cc83223 100644 --- a/python/src/tcf/channel/ChannelTCP.py +++ b/python/src/tcf/channel/ChannelTCP.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -10,8 +10,8 @@ # ***************************************************************************** import socket -import types +from .. import compat from .. import protocol from .StreamChannel import StreamChannel @@ -45,7 +45,7 @@ class ChannelTCP(StreamChannel): self.closed = True if self.closed: try: - if self.socket: + if hasattr(self, 'socket') and self.socket: self.socket.close() except socket.error as y: protocol.log("Cannot close socket", y) @@ -78,26 +78,26 @@ class ChannelTCP(StreamChannel): return -1 raise x + def str2bytes(self, data): + if isinstance(data, compat.strings): + return bytearray([ord(x) for x in data]) + elif isinstance(data, int): + return bytearray([data]) + return data + def put(self, b): if self.closed: return - t = type(b) - if t is types.StringType: - s = b - elif t is types.IntType: - s = chr(b) - else: - raise "Illegal argument type: %s" % t + s = self.str2bytes(b) self.socket.send(s) def putBuf(self, buf): if self.closed: return - t = type(buf) - if t is types.StringType: + if isinstance(buf, (bytes, bytearray)): s = buf else: - s = str(buf) + s = self.str2bytes(buf) self.socket.sendall(s) def flush(self): diff --git a/python/src/tcf/channel/Command.py b/python/src/tcf/channel/Command.py index 72b6e9544..392a1f7e8 100644 --- a/python/src/tcf/channel/Command.py +++ b/python/src/tcf/channel/Command.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -9,7 +9,6 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -import cStringIO from .. import protocol, errors, services from ..channel import Token, toJSONSequence, fromJSONSequence, dumpJSONObject @@ -92,37 +91,32 @@ class Command(object): raise NotImplementedError("Abstract method") def getCommandString(self): - buf = cStringIO.StringIO() - buf.write(str(self.service)) - buf.write(" ") - buf.write(self.command) + buf = str(self.service) + ' ' + str(self.command) if self.args is not None: i = 0 for arg in self.args: if i == 0: - buf.write(" ") + buf += " " else: - buf.write(", ") + buf += ", " i += 1 try: - dumpJSONObject(arg, buf) + buf += dumpJSONObject(arg) except Exception as x: - buf.write("***") - buf.write(x.message) - buf.write("***") - return buf.getvalue() + # Exception.message does not exist in python3, better use + # str(Exception) + buf += '***' + str(x) + '***' + return buf def toError(self, data, include_command_text=True): if not isinstance(data, dict): return None errMap = data - bf = cStringIO.StringIO() - bf.write("TCF error report:\n") + bf = 'TCF error report:\n' if include_command_text: cmd = self.getCommandString() if len(cmd) > 120: cmd = cmd[:120] + "..." - bf.write("Command: ") - bf.write(cmd) - errors.appendErrorProps(bf, errMap) - return errors.ErrorReport(bf.getvalue(), errMap) + bf += 'Command: ' + str(cmd) + bf += errors.appendErrorProps(errMap) + return errors.ErrorReport(bf, errMap) diff --git a/python/src/tcf/channel/StreamChannel.py b/python/src/tcf/channel/StreamChannel.py index ffadca8af..1f07f5e34 100644 --- a/python/src/tcf/channel/StreamChannel.py +++ b/python/src/tcf/channel/StreamChannel.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -9,7 +9,7 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -import types +from .. import compat from .AbstractChannel import AbstractChannel, EOS, EOM ESC = 3 @@ -92,7 +92,7 @@ class StreamChannel(AbstractChannel): elif n == 2: return EOS elif n == 3: - for i in xrange(0, 100000, 7): + for i in range(0, 100000, 7): while self.buf_pos >= self.buf_len: self.buf_len = self.getBuf(self.buf) self.buf_pos = 0 @@ -123,12 +123,12 @@ class StreamChannel(AbstractChannel): self.put(n) def write(self, buf): - t = type(buf) - if t == types.IntType: + if isinstance(buf, int): self.writeByte(buf) return - elif t == types.StringType: - buf = bytearray(buf) + elif isinstance(buf, compat.strings): + buf = bytearray(buf, 'utf-8') + if len(buf) > 32 and self.isZeroCopySupported(): self.put(ESC) self.put(3) diff --git a/python/src/tcf/channel/__init__.py b/python/src/tcf/channel/__init__.py index 7ac9ccb54..9795da2ab 100644 --- a/python/src/tcf/channel/__init__.py +++ b/python/src/tcf/channel/__init__.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -10,7 +10,6 @@ # ***************************************************************************** import binascii -import cStringIO import json import types @@ -51,7 +50,10 @@ class Token(object): tokenID = str(_token_cnt) _token_cnt += 1 else: - tokenID = str(tokenID) + if isinstance(tokenID, bytearray): + tokenID = tokenID.decode('utf-8') + else: + tokenID = str(tokenID) self.id = tokenID self.listener = listener @@ -165,11 +167,15 @@ class CommandListener(object): def toJSONSequence(args): if args is None: return None - buf = cStringIO.StringIO() + sequence = [] for arg in args: - json.dump(arg, buf, separators=(',', ':'), cls=TCFJSONEncoder) - buf.write('\0') - return buf.getvalue() + sequence.append(json.dumps(arg, separators=(',', ':'), + cls=TCFJSONEncoder)) + if sequence: + res = '\0'.join(sequence) + '\0' + else: + res = '' + return res def fromJSONSequence(byteArray): @@ -186,8 +192,8 @@ def fromJSONSequence(byteArray): return objects -def dumpJSONObject(obj, buf): - json.dump(obj, buf, separators=(',', ':'), cls=TCFJSONEncoder) +def dumpJSONObject(obj): + return json.dumps(obj, separators=(',', ':'), cls=TCFJSONEncoder) def toByteArray(data): @@ -196,10 +202,8 @@ def toByteArray(data): t = type(data) if t is bytearray: return data - elif t is str: - return binascii.a2b_base64(data) - elif t is unicode: - return binascii.a2b_base64(str(data)) + else: + return bytearray(binascii.a2b_base64(data)) raise TypeError(str(t)) @@ -207,6 +211,8 @@ class TCFJSONEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, bytearray): return binascii.b2a_base64(o)[:-1] + elif isinstance(o, bytes): + return o.decode('utf-8') elif hasattr(o, '__json__'): return o.__json__() elif hasattr(o, '__iter__'): diff --git a/python/src/tcf/compat.py b/python/src/tcf/compat.py new file mode 100644 index 000000000..0fd2b647a --- /dev/null +++ b/python/src/tcf/compat.py @@ -0,0 +1,45 @@ +# ***************************************************************************** +# * Copyright (c) 2015-2016 Wind River Systems, Inc. and others. +# * All rights reserved. This program and the accompanying materials +# * are made available under the terms of the Eclipse Public License v1.0 +# * which accompanies this distribution, and is available at +# * http:#www.eclipse.org/legal/epl-v10.html +# * +# * Contributors: +# * Wind River Systems - initial API and implementation +# ***************************************************************************** + +import sys +PY3 = sys.version_info[0] == 3 + + +if PY3: + ints = (int,) + strings = (str,) + inttype = int + longtype = int + + def str2bytes(data): + if data and isinstance(data[0], str): + return bytes([ord(c) for c in data]) + elif isinstance(data, bytes): + return data + return bytes(data) +else: + ints = (int, long) # @UndefinedVariable + strings = (basestring, str) # @UndefinedVariable + inttype = int + longtype = long # @UndefinedVariable + + def str2bytes(data): + if data and isinstance(data[0], str): + return bytearray([ord(c) for c in data]) + elif isinstance(data, bytearray): + return data + return bytearray(data) + + +def bytes2str(data): + if data and isinstance(data[0], int): + return ''.join(chr(b) for b in data) + return str(data) diff --git a/python/src/tcf/errors.py b/python/src/tcf/errors.py index 3e29d2ec6..6cf6eb2cc 100644 --- a/python/src/tcf/errors.py +++ b/python/src/tcf/errors.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -9,9 +9,7 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -import cStringIO import time -import types # Error report attribute names @@ -168,7 +166,7 @@ class ErrorReport(Exception): """ def __init__(self, msg, attrs): super(ErrorReport, self).__init__(msg) - if type(attrs) is types.IntType: + if isinstance(attrs, int): attrs = { ERROR_CODE: attrs, ERROR_TIME: int(time.time() * 1000), @@ -179,11 +177,9 @@ class ErrorReport(Exception): caused_by = attrs.get(ERROR_CAUSED_BY) if caused_by: errMap = caused_by - bf = cStringIO.StringIO() - bf.write("TCF error report:") - bf.write('\n') - appendErrorProps(bf, errMap) - self.caused_by = ErrorReport(bf.getvalue(), errMap) + bf = 'TCF error report:\n' + bf += appendErrorProps(errMap) + self.caused_by = ErrorReport(bf, errMap) def getErrorCode(self): """Get this exception error code. @@ -235,44 +231,33 @@ def toErrorString(data): return "Invalid error report format" -def appendErrorProps(bf, errMap): +def appendErrorProps(errMap): timeVal = errMap.get(ERROR_TIME) code = errMap.get(ERROR_CODE) service = errMap.get(ERROR_SERVICE) severity = errMap.get(ERROR_SEVERITY) alt_code = errMap.get(ERROR_ALT_CODE) alt_org = errMap.get(ERROR_ALT_ORG) + bf = '' if timeVal: - bf.write('\n') - bf.write("Time: ") - bf.write(time.strftime(_timestamp_format, - time.localtime(timeVal / 1000.))) + bf += '\nTime: ' + bf += time.strftime(_timestamp_format, time.localtime(timeVal / 1000.)) if severity: - bf.write('\n') - bf.write("Severity: ") + bf += '\nSeverity: ' if severity == SEVERITY_ERROR: - bf.write("Error") + bf += 'Error' elif severity == SEVERITY_FATAL: - bf.write("Fatal") + bf += 'Fatal' elif severity == SEVERITY_WARNING: - bf.write("Warning") + bf += 'Warning' else: - bf.write("Unknown") - bf.write('\n') - bf.write("Error text: ") - bf.write(toErrorString(errMap)) - bf.write('\n') - bf.write("Error code: ") - bf.write(str(code)) + bf += 'Unknown' + bf += '\nError text: ' + str(toErrorString(errMap)) + '\n' + bf += 'Error code: ' + str(code) if service: - bf.write('\n') - bf.write("Service: ") - bf.write(service) + bf += '\nService: ' + str(service) if alt_code: - bf.write('\n') - bf.write("Alt code: ") - bf.write(str(alt_code)) + bf += '\nAlt code: ' + str(alt_code) if alt_org: - bf.write('\n') - bf.write("Alt org: ") - bf.write(alt_org) + bf += '\nAlt org: ' + str(alt_org) + return bf diff --git a/python/src/tcf/peer.py b/python/src/tcf/peer.py index 665a25f34..89b79077b 100644 --- a/python/src/tcf/peer.py +++ b/python/src/tcf/peer.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -326,11 +326,11 @@ class AbstractPeer(TransientPeer): def updateAttributes(self, attrs): equ = True assert attrs.get(ATTR_ID) == self.rw_attrs.get(ATTR_ID) - for key in self.rw_attrs.keys(): + for key in list(self.rw_attrs.keys()): if self.rw_attrs.get(key) != attrs.get(key): equ = False break - for key in attrs.keys(): + for key in list(attrs.keys()): if attrs.get(key) != self.rw_attrs.get(key): equ = False break @@ -350,8 +350,8 @@ class AbstractPeer(TransientPeer): except IOError as x: protocol.log("Locator: failed to send 'peerChanged' event", x) self.last_heart_beat_time = timeVal - elif self.last_heart_beat_time + locator.DATA_RETENTION_PERIOD / 4 \ - < timeVal: + elif self.last_heart_beat_time + \ + int(locator.DATA_RETENTION_PERIOD / 4) < timeVal: for l in protocol.getLocator().getListeners(): try: l.peerHeartBeat(attrs.get(ATTR_ID)) diff --git a/python/src/tcf/protocol.py b/python/src/tcf/protocol.py index 2fd45e634..b424b8167 100644 --- a/python/src/tcf/protocol.py +++ b/python/src/tcf/protocol.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -40,7 +40,7 @@ def startEventQueue(): _event_queue = EventQueue.EventQueue(on_shutdown=shutdownDiscovery) _event_queue.start() # initialize LocatorService - from services.local.LocatorService import LocatorService + from .services.local.LocatorService import LocatorService _event_queue.invokeLater(LocatorService) # start timer dispatcher _timer_dispatcher = threading.Thread(target=_dispatch_timers) @@ -49,6 +49,26 @@ def startEventQueue(): _timer_dispatcher.start() +def stopEventQueue(): + """Stop the TCF event queue.""" + + if not _event_queue or _event_queue.isShutdown(): + return + + _event_queue.shutdown() + + # Stop timer dispatcher + + global _timer_queue_alive + + try: + with _timer_queue_lock: + _timer_queue_alive = False + _timer_queue_lock.notify_all() + except Exception: + pass + + def getEventQueue(): """ @return instance of event queue that is used for TCF events. @@ -164,16 +184,16 @@ def log(msg, x=None): @param x - an exception associated with the log entry or None. """ if not _logger: - print >> sys.stderr, msg + sys.stderr.write(str(msg) + '\n') while x: import traceback - print >> sys.stderr, "%s: %s" % (type(x).__name__, x) + sys.stderr.write("%s: %s\n" % (type(x).__name__, x)) tb = getattr(x, "tb", None) or sys.exc_info()[2] if tb: traceback.print_tb(tb) caused_by = getattr(x, "caused_by", None) if caused_by: - print >> sys.stderr, "Caused by:" + sys.stderr.write("Caused by: " + str(caused_by) + "\n") x = caused_by else: break @@ -184,7 +204,7 @@ def log(msg, x=None): def startDiscovery(): "Start discovery of remote peers if not running yet" # initialize LocatorService - from services.local.LocatorService import LocatorService + from .services.local.LocatorService import LocatorService if LocatorService.locator: invokeAndWait(LocatorService.startup) @@ -212,7 +232,7 @@ def getOpenChannels(): @return an array of IChannel """ assert isDispatchThread() - import transport + from . import transport return transport.getOpenChannels() @@ -237,7 +257,7 @@ def addChannelOpenListener(listener): @param listener """ assert isDispatchThread() - import transport + from . import transport transport.addChannelOpenListener(listener) @@ -247,7 +267,7 @@ def removeChannelOpenListener(listener): @param listener """ assert isDispatchThread() - import transport + from . import transport transport.removeChannelOpenListener(listener) @@ -257,7 +277,7 @@ def sendEvent(service_name, event_name, data): The message is sent to all open communication channels - broadcasted. """ assert isDispatchThread() - import transport + from . import transport transport.sendEvent(service_name, event_name, data) @@ -276,7 +296,7 @@ def sync(done): targets. """ assert isDispatchThread() - import transport + from . import transport transport.sync(done) @@ -355,7 +375,7 @@ def addServiceProvider(provider): This method can be invoked from any thread. @param provider - ServiceProvider implementation """ - import services + from . import services services.addServiceProvider(provider) @@ -365,7 +385,7 @@ def removeServiceProvider(provider): This method can be invoked from any thread. @param provider - ServiceProvider implementation """ - import services + from . import services services.removeServiceProvider(provider) @@ -375,7 +395,7 @@ def addTransportProvider(provider): This method can be invoked from any thread. @param provider - TransportProvider implementation """ - import transport + from . import transport transport.addTransportProvider(provider) @@ -385,7 +405,7 @@ def removeTransportProvider(provider): This method can be invoked from any thread. @param provider - TransportProvider implementation """ - import transport + from . import transport transport.removeTransportProvider(provider) @@ -400,6 +420,9 @@ class Timer(object): self.args = args self.kwargs = kwargs + def __lt__(self, x): + return self.__cmp__(x) == -1 + def __cmp__(self, x): if x is self: return 0 @@ -416,12 +439,17 @@ class Timer(object): _timer_queue_lock = threading.Condition() _timer_queue = [] +_timer_queue_alive = False def _dispatch_timers(): + global _timer_queue_alive + + _timer_queue_alive = True + try: with _timer_queue_lock: - while True: + while _timer_queue_alive: if not _timer_queue: _timer_queue_lock.wait() else: diff --git a/python/src/tcf/services/__init__.py b/python/src/tcf/services/__init__.py index 19c1a89e9..6c5cf56b1 100644 --- a/python/src/tcf/services/__init__.py +++ b/python/src/tcf/services/__init__.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -42,8 +42,8 @@ def removeServiceProvider(provider): def onChannelCreated(channel, services_by_name): with _lock: # TODO ZeroCopy support is incomplete -# zero_copy = ZeroCopy() -# services_by_name[zero_copy.getName()] = zero_copy + # zero_copy = ZeroCopy() + # services_by_name[zero_copy.getName()] = zero_copy for provider in _providers: try: arr = provider.getLocalService(channel) diff --git a/python/src/tcf/services/breakpoints.py b/python/src/tcf/services/breakpoints.py index 89ec1e0e9..1c0dca610 100644 --- a/python/src/tcf/services/breakpoints.py +++ b/python/src/tcf/services/breakpoints.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -36,6 +36,7 @@ .. |DoneGetIDs| replace:: :class:`DoneGetIDs` .. |DoneGetProperties| replace:: :class:`DoneGetProperties` .. |DoneGetStatus| replace:: :class:`DoneGetStatus` +.. |Pathmap Service| replace:: :mod:`tcf.services.pathmap` .. |Status| replace:: :ref:`Tcf-Breakpoints-Status` .. |Status Instances| replace:: :ref:`Tcf-Breakpoints-Status-Instances` .. |Time Scales| replace:: :ref:`Tcf-Breakpoints-Time-Scales` @@ -66,6 +67,8 @@ Properties +-----------------------+--------------+--------------------------------------+ | Name | Type | Description | +=======================+==============+======================================+ +| PROP_ACTION | |basestring| | Expression or script. | ++-----------------------+--------------+--------------------------------------+ | PROP_ACCESS_MODE | |int| | The access mode that will trigger | | | | the breakpoint. Access mode can be a | | | | bitwise OR of the values defined in | @@ -114,6 +117,10 @@ Properties | PROP_LINE | |int| | The source code line number of | | | | breakpoint location. | +-----------------------+--------------+--------------------------------------+ +| PROP_LINE_OFFSET | |int| | Max number of lines breakpoint is | +| | | allowed to be moved in case of | +| | | inexact line info match. | ++-----------------------+--------------+--------------------------------------+ | PROP_LOCATION | |basestring| | Defines location of the breakpoint. | | | | The expression evaluates either to a | | | | memory address or a register | @@ -153,6 +160,10 @@ Properties | PROP_UNITS | |basestring| | The units for the time value. See | | | | |Time Units|. | +-----------------------+--------------+--------------------------------------+ +| PROP_SKIP_PROLOGUE | |basestring| | If set, the breakpoint is set after | +| | | the function prologue. The default | +| | | value for this property is **False**.| ++-----------------------+--------------+--------------------------------------+ .. _Tcf-Breakpoints-Access-Modes: @@ -248,23 +259,26 @@ Status Status Instances ^^^^^^^^^^^^^^^^ -+-------------------------+--------------+------------------------------------+ -| Name | Type | Description | -+=========================+==============+====================================+ -| INSTANCE_ADDRESS | |int| | Breakpoint address. | -+-------------------------+--------------+------------------------------------+ -| INSTANCE_CONTEXT | |basestring| | Breakpoint context. | -+-------------------------+--------------+------------------------------------+ -| INSTANCE_ERROR | |basestring| | Breakpoint status instance error. | -+-------------------------+--------------+------------------------------------+ -| INSTANCE_HIT_COUNT | |int| | Breakpoint hit count. | -+-------------------------+--------------+------------------------------------+ -| INSTANCE_MEMORY_CONTEXT | |basestring| | Breakpoint memory context. | -+-------------------------+--------------+------------------------------------+ -| INSTANCE_SIZE | |int| | Breakpoint size. | -+-------------------------+--------------+------------------------------------+ -| INSTANCE_TYPE | |basestring| | Breakpoint type. | -+-------------------------+--------------+------------------------------------+ ++--------------------------+--------------+-----------------------------------+ +| Name | Type | Description | ++==========================+==============+===================================+ +| INSTANCE_ADDRESS | |int| | Breakpoint address. | ++--------------------------+--------------+-----------------------------------+ +| INSTANCE_CONDITION_ERROR | |basestring| | Breakpoint error message for an | +| | | invalid condition. | ++--------------------------+--------------+-----------------------------------+ +| INSTANCE_CONTEXT | |basestring| | Breakpoint context. | ++--------------------------+--------------+-----------------------------------+ +| INSTANCE_ERROR | |basestring| | Breakpoint status instance error. | ++--------------------------+--------------+-----------------------------------+ +| INSTANCE_HIT_COUNT | |int| | Breakpoint hit count. | ++--------------------------+--------------+-----------------------------------+ +| INSTANCE_MEMORY_CONTEXT | |basestring| | Breakpoint memory context. | ++--------------------------+--------------+-----------------------------------+ +| INSTANCE_SIZE | |int| | Breakpoint size. | ++--------------------------+--------------+-----------------------------------+ +| INSTANCE_TYPE | |basestring| | Breakpoint type. | ++--------------------------+--------------+-----------------------------------+ Service Capabilities ^^^^^^^^^^^^^^^^^^^^ @@ -305,8 +319,8 @@ of |basestring| type, and **CAPABILITY_ACCESS_MODE** which is of |int| type. | | **PROP_COLUMN** breakpoint properties are | | | supported. | +----------------------------+------------------------------------------------+ -| CAPABILITY_FILE_MAPPING | If **True**, **PROP_FILE_MAPPING** breakpoint | -| | property is supported. | +| CAPABILITY_FILE_MAPPING | If **True**, using file pathmapping is | +| | supported. See |Pathmap Service|. | +----------------------------+------------------------------------------------+ | CAPABILITY_HAS_CHILDREN | If **True**, children of the context can have | | | different capabilities. | @@ -323,6 +337,9 @@ of |basestring| type, and **CAPABILITY_ACCESS_MODE** which is of |int| type. | CAPABILITY_TEMPORARY | If **True**, **PROP_TEMPORARY** breakpoint | | | property is supported. | +----------------------------+------------------------------------------------+ +| CAPABILITY_SKIP_PROLOGUE | If **True**, **PROP_SKIP_PROLOGUE** breakpoint | +| | property is supported. | ++----------------------------+------------------------------------------------+ Service Methods --------------- @@ -458,6 +475,9 @@ PROP_TEMPORARY = "Temporary" PROP_EVENT_TYPE = "EventType" PROP_EVENT_ARGS = "EventArgs" PROP_CLIENT_DATA = "ClientData" +PROP_SKIP_PROLOGUE = "SkipPrologue" +PROP_ACTION = "Action" +PROP_LINE_OFFSET = "LineOffset" # Deprecated PROP_CONTEXTNAMES = "ContextNames" @@ -502,6 +522,7 @@ INSTANCE_SIZE = "Size" INSTANCE_TYPE = "BreakpointType" INSTANCE_MEMORY_CONTEXT = "MemoryContext" INSTANCE_HIT_COUNT = "HitCount" +INSTANCE_CONDITION_ERROR = "ConditionError" # Breakpoint service capabilities. CAPABILITY_CONTEXT_ID = "ID" @@ -519,6 +540,7 @@ CAPABILITY_TEMPORARY = "Temporary" CAPABILITY_IGNORE_COUNT = "IgnoreCount" CAPABILITY_ACCESS_MODE = "AccessMode" CAPABILITY_CLIENT_DATA = "ClientData" +CAPABILITY_SKIP_PROLOGUE = "SkipPrologue" # Deprecated CAPABILITY_CONTEXTNAMES = "ContextNames" diff --git a/python/src/tcf/services/disassembly.py b/python/src/tcf/services/disassembly.py index c203076e9..d80e558ad 100644 --- a/python/src/tcf/services/disassembly.py +++ b/python/src/tcf/services/disassembly.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -238,7 +238,7 @@ class DisassemblyLine(object): def getOpcodeValue(self): """ - :returns: instruction address. + :returns: a |bytearray| representing this instruction opcode value. """ return self.opcode @@ -258,15 +258,15 @@ class DisassemblyLine(object): def __repr__(self): res = self.__class__.__name__ + '(' + repr(self.addr) + ', ' + \ - repr(self.size) + ', ' + repr(self.instruction) + ', ' + \ - repr(self.opcode) + ')' + repr(self.size) + ', ' + repr(self.instruction) + ', ' + \ + repr(self.opcode) + ')' return res def __str__(self): op = self.opcode oplen = len(op) res = self.__class__.__name__ + ' [address=' + str(self.addr) + \ - ', size=' + str(self.size) + ', instruction=' + \ - str(self.instruction) + ', opcode=' + \ - ' '.join('%02x' % ord(byte) for byte in op[0:oplen]) + ']' + ', size=' + str(self.size) + ', instruction=' + \ + str(self.instruction) + ', opcode=' + \ + ' '.join('%02x' % ord(byte) for byte in op[0:oplen]) + ']' return res diff --git a/python/src/tcf/services/expressions.py b/python/src/tcf/services/expressions.py index 92f462e51..2e79e8bf9 100644 --- a/python/src/tcf/services/expressions.py +++ b/python/src/tcf/services/expressions.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -24,6 +24,10 @@ Context Properties +====================+==============+=========================================+ | PROP_BITS | |int| | Size of expression value in bits. | +--------------------+--------------+-----------------------------------------+ +| PROP_BIT_OFFS | |int| | Bit offset in expression piece. | ++--------------------+--------------+-----------------------------------------+ +| PROP_BIT_SIZE | |int| | Bit size of expression piece. | ++--------------------+--------------+-----------------------------------------+ | PROP_CAN_ASSIGN | |bool| | **True** if the expression can be | | | | assigned a new value. | +--------------------+--------------+-----------------------------------------+ @@ -41,6 +45,8 @@ Context Properties +--------------------+--------------+-----------------------------------------+ | PROP_PARENT_ID | |basestring| | ID of expression's parent context. | +--------------------+--------------+-----------------------------------------+ +| PROP_PIECES | |dict| | Expression piece. | ++--------------------+--------------+-----------------------------------------+ | PROP_SIZE | |int| | Size in bytes. | +--------------------+--------------+-----------------------------------------+ | PROP_SYMBOL_ID | |basestring| | Symbol ID if the expression represents a| @@ -163,7 +169,7 @@ Value """ from .. import services -from . import symbols +from . import symbols NAME = "Expressions" """Expressions service name.""" @@ -181,6 +187,9 @@ PROP_TYPE = "Type" PROP_CAN_ASSIGN = "CanAssign" PROP_HAS_FUNC_CALL = "HasFuncCall" PROP_CLASS = "Class" # same as symbols.TypeClass +PROP_PIECES = "Pieces" +PROP_BIT_OFFS = "BitOffs" +PROP_BIT_SIZE = "BitSize" # Expression value property names. @@ -261,6 +270,30 @@ class Expression(object): """ return self._props.get(PROP_BITS, 0) + def getBitSize(self): + """Get size of expression value in bits. + + Can be **0** if value size is even number of bytes, use :meth:`getSize` + in such case. + + :returns: Size in bits. + """ + return self._props.get(PROP_BIT_SIZE, 0) + + def getPieces(self): + """Get complete dictionary of pieces properties. + + :returns: A |dict| of pieces properties. + """ + return self._props.get(PROP_PIECES) + + def getBitOffset(self): + """Get offset of expression value in bits. + + :returns: Offset in bits. + """ + return self._props.get(PROP_BIT_OFFS, 0) + def getSize(self): """Get size in bytes. The size can include extra (unused) bits. @@ -331,7 +364,11 @@ class Value(object): self._props = props or {} def __str__(self): - return "[Expression Value %s %s]" % (self._value, self._props) + if isinstance(self._value, bytearray): + valuestr = ' '.join([hex(b) for b in self._value]) + else: + valuestr = str(self._value) + return '[Expression Value %s %s]' % (valuestr, self._props) def getTypeClass(self): """Get value type class. diff --git a/python/src/tcf/services/filesystem.py b/python/src/tcf/services/filesystem.py index 51f3bb4b5..f3cc7f301 100644 --- a/python/src/tcf/services/filesystem.py +++ b/python/src/tcf/services/filesystem.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -629,10 +629,10 @@ class FileAttrs(object): def __eq__(self, other): if not isinstance(other, FileAttrs): return False - return (self.flags == other.flags and self.size == other.size and \ - self.uid == other.uid and self.gid == other.gid and \ - self.permissions == other.permissions and \ - self.mtime == other.mtime and \ + return (self.flags == other.flags and self.size == other.size and + self.uid == other.uid and self.gid == other.gid and + self.permissions == other.permissions and + self.mtime == other.mtime and self.attributes == other.attributes) def __ne__(self, other): @@ -640,29 +640,29 @@ class FileAttrs(object): # The following flags are defined for the 'permissions' field: -S_IFMT = 0170000 -S_IFSOCK = 0140000 -S_IFLNK = 0120000 -S_IFREG = 0100000 -S_IFBLK = 0060000 -S_IFDIR = 0040000 -S_IFCHR = 0020000 -S_IFIFO = 0010000 -S_ISUID = 0004000 -S_ISGID = 0002000 -S_ISVTX = 0001000 -S_IRWXU = 00700 -S_IRUSR = 00400 -S_IWUSR = 00200 -S_IXUSR = 00100 -S_IRWXG = 00070 -S_IRGRP = 00040 -S_IWGRP = 00020 -S_IXGRP = 00010 -S_IRWXO = 00007 -S_IROTH = 00004 -S_IWOTH = 00002 -S_IXOTH = 00001 +S_IFMT = 0o170000 +S_IFSOCK = 0o140000 +S_IFLNK = 0o120000 +S_IFREG = 0o100000 +S_IFBLK = 0o060000 +S_IFDIR = 0o040000 +S_IFCHR = 0o020000 +S_IFIFO = 0o010000 +S_ISUID = 0o004000 +S_ISGID = 0o002000 +S_ISVTX = 0o001000 +S_IRWXU = 0o0700 +S_IRUSR = 0o0400 +S_IWUSR = 0o0200 +S_IXUSR = 0o0100 +S_IRWXG = 0o0070 +S_IRGRP = 0o0040 +S_IWGRP = 0o0020 +S_IXGRP = 0o0010 +S_IRWXO = 0o0007 +S_IROTH = 0o0004 +S_IWOTH = 0o0002 +S_IXOTH = 0o0001 class DirEntry(object): @@ -733,7 +733,7 @@ class FileSystemException(IOError): initialise this exception with """ def __init__(self, message_or_exception): - if isinstance(message_or_exception, (str, unicode)): + if isinstance(message_or_exception, str): super(FileSystemException, self).__init__(message_or_exception) elif isinstance(message_or_exception, Exception): self.caused_by = message_or_exception diff --git a/python/src/tcf/services/linenumbers.py b/python/src/tcf/services/linenumbers.py index a02c83f8c..e32ae3dee 100644 --- a/python/src/tcf/services/linenumbers.py +++ b/python/src/tcf/services/linenumbers.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -124,52 +124,42 @@ class CodeArea(object): if self.file: h += hash(self.file) return h + self.start_line + self.start_column + self.end_line + \ - self.end_column + self.end_column def __str__(self): - import cStringIO - bf = cStringIO.StringIO() - bf.write('[') + res = '[' if self.directory: - bf.write(self.directory) - bf.write(':') + res += str(self.directory) + ':' if self.file: - bf.write(self.file) - bf.write(':') - bf.write(str(self.start_line)) + res += str(self.file) + ':' + res += str(self.start_line) if self.start_column: - bf.write('.') - bf.write(str(self.start_column)) - bf.write("..") - bf.write(str(self.end_line)) + res += '.' + str(self.start_column) + res += '..' + str(self.end_line) if self.end_column: - bf.write('.') - bf.write(str(self.end_column)) - bf.write(" -> ") + res += '.' + str(self.end_column) + res += ' -> ' if self.start_address: - bf.write("0x") - bf.write(hex(self.start_address)) + res += '0x' + str(hex(self.start_address)) else: - bf.write('0') - bf.write("..") + res += '0' + res += '..' if self.end_address: - bf.write("0x") - bf.write(hex(self.end_address)) + res += '0x' + str(hex(self.end_address)) else: - bf.write('0') + res += '0' if self.isa: - bf.write(",isa ") - bf.write(str(self.isa)) + res += ',isa ' + str(self.isa) if self.is_statement: - bf.write(",statement") + res += ',statement' if self.basic_block: - bf.write(",basic block") + res += ',basic block' if self.prologue_end: - bf.write(",prologue end") + res += ',prologue end' if self.epilogue_begin: - bf.write(",epilogue begin") - bf.write(']') - return bf.getvalue() + res += ',epilogue begin' + res += ']' + return res class LineNumbersService(services.Service): diff --git a/python/src/tcf/services/local/LocatorService.py b/python/src/tcf/services/local/LocatorService.py index 44480b634..86e038e58 100644 --- a/python/src/tcf/services/local/LocatorService.py +++ b/python/src/tcf/services/local/LocatorService.py @@ -19,12 +19,12 @@ import platform import threading import time import socket -import cStringIO + from .. import locator from ...util import logging from ...channel import fromJSONSequence, toJSONSequence from ...channel.ChannelProxy import ChannelProxy -from ... import protocol, services, channel, peer, errors +from ... import compat, protocol, services, channel, peer, errors # Flag indicating whether tracing of the the discovery activity is enabled. __TRACE_DISCOVERY__ = False @@ -50,12 +50,12 @@ class SubNet(object): else: l = len(a1) * 8 while i + 8 <= l: - n = i / 8 + n = int(i / 8) if a1[n] != a2[n]: return False i += 8 while i < l: - n = i / 8 + n = int(i / 8) m = 1 << (7 - i % 8) if (a1[n] & m) != (a2[n] & m): return False @@ -119,6 +119,9 @@ class InetAddress(object): def __str__(self): return "%s/%s" % (self.host or "", self.addr) + def __hash__(self): + return hash(self.addr) + class InputPacket(object): "Wrapper for UDP packet data." @@ -216,6 +219,7 @@ class LocatorService(locator.LocatorService): class DNSLookupThread(threading.Thread): def run(self): + while service._alive: try: itemSet = None @@ -224,7 +228,8 @@ class LocatorService(locator.LocatorService): if not LocatorService.addr_request: service._addr_cache_lock.wait(period) msec = int(time.time() * 1000) - for host, a in LocatorService.addr_cache.items(): + items = list(LocatorService.addr_cache.items()) + for host, a in items: if a.time_stamp + period * 10 < msec: if a.used: if itemSet is None: @@ -263,9 +268,11 @@ class LocatorService(locator.LocatorService): sock = service.socket try: data, addr = sock.recvfrom(MAX_PACKET_SIZE) - p = InputPacket(data, InetAddress(None, addr[0]), - addr[1]) - protocol.invokeAndWait(self._callable, p) + if addr and len(addr) >= 2: + p = InputPacket(data, + InetAddress(None, addr[0]), + addr[1]) + protocol.invokeAndWait(self._callable, p) except RuntimeError: # TCF event dispatch is shutdown return @@ -285,7 +292,8 @@ class LocatorService(locator.LocatorService): self.input_thread = InputThread(self.__handleDatagramPacket) try: self.loopback_addr = InetAddress(None, "127.0.0.1") - self.out_buf[0:8] = 'TCF%s\0\0\0\0' % locator.CONF_VERSION + tcfversion = 'TCF%s\0\0\0\0' % locator.CONF_VERSION + self.out_buf[0:8] = [ord(c) for c in tcfversion] self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: self.socket.bind(('', DISCOVEY_PORT)) @@ -325,6 +333,19 @@ class LocatorService(locator.LocatorService): def _shutdown(self): if self._alive: self._alive = False + try: + self.socket.shutdown(socket.SHUT_RDWR) + except Exception: + pass + try: + self.socket.close() + except Exception: + pass + try: + with self._addr_cache_lock: + self._addr_cache_lock.notify_all() + except Exception: + pass def __makeErrorReport(self, code, msg): err = {} @@ -354,7 +375,7 @@ class LocatorService(locator.LocatorService): channel.sendResult(token, None) elif name == "getPeers": arr = [] - for p in self.peers.values(): + for p in list(self.peers.values()): arr.append(p.getAttributes()) channel.sendResult(token, toJSONSequence((None, arr))) else: @@ -367,10 +388,16 @@ class LocatorService(locator.LocatorService): return # Don't report same error multiple times to avoid filling up the log # file. - with self._error_log_lock: - if msg in self.error_log: - return - self.error_log.add(msg) + try: + with self._error_log_lock: + if msg in self.error_log: + return + self.error_log.add(msg) + except TypeError: + # If the error_log_lock thread is dead, it just means that we are + # shutting down. The _alive value does not seem to be up to date + # in some cases ... + return protocol.log(msg, x) def __getInetAddress(self, host): @@ -411,10 +438,10 @@ class LocatorService(locator.LocatorService): # Cleanup peers table stale_peers = None - for p in self.peers.values(): + for p in list(self.peers.values()): if isinstance(p, peer.RemotePeer): if p.getLastUpdateTime() + locator.DATA_RETENTION_PERIOD < tm: - if stale_peers == None: + if stale_peers is None: stale_peers = [] stale_peers.append(p) if stale_peers is not None: @@ -423,14 +450,14 @@ class LocatorService(locator.LocatorService): # Try to become a master port = self.socket.getsockname()[1] - period = locator.DATA_RETENTION_PERIOD / 2 + period = int(locator.DATA_RETENTION_PERIOD / 2) if port != DISCOVEY_PORT and \ self.last_master_packet_time + period <= tm: s0 = self.socket s1 = None try: s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s1.bind(DISCOVEY_PORT) + s1.bind((socket.gethostname(), DISCOVEY_PORT)) s1.setsockopt(socket.SOL_UDP, socket.SO_BROADCAST, 1) self.socket = s1 s0.close() @@ -471,12 +498,11 @@ class LocatorService(locator.LocatorService): continue self.subnets.add(s) if __TRACE_DISCOVERY__: - buf = cStringIO.StringIO() - buf.write("Refreshed subnet list:") + buf = "Refreshed subnet list:" for subnet in self.subnets: - buf.write("\n\t* address=%s, broadcast=%s" % \ - (subnet.address, subnet.broadcast)) - logging.trace(buf.getvalue()) + buf += "\n\t* address=%s, broadcast=%s" % \ + (subnet.address, subnet.broadcast) + logging.trace(buf) def __getAllIpAddresses(self): import fcntl # @UnresolvedImport @@ -485,13 +511,15 @@ class LocatorService(locator.LocatorService): nBytes = 8192 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - names = array.array('B', '\0' * nBytes) - ifcfg = struct.unpack('iL', - fcntl.ioctl(s.fileno(), 0x8912, - struct.pack('iL', nBytes, - names.buffer_info()[0])))[0] + names = array.array('B', [0] * nBytes) + ifcfg = struct.unpack( + 'iL', fcntl.ioctl(s.fileno(), 0x8912, + struct.pack('iL', nBytes, + names.buffer_info()[0])))[0] namestr = names.tostring() + if namestr and isinstance(namestr[0], int): + namestr = ''.join(chr(b) for b in namestr) res = [] # the ipconf structure changed at a time, check if there are more than @@ -513,7 +541,7 @@ class LocatorService(locator.LocatorService): ipStartIx = ix + 20 ipEndIx = ix + 24 ip = namestr[ipStartIx:ipEndIx] - res.append(str(ord(ip[0])) + '.' + str(ord(ip[1])) + '.' + \ + res.append(str(ord(ip[0])) + '.' + str(ord(ip[1])) + '.' + str(ord(ip[2])) + '.' + str(ord(ip[3]))) return (res) @@ -523,21 +551,24 @@ class LocatorService(locator.LocatorService): if len(self.addr_list) == 0: # Create the list of IP address for this host _, _, self.addr_list = socket.gethostbyname_ex(hostname) - if not "127.0.0.1" in self.addr_list: + if "127.0.0.1" not in self.addr_list: self.addr_list.append("127.0.0.1") # On unix hosts, use sockets to get the other interfaces IPs if (platform.system() != 'Windows'): for ip_addr in self.__getAllIpAddresses(): - if not ip_addr in self.addr_list: + if ip_addr not in self.addr_list: self.addr_list.append(ip_addr) for address in self.addr_list: rawaddr = socket.inet_aton(address) if len(rawaddr) != 4: continue - rawaddr = rawaddr[:3] + '\xFF' + if isinstance(rawaddr, str): + rawaddr = rawaddr[:3] + '\xFF' + elif isinstance(rawaddr, bytes): + rawaddr = bytes([b for b in rawaddr[:3]] + [255]) broadcast = socket.inet_ntoa(rawaddr) _set.add(SubNet(24, InetAddress(hostname, address), InetAddress(None, broadcast))) @@ -569,7 +600,7 @@ class LocatorService(locator.LocatorService): addr == subnet.address: return False - self.socket.sendto(str(self.out_buf[:size]), + self.socket.sendto(compat.str2bytes(self.out_buf[:size]), (addr.getHostAddress(), port)) if __TRACE_DISCOVERY__: @@ -630,7 +661,7 @@ class LocatorService(locator.LocatorService): """ cnt = 0 attrs = {} - s = data[8:size].decode("UTF-8") + s = data[8:].decode("UTF-8") l = len(s) i = 0 while i < l: @@ -662,8 +693,11 @@ class LocatorService(locator.LocatorService): for subnet in self.subnets: if isinstance(_peer, peer.RemotePeer): - if self.socket.getsockname()[1] != DISCOVEY_PORT: - return + try: + if self.socket.getsockname()[1] != DISCOVEY_PORT: + return + except: + pass if not subnet.address == self.loopback_addr and \ not subnet.address == peer_addr: continue @@ -671,13 +705,10 @@ class LocatorService(locator.LocatorService): if not subnet.contains(peer_addr): continue if i == 8: - sb = cStringIO.StringIO() - for key in attrs.keys(): - sb.write(key) - sb.write('=') - sb.write(attrs.get(key)) - sb.write('\0') - bt = self.__getUTF8Bytes(sb.getvalue()) + sb = [] + for key in list(attrs.keys()): + sb.append(str(key) + '=' + str(attrs.get(key))) + bt = self.__getUTF8Bytes('\0'.join(sb)) if i + len(bt) > len(self.out_buf): return self.out_buf[i:i + len(bt)] = bt @@ -695,7 +726,7 @@ class LocatorService(locator.LocatorService): def __sendAll(self, addr, port, sl, tm): for subnet in self.subnets: subnet.send_all_ok = False - for peer in self.peers.values(): + for peer in list(self.peers.values()): self._sendPeerInfo(peer, addr, port) if addr is not None and sl is not None and \ sl.last_req_slaves_time + locator.DATA_RETENTION_PERIOD >= tm: @@ -750,7 +781,7 @@ class LocatorService(locator.LocatorService): if i > 8 and i + len(bt) >= PREF_PACKET_SIZE: self.__sendDatagramPacket(subnet, i, addr, port) i = 8 - self.out_buf[i:i+len(bt)] = bt + self.out_buf[i:len(bt)] = bt i += len(bt) self.out_buf[i] = 0 i += 1 @@ -783,14 +814,14 @@ class LocatorService(locator.LocatorService): remote_port = p.getPort() remote_address = p.getAddress() if self.__isRemote(remote_address, remote_port): - code = ord(buf[4]) - if code == locator.CONF_PEERS_REMOVED: + if buf[4] == locator.CONF_PEERS_REMOVED: self.__handlePeerRemovedPacket(p) else: sl = None if remote_port != DISCOVEY_PORT: sl = self.__addSlave(remote_address, remote_port, tm, tm) + code = ord(buf[4]) if code == locator.CONF_PEER_INFO: self.__handlePeerInfoPacket(p) elif code == locator.CONF_REQ_INFO: @@ -802,11 +833,11 @@ class LocatorService(locator.LocatorService): for subnet in self.subnets: if not subnet.contains(remote_address): continue - delay = locator.DATA_RETENTION_PERIOD / 3 + delay = int(locator.DATA_RETENTION_PERIOD / 3) if remote_port != DISCOVEY_PORT: - delay = locator.DATA_RETENTION_PERIOD / 32 + delay = int(locator.DATA_RETENTION_PERIOD / 32) elif subnet.address != remote_address: - delay = locator.DATA_RETENTION_PERIOD / 2 + delay = int(locator.DATA_RETENTION_PERIOD / 2) if subnet.last_slaves_req_time + delay <= tm: self.__sendSlavesRequest(subnet, remote_address, remote_port) @@ -815,7 +846,7 @@ class LocatorService(locator.LocatorService): remote_port == DISCOVEY_PORT: self.last_master_packet_time = tm except Exception as x: - self._log("Invalid datagram packet received from %s/%s" % \ + self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x) def __handlePeerInfoPacket(self, p): @@ -843,7 +874,7 @@ class LocatorService(locator.LocatorService): elif _peer is None: peer.RemotePeer(attrs) except Exception as x: - self._log("Invalid datagram packet received from %s/%s" % \ + self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x) def __handleReqInfoPacket(self, p, sl, tm): @@ -856,7 +887,7 @@ class LocatorService(locator.LocatorService): attrs = self.__parseIDs(p.getData(), p.getLength()) if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_SLAVES_INFO", attrs, p) - for s in attrs.values(): + for s in list(attrs.values()): i = 0 l = len(s) time0 = i @@ -888,9 +919,9 @@ class LocatorService(locator.LocatorService): time_val = time_now if time_val < 3600000: # Time stamp is "time to live" in milliseconds - time_val = time_now + time_val / 1000 - \ - locator.DATA_RETENTION_PERIOD - elif time_val < time_now / 1000 + 50000000: + time_val = time_now + int(time_val / 1000) - \ + locator.DATA_RETENTION_PERIOD + elif time_val < int(time_now / 1000) + 50000000: # Time stamp is in seconds time_val = 1000 else: @@ -899,17 +930,17 @@ class LocatorService(locator.LocatorService): if time_val < time_now - delta or \ time_val > time_now + delta: msg = "Invalid slave info timestamp: %s -> %s" % ( - timestamp, - time.strftime("%Y-%m-%d %H:%M:%S", - time.localtime(time_val / - 1000.))) + timestamp, + time.strftime("%Y-%m-%d %H:%M:%S", + time.localtime(time_val / + 1000.))) self._log("Invalid datagram packet received " + - "from %s/%s" % ( - p.getAddress(), p.getPort()), + "from %s/%s" % (p.getAddress(), + p.getPort()), Exception(msg)) time_val = time_now - \ - locator.DATA_RETENTION_PERIOD / 2 + int(locator.DATA_RETENTION_PERIOD / 2) self.__addSlave(addr, port, time_val, time_now) except Exception as x: self._log("Invalid datagram packet received from " + @@ -928,7 +959,7 @@ class LocatorService(locator.LocatorService): if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_PEERS_REMOVED", attrs, p) - for _id in attrs.values(): + for _id in list(attrs.values()): _peer = self.peers.get(_id) if isinstance(_peer, peer.RemotePeer): _peer.dispose() @@ -985,14 +1016,13 @@ class LocatorService(locator.LocatorService): # addr is a InputPacket port = addr.getPort() addr = addr.getAddress() - buf = cStringIO.StringIO() - buf.write(packet_type) - buf.write((" sent to ", " received from ")[received]) - buf.write("%s/%s" % (addr, port)) + buf = str(packet_type) + buf += (" sent to ", " received from ")[received] + buf += "%s/%s" % (addr, port) if attrs is not None: - for key, value in attrs.items(): - buf.write("\n\t%s=%s" % (key, value)) - logging.trace(buf.getvalue()) + for key, value in list(attrs.items()): + buf += "\n\t%s=%s" % (key, value) + logging.trace(buf) class LocatorServiceProvider(services.ServiceProvider): diff --git a/python/src/tcf/services/memorymap.py b/python/src/tcf/services/memorymap.py index db8ef260a..d2693787a 100644 --- a/python/src/tcf/services/memorymap.py +++ b/python/src/tcf/services/memorymap.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -114,6 +114,7 @@ MemoryRegion :members: """ +from .. import compat from .. import services NAME = "MemoryMap" @@ -148,7 +149,7 @@ class MemoryRegion(object): # <address> is an integer, <region> is a MemoryRegion object if address in region: - print address + print(address) :param props: Properties to initialise memory region with. See `Properties`_. @@ -265,9 +266,9 @@ class MemoryRegion(object): res += PROP_FILE_NAME + '=' + str(self._props.get(PROP_FILE_NAME)) res += ', ' + PROP_ID + '=' + str(self._props.get(PROP_ID)) addr = self._props.get(PROP_ADDRESS) - if isinstance(addr, int): + if isinstance(addr, compat.inttype): res += ', ' + PROP_ADDRESS + '=0x{0:08x}'.format(addr) - elif isinstance(addr, long): + elif isinstance(addr, compat.longtype): res += ', ' + PROP_ADDRESS + '=0x{0:016x}'.format(addr) else: res += ', ' + PROP_ADDRESS + '=' + str(addr) diff --git a/python/src/tcf/services/pathmap.py b/python/src/tcf/services/pathmap.py index eb7ac4084..eb0e09238 100644 --- a/python/src/tcf/services/pathmap.py +++ b/python/src/tcf/services/pathmap.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -17,8 +17,12 @@ .. |DoneSet| replace:: :class:`DoneSet` .. |PathMapRule| replace:: :class:`PathMapRule` .. |PathMapListener| replace:: :class:`PathMapListener` +.. |Properties| replace:: :ref:`Tcf-Path-Mapping-Properties` +.. |Protocols| replace:: :ref:`Tcf-Path-Mapping-Protocols` +.. _Tcf-Path-Mapping-Properties: + Path Mapping Properties ----------------------- Properties @@ -39,14 +43,15 @@ All properties are of type |basestring|. +--------------------+--------------------------------------------------------+ | PROP_ID | Rule ID. | +--------------------+--------------------------------------------------------+ -| PROP_PROTOCOL | File access protocol, see `Protocols`_, default is | -| | ``PROTOCOL_FILE``. | +| PROP_PROTOCOL | File access protocol, see |Protocols| | +--------------------+--------------------------------------------------------+ | PROP_SOURCE | Source, or compile-time file path. | +--------------------+--------------------------------------------------------+ -Protocols -^^^^^^^^^ +.. _Tcf-Path-Mapping-Protocols: + +Path Mapping Protocols +^^^^^^^^^^^^^^^^^^^^^^ All protocols are of type |basestring|. +-----------------+-----------------------------------------------------------+ @@ -147,7 +152,7 @@ class PathMapRule(object): """PathMapRule represents a single file path mapping rule. :param props: The properties to initialise this pathmap rule with. See - `Properties`_. + |Properties|. :type props: |dict| """ def __init__(self, props): @@ -169,7 +174,7 @@ class PathMapRule(object): def getProperties(self): """Get rule properties. - See `Properties`_ definitions for property names. + See |Properties| definitions for property names. Context properties are read only, clients should not try to modify them. @@ -211,12 +216,11 @@ class PathMapRule(object): def getProtocol(self): """Get file access protocol name. - See `Protocols`_ for path mapping protocol values. + See |Protocols| for path mapping protocol values. - :returns: A |basestring| representing protocol name or - ``PROTOCOL_FILE``. + :returns: A |basestring| representing protocol name or **None**. """ - return self._props.get(PROP_PROTOCOL, PROTOCOL_FILE) + return self._props.get(PROP_PROTOCOL, None) class PathMapService(services.Service): diff --git a/python/src/tcf/services/registers.py b/python/src/tcf/services/registers.py index 4fabba5e0..99ab27c35 100644 --- a/python/src/tcf/services/registers.py +++ b/python/src/tcf/services/registers.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -111,6 +111,8 @@ See |RegistersContext| | | | overwritten - every write counts. | +---------------------+--------------+----------------------------------------+ +.. _Tcf-Register-Role-Properties: + Register Role Properties ^^^^^^^^^^^^^^^^^^^^^^^^ All register roles are of type |basestring|. diff --git a/python/src/tcf/services/remote/ContextQueryProxy.py b/python/src/tcf/services/remote/ContextQueryProxy.py index a9a08dbaf..c8a7588a6 100644 --- a/python/src/tcf/services/remote/ContextQueryProxy.py +++ b/python/src/tcf/services/remote/ContextQueryProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2012-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2012-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -45,9 +45,8 @@ class ContextQueryProxy(contextquery.ContextQueryService): def __init__(self): super(GetAttrNamesCommand, self).__init__(service.channel, - service, - "getAttrNames", - None) + service, + "getAttrNames", None) def done(self, error, args): res = None diff --git a/python/src/tcf/services/remote/DiagnosticsProxy.py b/python/src/tcf/services/remote/DiagnosticsProxy.py index dd7fb4132..31e506d79 100644 --- a/python/src/tcf/services/remote/DiagnosticsProxy.py +++ b/python/src/tcf/services/remote/DiagnosticsProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -58,10 +58,13 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): if isinstance(err, errors.ErrorReport): errMap = err.getAttributes() else: + # Exception.message does not exist in python3, better use + # str(Exception) + errMap = { errors.ERROR_TIME: int(time.time() * 1000), errors.ERROR_CODE: errors.TCF_ERROR_OTHER, - errors.ERROR_FORMAT: err.message + errors.ERROR_FORMAT: str(err) } done = self._makeCallback(done) service = self diff --git a/python/src/tcf/services/remote/DisassemblyProxy.py b/python/src/tcf/services/remote/DisassemblyProxy.py index 123757a9d..94c30af60 100644 --- a/python/src/tcf/services/remote/DisassemblyProxy.py +++ b/python/src/tcf/services/remote/DisassemblyProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -65,7 +65,7 @@ class DisassemblyProxy(disassembly.DisassemblyService): def _toDisassemblyArray(o): if o is None: return None - return map(_toDisassemblyLine, o) + return list(map(_toDisassemblyLine, o)) def _toDisassemblyLine(m): diff --git a/python/src/tcf/services/remote/ExpressionsProxy.py b/python/src/tcf/services/remote/ExpressionsProxy.py index 4d21ca895..953fdf8ec 100644 --- a/python/src/tcf/services/remote/ExpressionsProxy.py +++ b/python/src/tcf/services/remote/ExpressionsProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -85,6 +85,7 @@ class ExpressionsProxy(expressions.ExpressionsService): def done(self, error, args): value = None + props = {} if not error: assert len(args) == 3 value = channel.toByteArray(args[0]) diff --git a/python/src/tcf/services/remote/FileSystemProxy.py b/python/src/tcf/services/remote/FileSystemProxy.py index 69b4d8eb6..08c97cf28 100644 --- a/python/src/tcf/services/remote/FileSystemProxy.py +++ b/python/src/tcf/services/remote/FileSystemProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -54,10 +54,10 @@ class FileSystemCommand(Command): if len(cmd) > 72: cmd = cmd[0:72] + "..." s = Status(error_code, - "TCF command exception:" + - "\nCommand: " + cmd + - "\nException: " + errors.toErrorString(data) + - "\nError code: " + str(error_code), data) + "TCF command exception:" + + "\nCommand: " + cmd + + "\nException: " + errors.toErrorString(data) + + "\nError code: " + str(error_code), data) caused_by = data.get(errors.ERROR_CAUSED_BY) if caused_by is not None: s.initCause(self.toError(caused_by, False)) @@ -480,8 +480,9 @@ class FileSystemProxy(filesystem.FileSystemService): class CopyCommand(FileSystemCommand): def __init__(self): - super(CopyCommand, self).__init__(service, "copy", - (src_path, dst_path, copy_permissions, copy_uidgid)) + copyparams = (src_path, dst_path, copy_permissions, + copy_uidgid) + super(CopyCommand, self).__init__(service, "copy", copyparams) def done(self, error, args): s = None diff --git a/python/src/tcf/services/remote/LineNumbersProxy.py b/python/src/tcf/services/remote/LineNumbersProxy.py index 5436bd695..86808c6d7 100644 --- a/python/src/tcf/services/remote/LineNumbersProxy.py +++ b/python/src/tcf/services/remote/LineNumbersProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -69,10 +69,15 @@ def _toCodeAreaArray(o): directory = area.get("Dir", directory) filePath = area.get("File", filePath) arr.append(linenumbers.CodeArea(directory, filePath, - area.get("SLine", 0), area.get("SCol", 0), - area.get("ELine", 0), area.get("ECol", 0), - area.get("SAddr"), area.get("EAddr"), - area.get("ISA", 0), - area.get("IsStmt"), area.get("BasicBlock"), - area.get("PrologueEnd"), area.get("EpilogueBegin"))) + area.get("SLine", 0), + area.get("SCol", 0), + area.get("ELine", 0), + area.get("ECol", 0), + area.get("SAddr"), + area.get("EAddr"), + area.get("ISA", 0), + area.get("IsStmt"), + area.get("BasicBlock"), + area.get("PrologueEnd"), + area.get("EpilogueBegin"))) return arr diff --git a/python/src/tcf/services/remote/LocatorProxy.py b/python/src/tcf/services/remote/LocatorProxy.py index 3fbacd340..d5b5c4159 100644 --- a/python/src/tcf/services/remote/LocatorProxy.py +++ b/python/src/tcf/services/remote/LocatorProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -155,7 +155,7 @@ class LocatorProxy(locator.LocatorService): try: l.peerRemoved(peerId) except Exception as x: - protocol.log("Unhandled exception in "\ + protocol.log("Unhandled exception in " "Locator listener", x) assert len(service.peers) == 0 diff --git a/python/src/tcf/services/remote/MemoryMapProxy.py b/python/src/tcf/services/remote/MemoryMapProxy.py index 76ed14f50..81fc3f72f 100644 --- a/python/src/tcf/services/remote/MemoryMapProxy.py +++ b/python/src/tcf/services/remote/MemoryMapProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -90,7 +90,7 @@ class ChannelEventListener(channel.EventListener): def _toMemoryMap(o): if o is None: return None - return map(_toMemoryRegion, o) + return list(map(_toMemoryRegion, o)) def _toMemoryRegion(o): diff --git a/python/src/tcf/services/remote/MemoryProxy.py b/python/src/tcf/services/remote/MemoryProxy.py index fdc51bd7a..4a2f10852 100644 --- a/python/src/tcf/services/remote/MemoryProxy.py +++ b/python/src/tcf/services/remote/MemoryProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -20,6 +20,9 @@ class Range(object): stat = 0 msg = None + def __lt__(self, o): + return self.__cmp__(o) == -1 + def __cmp__(self, o): if self.offs < o.offs: return -1 @@ -59,7 +62,7 @@ class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, l = 0 h = len(self.ranges) - 1 while l <= h: - n = (l + h) / 2 + n = int((l + h) / 2) r = self.ranges[n] if r.offs > offset: h = n - 1 @@ -75,7 +78,7 @@ class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, l = 0 h = len(self.ranges) - 1 while l <= h: - n = (l + h) / 2 + n = int((l + h) / 2) r = self.ranges[n] if r.offs > offset: h = n - 1 @@ -105,7 +108,9 @@ class MemContext(memory.MemoryContext): def done(self, error, args): e = None if error: - e = memory.MemoryError(error.message) + # XXX : fle : Exception.message does not exist in python3, + # better use str(Exception) + e = memory.MemoryError(str(error)) else: assert len(args) == 2 e = self.toMemoryError(addr, args[0], args[1]) @@ -126,7 +131,9 @@ class MemContext(memory.MemoryContext): def done(self, error, args): e = None if error: - e = memory.MemoryError(error.message) + # Exception.message does not exist in python3, better use + # str(Exception) + e = memory.MemoryError(str(error)) else: assert len(args) == 3 byts = channel.toByteArray(args[0]) @@ -152,7 +159,9 @@ class MemContext(memory.MemoryContext): def done(self, error, args): e = None if error: - e = memory.MemoryError(error.message) + # XXX : fle : Exception.message does not exist in python3, + # better use str(Exception) + e = memory.MemoryError(str(error)) else: assert len(args) == 2 e = self.toMemoryError(addr, args[0], args[1]) @@ -282,10 +291,10 @@ def _toContextArray(svc, o): def _toSizeArray(o): if o is None: return None - return map(lambda m: m.get("size", 0), o) + return [m.get("size", 0) for m in o] def _toAddrArray(o): if o is None: return None - return map(lambda m: m.get("addr"), o) + return [m.get("addr") for m in o] diff --git a/python/src/tcf/services/remote/PathMapProxy.py b/python/src/tcf/services/remote/PathMapProxy.py index 42da055f3..b2717cdb3 100644 --- a/python/src/tcf/services/remote/PathMapProxy.py +++ b/python/src/tcf/services/remote/PathMapProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -88,7 +88,7 @@ class PathMapProxy(pathmap.PathMapService): def _toPathMap(o): if o is None: return None - return map(_toPathMapRule, o) + return list(map(_toPathMapRule, o)) def _toPathMapRule(o): diff --git a/python/src/tcf/services/remote/ProcessesProxy.py b/python/src/tcf/services/remote/ProcessesProxy.py index c4fbc901b..80bb9b215 100644 --- a/python/src/tcf/services/remote/ProcessesProxy.py +++ b/python/src/tcf/services/remote/ProcessesProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -36,7 +36,7 @@ class ProcessContext(processes.ProcessContext): class _Command(Command): def __init__(self): super(_Command, self).__init__(service.channel, service, - command, (contextID,)) + command, (contextID,)) def done(self, error, args): if not error: @@ -248,7 +248,7 @@ def _toEnvStringArray(envVars): arr = [] if not envVars: return arr - for name, value in envVars.items(): + for name, value in list(envVars.items()): arr.append("%s=%s" % (name, value)) return arr diff --git a/python/src/tcf/services/remote/ProcessesV1Proxy.py b/python/src/tcf/services/remote/ProcessesV1Proxy.py index 2eab77963..b88431966 100644 --- a/python/src/tcf/services/remote/ProcessesV1Proxy.py +++ b/python/src/tcf/services/remote/ProcessesV1Proxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -47,16 +47,24 @@ class ProcessesV1Proxy(ProcessesProxy.ProcessesProxy, class GetCapabilitiesCommand(Command): def __init__(self): - super(GetCapabilitiesCommand, - self).__init__(service.channel, service, - "getCapabilities", (contextId,)) + super(GetCapabilitiesCommand, self).__init__(service.channel, + service, + "getCapabilities", + (contextId,)) def done(self, error, args): capabilityData = None if not error: - assert len(args) == 2 - error = self.toError(args[0]) - capabilityData = args[1] + # Defect WB4-1784, getting capabilities with a null + # context ID does not return the global system capabilities + # as it should + if len(args) == 1: + error = self.toError(args[0]) + capabilityData = {} + else: + assert len(args) == 2 + error = self.toError(args[0]) + capabilityData = args[1] done.doneGetCapabilities(self.token, error, capabilityData) diff --git a/python/src/tcf/services/remote/RunControlProxy.py b/python/src/tcf/services/remote/RunControlProxy.py index 7675a129c..72a5db284 100644 --- a/python/src/tcf/services/remote/RunControlProxy.py +++ b/python/src/tcf/services/remote/RunControlProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -134,6 +134,9 @@ class ChannelEventListener(channel.EventListener): elif name == "containerResumed": assert len(args) == 1 self.listener.containerResumed(args[0]) + elif name == "contextStateChanged": + assert len(args) == 1 + self.listener.contextStateChanged(args[0]) else: raise IOError("RunControl service: unknown event: " + name) except Exception as x: diff --git a/python/src/tcf/services/remote/StackTraceProxy.py b/python/src/tcf/services/remote/StackTraceProxy.py index 843cf1e8c..6375ecdd7 100644 --- a/python/src/tcf/services/remote/StackTraceProxy.py +++ b/python/src/tcf/services/remote/StackTraceProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2015-2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -29,14 +29,38 @@ class StackTraceProxy(stacktrace.StackTraceService): (parent_context_id,)) def done(self, error, args): - contexts = None + contextIds = None if not error: assert len(args) == 2 error = self.toError(args[0]) - contexts = args[1] - done.doneGetChildren(self.token, error, contexts) + contextIds = args[1] + done.doneGetChildren(self.token, error, contextIds) return GetChildrenCommand().token + def getChildrenRange(self, parent_context_id, range_start, range_end, + done): + done = self._makeCallback(done) + service = self + + class GetChildrenRangeCommand(Command): + def __init__(self): + super(GetChildrenRangeCommand, self).__init__( + service.channel, + service, + "getChildrenRange", + (parent_context_id, + range_start, + range_end,)) + + def done(self, error, args): + contextIds = None + if not error: + assert len(args) == 2 + error = self.toError(args[0]) + contextIds = args[1] + done.doneGetChildren(self.token, error, contextIds) + return GetChildrenRangeCommand().token + def getContext(self, ids, done): done = self._makeCallback(done) service = self diff --git a/python/src/tcf/services/remote/SymbolsProxy.py b/python/src/tcf/services/remote/SymbolsProxy.py index bce60ac0b..42757105f 100644 --- a/python/src/tcf/services/remote/SymbolsProxy.py +++ b/python/src/tcf/services/remote/SymbolsProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -14,11 +14,16 @@ from ... import channel from ...channel.Command import Command -class Context(symbols.Symbol): +class SymbolWithValue(symbols.Symbol): def __init__(self, props): - super(Context, self).__init__(props) + super(SymbolWithValue, self).__init__(props) self.value = channel.toByteArray(props.get(symbols.PROP_VALUE)) + def __str__(self): + res = symbols.Symbol.__str__(self).rstrip(']') + res += ', value=' + str(self.value) + ']' + return res + def getValue(self): return self.value @@ -44,7 +49,7 @@ class SymbolsProxy(symbols.SymbolsService): assert len(args) == 2 error = self.toError(args[0]) if args[1]: - ctx = Context(args[1]) + ctx = SymbolWithValue(args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token diff --git a/python/src/tcf/services/runcontrol.py b/python/src/tcf/services/runcontrol.py index e84d7f577..729a94017 100644 --- a/python/src/tcf/services/runcontrol.py +++ b/python/src/tcf/services/runcontrol.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -526,8 +526,8 @@ class RunControlISA(object): res += 'Address=' + str(self.getAddress()) + ', ' res += ISA_SIZE + '=' + str(self.getSize()) + ', ' res += ISA_ALIGNMENT + '=' + str(self.getAlignment()) + ', ' - res += ISA_MAX_INSTRUCTION_SIZE + '=' + \ - str(self.getMaxInstructionSize()) + ', ' + res += ISA_MAX_INSTRUCTION_SIZE + '=' + res += str(self.getMaxInstructionSize()) + ', ' res += 'Default=' + str(self.getDefault()) res += ']' return res @@ -980,6 +980,18 @@ class RunControlListener(object): """ pass + def contextStateChanged(self, context): + """Called when context state changes and the context is not and was not + in suspended state. + + Changes to and from suspended state should be reported by other events: + contextSuspended, contextResumed, containerSuspended, containerResumed. + + :param context: ID of a context that changed state. + :type context: |basestring| + """ + pass + def contextSuspended(self, context, pc, reason, params): """Called when a thread is suspended. diff --git a/python/src/tcf/services/stacktrace.py b/python/src/tcf/services/stacktrace.py index 7db48c29e..c8eb09829 100644 --- a/python/src/tcf/services/stacktrace.py +++ b/python/src/tcf/services/stacktrace.py @@ -1,5 +1,5 @@ -#****************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2014-2015, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -7,11 +7,12 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -#****************************************************************************** +# ***************************************************************************** """TCF stacktrace service interface. .. |getChildren| replace:: :meth:`~StackTraceService.getChildren` +.. |getChildrenRange| replace:: :meth:`~StackTraceService.getChildrenRange` .. |getContext| replace:: :meth:`~StackTraceService.getContext` .. |runcontrol| replace:: :mod:`~tcf.services.runcontrol` .. |DoneGetChildren| replace:: :class:`DoneGetChildren` @@ -35,6 +36,9 @@ Properties +--------------------------+--------------+-----------------------------------+ | PROP_ID | |basestring| | String, stack frame ID. | +--------------------------+--------------+-----------------------------------+ +| PROP_INDEX | |int| | Stack frame level, starting from | +| | | stack top. | ++--------------------------+--------------+-----------------------------------+ | PROP_INSTRUCTION_ADDRESS | |int| | Instruction pointer. | +--------------------------+--------------+-----------------------------------+ | PROP_LEVEL | |int| | Stack frame level, starting from | @@ -51,6 +55,15 @@ Properties | PROP_TOP_FRAME | |bool| | **True** if the frame is top frame| | | | on a stack. | +--------------------------+--------------+-----------------------------------+ +| PROP_WALK | |bool| | **True** if the frame is found by | +| | | stack walking (debug info). | ++--------------------------+--------------+-----------------------------------+ +| PROP_INLINED | |int| | Inlined function level. | ++--------------------------+--------------+-----------------------------------+ +| PROP_FUNC_ID | |basestring| | Function symbol ID. | ++--------------------------+--------------+-----------------------------------+ +| PROP_CODE_AREA | |CodeArea| | Call site code area. | ++--------------------------+--------------+-----------------------------------+ Service Methods --------------- @@ -69,6 +82,10 @@ getChildren ^^^^^^^^^^^ .. automethod:: StackTraceService.getChildren +getChildrenRange +^^^^^^^^^^^^^^^^ +.. automethod:: StackTraceService.getChildrenRange + Callback Classes ---------------- DoneGetContext @@ -91,6 +108,7 @@ StackTraceContext """ from .. import services +from .remote.LineNumbersProxy import _toCodeAreaArray NAME = "StackTrace" """StackTrace service name.""" @@ -108,6 +126,9 @@ PROP_ARGUMENTS_COUNT = "ArgsCnt" PROP_ARGUMENTS_ADDRESS = "ArgsAddr" PROP_INDEX = "Index" PROP_WALK = "Walk" +PROP_INLINED = "Inlined" +PROP_FUNC_ID = "FuncID" +PROP_CODE_AREA = "CodeArea" class StackTraceService(services.Service): @@ -134,7 +155,7 @@ class StackTraceService(services.Service): raise NotImplementedError("Abstract method") def getChildren(self, parent_context_id, done): - """Retrieve stack trace context list. + """Retrieve stack trace contexts list. Parent context usually corresponds to an execution thread. @@ -152,6 +173,31 @@ class StackTraceService(services.Service): """ raise NotImplementedError("Abstract method") + def getChildrenRange(self, parent_context_id, range_start, range_end, + done): + """Retrieve a range of stack trace contexts. + + Parent context usually corresponds to an execution thread. + + 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 :meth:`getChildren` commands. + + 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. + :type parent_context_id: |basestring| + :param range_start: Start index of the range (inclusive). Index 0 is + the top frame. + :type range_start: |int| + :param range_end: End index of the range (inclusive). + :type range_end: |int| + :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|.""" @@ -351,6 +397,39 @@ class StackTraceContext(object): """ return self._props.get(PROP_ARGUMENTS_ADDRESS, None) + def getInlined(self): + """Get inlined function level. + + :returns: An |int| representing the inlined function level, or + **None**. + """ + return self._props.get(PROP_INLINED, None) + + def getFuncID(self): + """Get function symbol ID. + + If **None**, client should use Symbols service to find function + symbol ID. + + :returns: A |basestring| representing function symbol ID, or an empty + |basestring| if unknown. + """ + return self._props.get(PROP_FUNC_ID, '') + + def getCodeArea(self): + """Get code area context. + + Get code area that describes source code location of the frame. + If **None**, client should use LineNumbers service to find frame source + location. + + :returns: A |list| of |CodeArea| objects. representing this stack code + area or **None** if not available. + """ + if self._props.get(PROP_CODE_AREA, None): + return _toCodeAreaArray((self._props.get(PROP_CODE_AREA, None),)) + return None + def getProperties(self): """Get complete map of context properties. diff --git a/python/src/tcf/services/symbols.py b/python/src/tcf/services/symbols.py index 9c574286d..bf7594ef8 100644 --- a/python/src/tcf/services/symbols.py +++ b/python/src/tcf/services/symbols.py @@ -1,5 +1,5 @@ -#****************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2014-2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -7,7 +7,7 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -#****************************************************************************** +# ***************************************************************************** """TCF symbols service interface. @@ -62,17 +62,23 @@ Symbol Context Properties | PROP_BIG_ENDIAN | |bool| | **True** if symbol's value is big | | | | endian. | +--------------------+--------------+-----------------------------------------+ +| PROP_BIT_STRIDE | |int| | Symbol's bit stride (if any). | ++--------------------+--------------+-----------------------------------------+ | PROP_CONTAINER_ID | |basestring| | ID of the symbol containing this symbol.| +--------------------+--------------+-----------------------------------------+ | PROP_FLAGS | |int| | Symbol flags. See | | | | `Symbol Flags Properties`_. | +--------------------+--------------+-----------------------------------------+ +| PROP_FRAME | |int| | Symbol frame index. | ++--------------------+--------------+-----------------------------------------+ | PROP_ID | |basestring| | Symbol's unique TCF ID. | +--------------------+--------------+-----------------------------------------+ | PROP_INDEX_TYPE_ID | |basestring| | Index type ID. | +--------------------+--------------+-----------------------------------------+ | PROP_LENGTH | |int| | Symbol length (if applicable) | +--------------------+--------------+-----------------------------------------+ +| PROP_LOC_ENT_OFFSET| |int| | Symbol local entry point offset. | ++--------------------+--------------+-----------------------------------------+ | PROP_LOWER_BOUND | |int| | Symbol's lower bound in memory. | +--------------------+--------------+-----------------------------------------+ | PROP_NAME | |basestring| | Symbol's name. | @@ -114,7 +120,7 @@ All symbol flags are of type |int|. +-------------------------+--------------------------------+ | SYM_FLAG_BIG_ENDIAN | Symbol is big endian. | +-------------------------+--------------------------------+ -| SYM_FLAG_BOOL_TYPE | Symbol is a boolean | +| SYM_FLAG_BOOL_TYPE | Symbol is a boolean. | +-------------------------+--------------------------------+ | SYM_FLAG_CLASS_TYPE | Symbol is a class type symbol. | +-------------------------+--------------------------------+ @@ -124,7 +130,9 @@ All symbol flags are of type |int|. +-------------------------+--------------------------------+ | SYM_FLAG_EXTERNAL | Symbol is external. | +-------------------------+--------------------------------+ -| SYM_FLAG_INHERITANCE | Symbol is a base class | +| SYM_FLAG_INDIRECT | Symbol is a data indirection. | ++-------------------------+--------------------------------+ +| SYM_FLAG_INHERITANCE | Symbol is a base class. | +-------------------------+--------------------------------+ | SYM_FLAG_INTERFACE_TYPE | Symbol is an interface. | +-------------------------+--------------------------------+ @@ -146,6 +154,8 @@ All symbol flags are of type |int|. +-------------------------+--------------------------------+ | SYM_FLAG_RESTRICT_TYPE | Symbol is of restrict type. | +-------------------------+--------------------------------+ +| SYM_FLAG_RVALUE | Symbol is a rvalue reference. | ++-------------------------+--------------------------------+ | SYM_FLAG_SHARED_TYPE | Symbol is of shared type. | +-------------------------+--------------------------------+ | SYM_FLAG_STRUCT_TYPE | Symbol is of structure type. | @@ -265,26 +275,30 @@ Symbol Location Properties .. seealso:: |getLocationInfo| -+-----------------+--------+--------------------------------------------------+ -| Name | Type | Description | -+=================+========+==================================================+ -| LOC_ARG_CNT | |int| | Number of argument required to execute location | -| | | instructions. | -+-----------------+--------+--------------------------------------------------+ -| LOC_CODE_ADDR | |int| | Start address of code range where the location | -| | | info is valid, or **None** if it is valid | -| | | everywhere. | -+-----------------+--------+--------------------------------------------------+ -| LOC_CODE_SIZE | |int| | Size in bytes of code range where the location | -| | | info is valid, or **None** if it is valid | -| | | everywhere. | -+-----------------+--------+--------------------------------------------------+ -| LOC_LENGTH_CMDS | |list| | Instructions to compute dynamic array length | -| | | location. | -+-----------------+--------+--------------------------------------------------+ -| LOC_VALUE_CMDS | |list| | Instructions to compute object value location, | -| | | e.g. address, or offset, or register ID, etc... | -+-----------------+--------+--------------------------------------------------+ ++------------------+--------+-------------------------------------------------+ +| Name | Type | Description | ++==================+========+=================================================+ +| LOC_ARG_CNT | |int| | Number of argument required to execute location | +| | | instructions. | ++------------------+--------+-------------------------------------------------+ +| LOC_CODE_ADDR | |int| | Start address of code range where the location | +| | | info is valid, or **None** if it is valid | +| | | everywhere. | ++------------------+--------+-------------------------------------------------+ +| LOC_CODE_SIZE | |int| | Size in bytes of code range where the location | +| | | info is valid, or **None** if it is valid | +| | | everywhere. | ++------------------+--------+-------------------------------------------------+ +| LOC_LENGTH_CMDS | |list| | Instructions to compute dynamic array length | +| | | location. | ++------------------+--------+-------------------------------------------------+ +| LOC_VALUE_CMDS | |list| | Instructions to compute object value location, | +| | | e.g. address, or offset, or register ID, etc... | ++------------------+--------+-------------------------------------------------+ +| LOC_DISCRIMINANT | |list| | List of discriminant values for a variant. | +| | | Each element of the list is a |dict| with two | +| | | values, the lower bound 'X' and upper bound 'Y'.| ++------------------+--------+-------------------------------------------------+ Service Methods --------------- @@ -383,15 +397,22 @@ DoneList Helper Classes -------------- + +.. _Tcf-Symbol: + Symbol ^^^^^^ .. autoclass:: Symbol :members: +.. _Tcf-Symbol-Class: + SymbolClass ^^^^^^^^^^^ .. autoclass:: SymbolClass +.. _Tcf-Symbol-Type-Class: + TypeClass ^^^^^^^^^ .. autoclass:: TypeClass @@ -415,30 +436,34 @@ class SymbolClass: if symbol.getSymbolClass() is tcfsyms.TypeClass.function: # Print name + address - print '{0} : 0x{1:016x}'.format(symbol.getName(), - symbol.getAddress()) + print('{0} : 0x{1:016x}'.format(symbol.getName(), + symbol.getAddress())) Here is the value/class association table: - +-------+-----------+-----------------------+ - | Value | Name | Description | - +=======+===========+=======================+ - | **0** | unknown | Unknown symbol class. | - +-------+-----------+-----------------------+ - | **1** | value | Constant value. | - +-------+-----------+-----------------------+ - | **2** | reference | Variable data object. | - +-------+-----------+-----------------------+ - | **3** | function | Function body. | - +-------+-----------+-----------------------+ - | **4** | type | A type. | - +-------+-----------+-----------------------+ - | **5** | comp_unit | A compilation unit. | - +-------+-----------+-----------------------+ - | **6** | block | A block of code. | - +-------+-----------+-----------------------+ - | **7** | namespace | A namespace. | - +-------+-----------+-----------------------+ + +-------+--------------+-----------------------------+ + | Value | Name | Description | + +=======+==============+=============================+ + | **0** | unknown | Unknown symbol class. | + +-------+--------------+-----------------------------+ + | **1** | value | Constant value. | + +-------+--------------+-----------------------------+ + | **2** | reference | Variable data object. | + +-------+--------------+-----------------------------+ + | **3** | function | Function body. | + +-------+--------------+-----------------------------+ + | **4** | type | A type. | + +-------+--------------+-----------------------------+ + | **5** | comp_unit | A compilation unit. | + +-------+--------------+-----------------------------+ + | **6** | block | A block of code. | + +-------+--------------+-----------------------------+ + | **7** | namespace | A namespace. | + +-------+--------------+-----------------------------+ + | **8** | variant_part | A variant part. | + +-------+--------------+-----------------------------+ + | **9** | variant | A member of a variant part. | + +-------+--------------+-----------------------------+ """ unknown = 0 value = 1 @@ -448,6 +473,8 @@ class SymbolClass: comp_unit = 5 block = 6 namespace = 7 + variant_part = 8 + variant = 9 class TypeClass: @@ -461,8 +488,8 @@ class TypeClass: if symbol.getTypeClass() is tcfsyms.TypeClass.pointer: # print it as a pointer - print '{0} : 0x{1:016x}'.format(symbol.getName(), - symbol.getAddress()) + print('{0} : 0x{1:016x}'.format(symbol.getName(), + symbol.getAddress())) Here is the value/type association table: @@ -501,33 +528,35 @@ class TypeClass: function = 8 member_ptr = 9 -SYM_FLAG_PARAMETER = 0x000001 -SYM_FLAG_TYPEDEF = 0x000002 -SYM_FLAG_CONST_TYPE = 0x000004 -SYM_FLAG_PACKET_TYPE = 0x000008 -SYM_FLAG_SUBRANGE_TYPE = 0x000010 -SYM_FLAG_VOLATILE_TYPE = 0x000020 -SYM_FLAG_RESTRICT_TYPE = 0x000040 -SYM_FLAG_UNION_TYPE = 0x000080 -SYM_FLAG_CLASS_TYPE = 0x000100 -SYM_FLAG_INTERFACE_TYPE = 0x000200 -SYM_FLAG_SHARED_TYPE = 0x000400 -SYM_FLAG_REFERENCE = 0x000800 -SYM_FLAG_BIG_ENDIAN = 0x001000 -SYM_FLAG_LITTLE_ENDIAN = 0x002000 -SYM_FLAG_OPTIONAL = 0x004000 -SYM_FLAG_EXTERNAL = 0x008000 -SYM_FLAG_VARARG = 0x010000 -SYM_FLAG_ARTIFICIAL = 0x020000 -SYM_FLAG_TYPE_PARAMETER = 0x040000 -SYM_FLAG_PRIVATE = 0x080000 -SYM_FLAG_PROTECTED = 0x0100000 -SYM_FLAG_PUBLIC = 0x0200000 -SYM_FLAG_ENUM_TYPE = 0x0400000 -SYM_FLAG_STRUCT_TYPE = 0x0800000 -SYM_FLAG_STRING_TYPE = 0x1000000 -SYM_FLAG_INHERITANCE = 0x2000000 -SYM_FLAG_BOOL_TYPE = 0x4000000 +SYM_FLAG_PARAMETER = 0x0000001 +SYM_FLAG_TYPEDEF = 0x0000002 +SYM_FLAG_CONST_TYPE = 0x0000004 +SYM_FLAG_PACKET_TYPE = 0x0000008 +SYM_FLAG_SUBRANGE_TYPE = 0x0000010 +SYM_FLAG_VOLATILE_TYPE = 0x0000020 +SYM_FLAG_RESTRICT_TYPE = 0x0000040 +SYM_FLAG_UNION_TYPE = 0x0000080 +SYM_FLAG_CLASS_TYPE = 0x0000100 +SYM_FLAG_INTERFACE_TYPE = 0x0000200 +SYM_FLAG_SHARED_TYPE = 0x0000400 +SYM_FLAG_REFERENCE = 0x0000800 +SYM_FLAG_BIG_ENDIAN = 0x0001000 +SYM_FLAG_LITTLE_ENDIAN = 0x0002000 +SYM_FLAG_OPTIONAL = 0x0004000 +SYM_FLAG_EXTERNAL = 0x0008000 +SYM_FLAG_VARARG = 0x0010000 +SYM_FLAG_ARTIFICIAL = 0x0020000 +SYM_FLAG_TYPE_PARAMETER = 0x0040000 +SYM_FLAG_PRIVATE = 0x0080000 +SYM_FLAG_PROTECTED = 0x00100000 +SYM_FLAG_PUBLIC = 0x00200000 +SYM_FLAG_ENUM_TYPE = 0x00400000 +SYM_FLAG_STRUCT_TYPE = 0x00800000 +SYM_FLAG_STRING_TYPE = 0x01000000 +SYM_FLAG_INHERITANCE = 0x02000000 +SYM_FLAG_BOOL_TYPE = 0x04000000 +SYM_FLAG_INDIRECT = 0x08000000 +SYM_FLAG_RVALUE = 0x10000000 # Symbol context property names. @@ -551,12 +580,55 @@ PROP_BIG_ENDIAN = "BigEndian" PROP_REGISTER = "Register" PROP_FLAGS = "Flags" PROP_CONTAINER_ID = "ContainerID" +PROP_FRAME = "Frame" +PROP_LOC_ENT_OFFSET = "LocalEntryOffset" +PROP_BIT_STRIDE = "BitStride" # Symbol context properties update policies. UPDATE_ON_MEMORY_MAP_CHANGES = 0 UPDATE_ON_EXE_STATE_CHANGES = 1 +# Command codes that are used to calculate frame pointer and register values +# during stack tracing. + +CMD_NUMBER = 1 +CMD_FP = 3 +CMD_ADD = 5 +CMD_SUB = 6 +CMD_MUL = 7 +CMD_DIV = 8 +CMD_AND = 9 +CMD_OR = 10 +CMD_XOR = 11 +CMD_NEG = 12 +CMD_GE = 13 +CMD_GT = 14 +CMD_LE = 15 +CMD_LT = 16 +CMD_SHL = 17 +CMD_SHR = 18 +CMD_ARG = 19 +CMD_LOCATION = 20 +CMD_FCALL = 21 +CMD_WR_REG = 22 +CMD_WR_MEM = 23 +CMD_PIECE = 24 + +# Deprecated + +CMD_REGISTER = 2 +CMD_DEREF = 4 + +# Symbol location properties. + +LOC_CODE_ADDR = "CodeAddr" +LOC_CODE_SIZE = "CodeSize" +LOC_ARG_CNT = "ArgCnt" +LOC_VALUE_CMDS = "ValueCmds" +LOC_LENGTH_CMDS = "LengthCmds" +LOC_DISCRIMINANT = "Discriminant" + class Symbol(object): """Symbol context interface. @@ -569,16 +641,105 @@ class Symbol(object): def __init__(self, props): self._props = props or {} + def __repr__(self): + return self.__class__.__name__ + '(' + repr(self._props) + ')' + def __str__(self): - return "[Symbol Context %s]" % self._props + res = self.__class__.__name__ + ' [' + for key in list(self._props.keys()): + res += str(key) + '=' + str(self._props.get(key)) + if key == PROP_SYMBOL_CLASS: + # Add a meaningful word here. + value = self._props.get(key) + for attr in dir(SymbolClass): + if getattr(SymbolClass, attr) == value: + res += '(' + attr + ')' + break + if key == PROP_TYPE_CLASS: + # Add a meaningful word here. + value = self._props.get(key) + for attr in dir(TypeClass): + if getattr(TypeClass, attr) == value: + res += '(' + attr + ')' + break + if key == PROP_FLAGS and self._props.get(key) != 0: + value = self._props.get(key) + flags = [] + if value & SYM_FLAG_PARAMETER: + flags.append('PARAMETER') + if value & SYM_FLAG_TYPEDEF: + flags.append('TYPEDEF') + if value & SYM_FLAG_CONST_TYPE: + flags.append('CONST_TYPE') + if value & SYM_FLAG_PACKET_TYPE: + flags.append('PACKET_TYPE') + if value & SYM_FLAG_SUBRANGE_TYPE: + flags.append('SUBRANGE_TYPE') + if value & SYM_FLAG_VOLATILE_TYPE: + flags.append('VOLATILE_TYPE') + if value & SYM_FLAG_RESTRICT_TYPE: + flags.append('RESTRICT_TYPE') + if value & SYM_FLAG_UNION_TYPE: + flags.append('UNION_TYPE') + if value & SYM_FLAG_CLASS_TYPE: + flags.append('CLASS_TYPE') + if value & SYM_FLAG_INTERFACE_TYPE: + flags.append('INTERFACE_TYPE') + if value & SYM_FLAG_SHARED_TYPE: + flags.append('SHARED_TYPE') + if value & SYM_FLAG_REFERENCE: + flags.append('REFERENCE') + if value & SYM_FLAG_BIG_ENDIAN: + flags.append('BIG_ENDIAN') + if value & SYM_FLAG_LITTLE_ENDIAN: + flags.append('LITTLE_ENDIAN') + if value & SYM_FLAG_OPTIONAL: + flags.append('OPTIONAL') + if value & SYM_FLAG_EXTERNAL: + flags.append('EXTERNAL') + if value & SYM_FLAG_VARARG: + flags.append('VARARG') + if value & SYM_FLAG_ARTIFICIAL: + flags.append('ARTIFICIAL') + if value & SYM_FLAG_TYPE_PARAMETER: + flags.append('TYPE_PARAMETER') + if value & SYM_FLAG_PRIVATE: + flags.append('PRIVATE') + if value & SYM_FLAG_PROTECTED: + flags.append('PROTECTED') + if value & SYM_FLAG_PUBLIC: + flags.append('PUBLIC') + if value & SYM_FLAG_ENUM_TYPE: + flags.append('ENUM_TYPE') + if value & SYM_FLAG_STRUCT_TYPE: + flags.append('STRUCT_TYPE') + if value & SYM_FLAG_STRING_TYPE: + flags.append('STRING_TYPE') + if value & SYM_FLAG_INHERITANCE: + flags.append('INHERITANCE') + if value & SYM_FLAG_BOOL_TYPE: + flags.append('BOOL_TYPE') + res += '(' + '|'.join(flags) + ')' + res += ', ' + res = res.rstrip(', ') + res += ']' + return res def getID(self): """Get symbol ID. - :returns: A |basestring| reprsenting this symbol's unique TCF ID. + :returns: A |basestring| representing this symbol's unique TCF ID. """ return self._props.get(PROP_ID) + def getFrame(self): + """Get symbol frame index. + + :returns: A |int| representing frame index (from top stack frame), or + **None** if the symbol is not defined in a frame. + """ + return self._props.get(PROP_FRAME, None) + def getOwnerID(self): """Get symbol owner ID. @@ -654,6 +815,14 @@ class Symbol(object): """ return self._props.get(PROP_BASE_TYPE_ID) + def getBitStride(self): + """Return bit stride of this symbol for this array. + + :returns: An |int| reprsenting this symbol's bit stride in bits or + **None**. + """ + return self._props.get(PROP_BIT_STRIDE) + def getContainerID(self): """Get container type ID. @@ -747,6 +916,14 @@ class Symbol(object): """ return self._props.get(PROP_FLAGS, 0) + def getLocalEntryOffset(self): + """Return offset of the symbol local entry point. + + :returns: An |int| representing this symbol's local entry point offset + or **None** + """ + return self._props.get(PROP_LOC_ENT_OFFSET) + def getProperties(self): """Get complete map of context properties. @@ -1051,45 +1228,6 @@ class DoneGetArrayType(object): """ pass -# Command codes that are used to calculate frame pointer and register values -# during stack tracing. - -CMD_NUMBER = 1 -CMD_FP = 3 -CMD_ADD = 5 -CMD_SUB = 6 -CMD_MUL = 7 -CMD_DIV = 8 -CMD_AND = 9 -CMD_OR = 10 -CMD_XOR = 11 -CMD_NEG = 12 -CMD_GE = 13 -CMD_GT = 14 -CMD_LE = 15 -CMD_LT = 16 -CMD_SHL = 17 -CMD_SHR = 18 -CMD_ARG = 19 -CMD_LOCATION = 20 -CMD_FCALL = 21 -CMD_WR_REG = 22 -CMD_WR_MEM = 23 -CMD_PIECE = 24 - -# Deprecated - -CMD_REGISTER = 2 -CMD_DEREF = 4 - -# Symbol location properties. - -LOC_CODE_ADDR = "CodeAddr" -LOC_CODE_SIZE = "CodeSize" -LOC_ARG_CNT = "ArgCnt" -LOC_VALUE_CMDS = "ValueCmds" -LOC_LENGTH_CMDS = "LengthCmds" - class DoneFindFrameInfo(object): """Client call back interface for |findFrameInfo|.""" diff --git a/python/src/tcf/services/sysmonitor.py b/python/src/tcf/services/sysmonitor.py index 6e5d69218..9ccd13462 100644 --- a/python/src/tcf/services/sysmonitor.py +++ b/python/src/tcf/services/sysmonitor.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -244,6 +244,8 @@ NAME = "SysMonitor" # Context property names. PROP_ID = "ID" PROP_PARENTID = "ParentID" +PROP_SYSTEMID = "SystemID" +PROP_SYSTEMTYPE = "SystemType" PROP_CWD = "CWD" PROP_ROOT = "Root" PROP_UID = "UID" @@ -328,6 +330,22 @@ class SysMonitorContext(object): """ return self._props.get(PROP_PARENTID, '') + def getSystemID(self): + """Get target context ID. + + :returns: A |basestring| representing this target context ID or None + if unspecified. + """ + return self._props.get(PROP_SYSTEMID, None) + + def getSystemType(self): + """Get target context type. + + :returns: A |basestring| representing this target context type or None + if unspecified. + """ + return self._props.get(PROP_SYSTEMTYPE, None) + def getPGRP(self): """Get process group ID. diff --git a/python/src/tcf/shell.py b/python/src/tcf/shell.py index b392ef7a7..cd1459121 100644 --- a/python/src/tcf/shell.py +++ b/python/src/tcf/shell.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -53,8 +53,8 @@ class print_peers: def __repr__(self): peers = tcf.peers() - return '\n'.join(map(lambda p: "%s, %s" % (p.getID(), p.getName()), - peers.values())) + return '\n'.join(["%s, %s" % (p.getID(), p.getName()) + for p in list(peers.values())]) class Shell(code.InteractiveConsole, protocol.ChannelOpenListener, diff --git a/python/src/tcf/tests/BasicTests.py b/python/src/tcf/tests/BasicTests.py index 5b14c6340..e4218271e 100644 --- a/python/src/tcf/tests/BasicTests.py +++ b/python/src/tcf/tests/BasicTests.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -24,13 +24,13 @@ __TRACE = False class TraceListener(channel.TraceListener): def onMessageReceived(self, msgType, token, service, name, data): - print "<<<", msgType, token, service, name, data + print("<<< ", msgType, token, service, name, data) def onMessageSent(self, msgType, token, service, name, data): - print ">>>", msgType, token, service, name, data + print(">>>", msgType, token, service, name, data) def onChannelClosed(self, error): - print >> sys.stderr, "*** closed ***", error + sys.stderr.write("*** closed *** " + str(error) + "\n") _suspended = [] _memory = [] @@ -50,8 +50,8 @@ def test(): assert c.state == channel.STATE_OPEN if __TRACE: protocol.invokeAndWait(c.addTraceListener, TraceListener()) - _services = protocol.invokeAndWait(c.getRemoteServices) - print "services=", _services + _services = sorted(protocol.invokeAndWait(c.getRemoteServices)) + print("services=" + str(_services)) if "RunControl" in _services: # RunControl must be first @@ -60,14 +60,14 @@ def test(): for service in _services: testFct = globals().get("test" + service) if testFct: - print "Testing service '%s'..." % service + print("Testing service '%s'..." % service) try: testFct(c) - print "Completed test of service '%s'." % service + print("Completed test of service '%s'." % service) except Exception as e: protocol.log("Exception testing %s" % service, e) else: - print "No test for service '%s' found." % service + print("No test for service '%s' found." % service) try: testSyncCommands(c) testTasks(c) @@ -87,11 +87,11 @@ def testTimer(): def countdown(left): if left == 0: - print "Ignition sequence started!" + print("Ignition sequence started!") with cond: cond.notify() return - print "%d seconds to go" % left + print("%d seconds to go" % left) sys.stdout.flush() protocol.invokeLaterWithDelay(1000, countdown, left - 1) with cond: @@ -113,7 +113,7 @@ def testRunControl(c): if error: protocol.log("Error from RunControl.getContext", error) else: - print context + print(context) class DoneGetState(runcontrol.DoneGetState): @@ -124,10 +124,10 @@ def testRunControl(c): protocol.log( "Error from RunControl.getState", error) else: - print "suspended: ", suspended - print "pc: ", pc - print "reason: ", reason - print "params: ", params + print("suspended: " + str(suspended)) + print("pc: " + str(pc)) + print("reason: " + str(reason)) + print("params: " + str(params)) if suspended: _suspended.append(context.getID()) if len(pending) == 0: @@ -161,18 +161,18 @@ def testRunControl(c): class RCListener(runcontrol.RunControlListener): def contextSuspended(self, *args): - print "context suspended: ", args + print("context suspended: " + str(args)) rc.removeListener(self) def contextResumed(self, *args): - print "context resumed: ", args + print("context resumed: " + str(args)) def containerSuspended(self, *args): - print "container suspended:", args + print("container suspended: " + str(args)) rc.removeListener(self) def containerResumed(self, *args): - print "container resumed:", args + print("container resumed: " + str(args)) rc.addListener(RCListener()) class DoneGetContext(runcontrol.DoneGetContext): @@ -198,6 +198,7 @@ def testRunControl(c): with lock: protocol.invokeLater(listenerTest) lock.wait(5) + _suspended.pop(0) def testBreakpoints(c): @@ -210,19 +211,19 @@ def testBreakpoints(c): if error: protocol.log("Error from Breakpoints.getIDs", error) return - print "Breakpoints :", ids + print("Breakpoints : " + str(ids)) def doneGetProperties(token, error, props): if error: protocol.log("Error from Breakpoints.getProperties", error) return - print "Breakpoint Properties: ", props + print("Breakpoint Properties: " + str(props)) def doneGetStatus(token, error, props): if error: protocol.log("Error from Breakpoints.getStatus", error) return - print "Breakpoint Status: ", props + print("Breakpoint Status: " + str(props)) for bpid in ids: bps.getProperties(bpid, doneGetProperties) bps.getStatus(bpid, doneGetStatus) @@ -234,17 +235,18 @@ def testBreakpoints(c): class BPListener(breakpoints.BreakpointsListener): def breakpointStatusChanged(self, bpid, status): - print "breakpointStatusChanged", bpid, status + print("breakpointStatusChanged " + str(bpid) + " " + + str(status)) def contextAdded(self, bps): - print "breakpointAdded", bps + print("breakpointAdded " + str(bps)) bpsvc.removeListener(self) def contextChanged(self, bps): - print "breakpointChanged", bps + print("breakpointChanged " + str(bps)) def contextRemoved(self, ids): - print "breakpointRemoved", ids + print("breakpointRemoved " + str(ids)) bpsvc.addListener(BPListener()) def doneSet(token, error): @@ -280,7 +282,7 @@ def testStackTrace(c): return if ctxs: for ctx in ctxs: - print ctx + print(ctx) stack.getContext(ctx_ids, DoneGetContext()) stack.getChildren(ctx_id, DoneGetChildren()) for ctx_id in _suspended: @@ -303,11 +305,11 @@ def testDisassembly(c): if frameData: addr = frameData[0].get("IP") if addr: - print "Disassemble context %s from 0x%x" % (ctx_id, addr) + print("Disassemble context %s from 0x%x" % (ctx_id, addr)) lines = dis.disassemble(ctx_id, addr, 256, None).get() if lines: for line in lines: - print line + print(line) def testSymbols(c): @@ -328,7 +330,7 @@ def testSymbols(c): protocol.log( "Error from Symbols.getContext", error) return - print ctx + print(ctx) if ctx_ids: for ctx_id in ctx_ids: syms.getContext(ctx_id, DoneGetContext()) @@ -366,7 +368,7 @@ def testRegisters(c): protocol.log( "Error from Registers.getContext", error) else: - print ctx + print(ctx) if ctx.isReadable() and not ctx.isReadOnce() \ and ctx.getSize() >= 2: locs = [] @@ -383,8 +385,9 @@ def testRegisters(c): "Error from Registers.getm", error) else: - print "getm", \ - ctx.getID(), map(ord, value) + print("getm " + str(ctx.getID()) + + " " + + str(list(map(int, value)))) if not pending: onDone() pending.append(regs.getm(locs, DoneGetM())) @@ -429,7 +432,7 @@ def testExpressions(c): e = exprs.create(_suspended[0], None, "1+2*(3-4/2)").getE() eid = e.get(expressions.PROP_ID) val, cls = exprs.evaluate(eid).getE() - print e.get(expressions.PROP_EXPRESSION), "=", val + print(e.get(expressions.PROP_EXPRESSION) + " = " + str(val)) exprs.dispose(eid) @@ -445,10 +448,10 @@ def testLineNumbers(c): if bt: bt = stack.getContext(bt).get() for frame in bt: - addr = frame.get(stacktrace.PROP_INSTRUCTION_ADDRESS) + addr = frame.get(stacktrace.PROP_INSTRUCTION_ADDRESS) or 0 area = lineNumbers.mapToSource(ctx_id, addr, addr + 1).get() - print "Frame %d - CodeArea: %s" % ( - frame.get(stacktrace.PROP_LEVEL), area) + print("Frame %d - CodeArea: %s" % + (frame.get(stacktrace.PROP_LEVEL), area)) def testSyncCommands(c): @@ -468,16 +471,16 @@ def testSyncCommands(c): e = errors.ErrorReport("Test", errors.TCF_ERROR_OTHER) r = diag.echoERR(e.getAttributes()).getE() assert e.getAttributes() == r - print "Diagnostic tests:", diag.getTestList().getE() + print("Diagnostic tests: " + str(diag.getTestList().getE())) for ctx_id in _suspended: - print "Symbols:", ctl.Symbols.list(ctx_id) + print("Symbols: " + str(ctl.Symbols.list(ctx_id))) for ctx_id in _suspended: frame_ids = ctl.StackTrace.getChildren(ctx_id).get() if frame_ids: error, args = ctl.StackTrace.getContext(frame_ids) if not error: - print "Stack contexts:", args + print("Stack contexts: " + str(args)) try: ctl.Breakpoints except AttributeError: @@ -485,10 +488,10 @@ def testSyncCommands(c): return def gotBreakpoints(error, bps): - print "Got breakpoint list:", bps + print("Got breakpoint list: " + str(bps)) ctl.Breakpoints.getIDs(onDone=gotBreakpoints) try: - print ctl.Processes.getChildren(None, False) + print(ctl.Processes.getChildren(None, False)) except: pass # no Processes service @@ -516,7 +519,7 @@ def testTasks(c): es.create(_suspended[0], None, expr, doneCreate) t = task.Task(compute, "1+2*(3-4/2)", channel=c) val = t.get() - print "Task result:", val + print("Task result: " + str(val)) def testEvents(c): @@ -534,16 +537,16 @@ def testEvents(c): return ctx = ctxs[0] rc.resume(ctx, 0, 1, None).wait() - print recorder + print(recorder) rc.suspend(ctx).wait() - print recorder + print(recorder) recorder.stop() def testDataCache(c): from tcf.util import cache # @UnresolvedImport from tcf.services import runcontrol # @UnresolvedImport - if not runcontrol.NAME in _services: + if runcontrol.NAME not in _services: return class ContextsCache(cache.DataCache): @@ -572,7 +575,7 @@ def testDataCache(c): contextsCache = ContextsCache(c) def done(): - print "ContextsCache is valid:", contextsCache.getData() + print("ContextsCache is valid: " + str(contextsCache.getData())) protocol.invokeLater(contextsCache.validate, done) @@ -593,7 +596,7 @@ def testProcesses(c): if error: protocol.log("Error from Processes.GetChildren", error) else: - print "Processes:", context_ids + print("Processes: " + str(context_ids)) with lock: lock.notify() proc.getChildren(None, False, DoneGetChildren()) @@ -610,9 +613,9 @@ def testFileSystem(c): # no FileSystem service return roots = fs.roots().get() - print "FileSystem roots:", roots + print("FileSystem roots: " + str(roots)) user = fs.user().get() - print "User info: ", user + print("User info: " + str(user)) def testMemory(c): @@ -629,7 +632,7 @@ def testMemory(c): if error: protocol.log("Error from Memory.getContext", error) else: - print context + print(context) if len(pending) == 0: with lock: lock.notify() @@ -674,7 +677,7 @@ def testMemoryMap(c): if error: protocol.log("Error from MemoryMap.get", error) else: - print mmap + print(mmap) with lock: lock.notify() mm.get(map_id, DoneGet()) @@ -691,15 +694,13 @@ def testMemoryMap(c): protocol.log("Error from MemoryMap.set", error) with lock: lock.notify() - mm.set( - id, - {memorymap.PROP_FILE_NAME: "/tmp/system.elf"}, - DoneSet()) + mm.set(map_id, {memorymap.PROP_FILE_NAME: "/tmp/system.elf"}, + DoneSet()) with lock: protocol.invokeLater(setMap) lock.wait(1) - mmap = mm.get(id).get() - print "Memory map:", mmap + mmap = mm.get(map_id).get() + print("Memory map: " + str(mmap)) def testPathMap(c): @@ -720,7 +721,7 @@ def testPathMap(c): if error: protocol.log("Error from PathMap.get", error) else: - print mmap + print(mmap) with lock: lock.notify() pm.get(DoneGet()) @@ -743,7 +744,7 @@ def testPathMap(c): protocol.invokeLater(setMap) lock.wait(1) mmap = pm.get().get() - print "Path map:", mmap + print("Path map: " + str(mmap)) def testSysMonitor(c): @@ -788,14 +789,14 @@ def testSysMonitor(c): with lock: protocol.invokeLater(getProcesses) lock.wait(5) - print "%d processes found:" % len(processes) + print("%d processes found:" % len(processes)) for p in processes: - print p + print(p) cmdl = sm.getCommandLine(p.getID()).get() if cmdl: - print "Command line: ", cmdl + print("Command line: " + str(cmdl)) envp = sm.getEnvironment(p.getID()).get() - print "Environment: ", envp + print("Environment: " + str(envp)) if __name__ == '__main__': test() diff --git a/python/src/tcf/tests/ProcessStart.py b/python/src/tcf/tests/ProcessStart.py index 88f7d64a2..511ee9a17 100644 --- a/python/src/tcf/tests/ProcessStart.py +++ b/python/src/tcf/tests/ProcessStart.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -43,6 +43,7 @@ class TcfProtocolLogger (object): """Sometimes we get some protocol warnings. I would like to remove them by flushing the log cache here. """ + pass class TcfValue(object): @@ -122,7 +123,11 @@ class StreamsListener(streams.StreamsListener): :param eos: true if end of stream was reached. """ if data: - print data, + if isinstance(data, bytearray): + s = data.decode('utf-8') + else: + s = str(data) + sys.stdout.write(s) if not eos: self._service.read(self._streamID, self._size, self) @@ -216,7 +221,7 @@ def getChildren(service, contextID=None): :param context_ids: array of available context IDs. """ if error: - protocol.log("Error from " + service.getName() + \ + protocol.log("Error from " + service.getName() + ".getContext()", error) else: val.setValue(ids) @@ -267,7 +272,8 @@ def getContext(service, contextID): rcIDs = getChildren(rcSvc, None) rcContext = getContext(rcSvc, rcIDs[0]) - print 'Runcontrol context is a container: ', rcContext.isContainer() + print('Runcontrol context is a container: ' + + str(rcContext.isContainer())) :param service: The TCF service to get context from. :param contextID: ID of the context to get from *service* @@ -296,7 +302,7 @@ def getContext(service, contextID): :param context: context data. """ if error: - protocol.log("Error from " + service.getName() + \ + protocol.log("Error from " + service.getName() + ".getContext()", error) else: val.setValue(context) @@ -397,11 +403,11 @@ def start(connection, path, *args): # get connection's processes service proc = connection.getRemoteService(processes_v1.NAME) or \ - connection.getRemoteService(processes.NAME) + connection.getRemoteService(processes.NAME) if not proc: with condition: - print 'No processes service available' + print('No processes service available') condition.notify() return @@ -616,11 +622,11 @@ p = start(c, '/bin/ls', '-l', '-a') rcSvc = getService(c, runcontrol.NAME) if rcSvc is None: - print 'No runcontrol service. Exiting ...' + print('No runcontrol service. Exiting ...') sys.exit() context = getContext(rcSvc, p.getID()) -print 'Runcontrol context is a container:', context.isContainer() +print('Runcontrol context is a container: ' + str(context.isContainer())) while context and not context.hasState(): children = getChildren(rcSvc, context.getID()) @@ -630,14 +636,14 @@ while context and not context.hasState(): break if context is None: - print 'No runcontrol context to resume. Exiting ...' + print('No runcontrol context to resume. Exiting ...') sys.exit() # get the state of this context. State is a tuple of # (suspended, pc, reason, params) ctxState = state(context) -print 'Context state : ' + str(ctxState) +print('Context state : ' + str(ctxState)) while ctxState and ctxState[0]: resume(context) @@ -646,7 +652,7 @@ while ctxState and ctxState[0]: try: ctxState = state(context) if ctxState: - print 'Context state : ' + str(ctxState) + print('Context state : ' + str(ctxState)) except: pass diff --git a/python/src/tcf/transport.py b/python/src/tcf/transport.py index f46df217a..e2bada707 100644 --- a/python/src/tcf/transport.py +++ b/python/src/tcf/transport.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -11,7 +11,7 @@ import threading -from . import protocol, channel +from . import protocol, channel from .services import locator _channels = [] @@ -125,7 +125,7 @@ class TCPTransportProvider(TransportProvider): port = attrs.get(peer.ATTR_IP_PORT) if not host: raise RuntimeError("No host name") - from channel.ChannelTCP import ChannelTCP + from .channel.ChannelTCP import ChannelTCP return ChannelTCP(p, host, _parsePort(port)) @@ -135,8 +135,8 @@ def _parsePort(port): try: return int(port) except Exception: - raise RuntimeError( - "Invalid value of \"Port\" attribute. Must be decimal number.") + raise RuntimeError("Invalid value of \"Port\" attribute. Must be " + + "decimal number.") def sendEvent(service_name, event_name, data): diff --git a/python/src/tcf/util/cache.py b/python/src/tcf/util/cache.py index 23df4cd22..f8b9bbf5e 100644 --- a/python/src/tcf/util/cache.py +++ b/python/src/tcf/util/cache.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013-2014, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -9,7 +9,6 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -import cStringIO from .. import protocol, channel from .task import Task @@ -263,7 +262,7 @@ class DataCache(object): if not self.__disposed: self.__data = data self.__error = None - self.__valid = True + self.__valid = data is not None self.post() def cancel(self): @@ -286,20 +285,19 @@ class DataCache(object): self.__disposed = True def __str__(self): - bf = cStringIO.StringIO() - bf.write('[') + res = '[' if self.__valid: - bf.append("valid,") + res += 'valid,' if self.__disposed: - bf.write("disposed,") + res += 'disposed,' if self.__posted: - bf.write("posted,") + res += 'posted,' if self.__error is not None: - bf.write("error,") - bf.write("data=") - bf.write(str(self.__data)) - bf.write(']') - return bf.getvalue() + res += 'error,' + res += 'data=' + res += str(self.__data) + res += ']' + return res def startDataRetrieval(self): """ diff --git a/python/src/tcf/util/event.py b/python/src/tcf/util/event.py index 4c552db29..4f77fb10a 100644 --- a/python/src/tcf/util/event.py +++ b/python/src/tcf/util/event.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -27,7 +27,7 @@ class DelegatingEventListener(channel.EventListener): def _print_event(service, name, *args): - print "Event: %s.%s%s" % (service, name, tuple(args)) + print("Event: %s.%s%s" % (service, name, tuple(args))) def get_event_printer(): @@ -70,7 +70,7 @@ class EventRecorder(object): if service: self.record(service, False) else: - for service in self._listeners.keys(): + for service in list(self._listeners.keys()): self.record(service, False) def get(self): diff --git a/python/src/tcf/util/logging.py b/python/src/tcf/util/logging.py index 889ff3dd7..132daa931 100644 --- a/python/src/tcf/util/logging.py +++ b/python/src/tcf/util/logging.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -11,7 +11,6 @@ "Internal utility methods used for logging/tracing." -import cStringIO import locale import time @@ -30,24 +29,24 @@ def getDebugTime(): the relative time between two events, since the counter will flip to zero roughly every 16 minutes. """ - traceBuilder = cStringIO.StringIO() + traceBuilder = '' # Record the time tm = int(time.time() * 1000) - seconds = (tm / 1000) % 1000 + seconds = int((tm / 1000)) % 1000 if seconds < 100: - traceBuilder.write('0') + traceBuilder += '0' if seconds < 10: - traceBuilder.write('0') - traceBuilder.write(str(seconds)) - traceBuilder.write(DECIMAL_DELIMITER) + traceBuilder += '0' + traceBuilder += str(seconds) + traceBuilder += str(DECIMAL_DELIMITER) millis = tm % 1000 if millis < 100: - traceBuilder.write('0') + traceBuilder += '0' if millis < 10: - traceBuilder.write('0') - traceBuilder.write(str(millis)) - return traceBuilder.getvalue() + traceBuilder += '0' + traceBuilder += str(millis) + return traceBuilder def trace(msg): diff --git a/python/src/tcf/util/sync.py b/python/src/tcf/util/sync.py index 2114febe0..e604cd2e0 100644 --- a/python/src/tcf/util/sync.py +++ b/python/src/tcf/util/sync.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at @@ -67,8 +67,8 @@ class CommandControl(object): return services if attr in services: return ServiceWrapper(self, attr) - raise AttributeError("Unknown service: %s. Use one of %s" % ( - attr, services)) + raise AttributeError("Unknown service: %s. Use one of %s" % + (attr, services)) def invoke(self, service, command, *args, **kwargs): cmd = None @@ -91,8 +91,10 @@ class CommandControl(object): class GenericCommand(Command): _result = None + def done(self, error, args): # @IgnorePep8 resultArgs = None + rcmds = ('read', 'readdir', 'roots') if not error and args: # error result is usually in args[0], # but there are exceptions @@ -102,16 +104,15 @@ class CommandControl(object): elif service == "Expressions" and command == "evaluate": error = self.toError(args[1]) resultArgs = (args[0], args[2]) - elif service == "FileSystem" and command in ( - 'read', 'readdir', 'roots'): + elif service == "FileSystem" and command in rcmds: error = self.toError(args[1]) resultArgs = (args[0],) + tuple(args[2:]) elif service == "Streams" and command == 'read': error = self.toError(args[1]) resultArgs = (args[0],) + tuple(args[2:]) - elif service == "Diagnostics" and \ - command.startswith("echo"): - resultArgs = (args[0],) + elif service == "Diagnostics": + if command.startswith("echo"): + resultArgs = (args[0],) else: error = self.toError(args[0]) resultArgs = args[1:] @@ -218,7 +219,7 @@ class CommandControl(object): protocol.invokeLater(self.cancel) return with self._lock: - for cmd in self._pending.values(): + for cmd in list(self._pending.values()): cmd.token.cancel() del self._queue[:] @@ -226,7 +227,7 @@ class CommandControl(object): if wait: self.wait() with self._lock: - result = map(lambda c: c.getResult(), self._complete) + result = [c.getResult() for c in self._complete] del self._complete[:] return result @@ -267,5 +268,5 @@ class CommandWrapper(object): self._command = command def __call__(self, *args, **kwargs): - return self._control.invoke( - self._service, self._command, *args, **kwargs) + return self._control.invoke(self._service, self._command, *args, + **kwargs) diff --git a/python/src/tcf/util/task.py b/python/src/tcf/util/task.py index cdca94eb7..3864cef16 100644 --- a/python/src/tcf/util/task.py +++ b/python/src/tcf/util/task.py @@ -1,5 +1,5 @@ -#****************************************************************************** -# Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. +# ***************************************************************************** +# Copyright (c) 2011, 2013, 2016 Wind River Systems, Inc. and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at @@ -7,7 +7,7 @@ # # Contributors: # Wind River Systems - initial API and implementation -#****************************************************************************** +# ***************************************************************************** import threading from .. import protocol, channel |