def getChildren(service, contextID=None): """Get a TCF context IDs from a given service. As many TCF services have a **getChildren()** command, this function is intended to implement a service-independant **getChildren()** command. :param service: The TCF service to get context list from. :param contextID: parent ID of the context list to get from *service*. :returns: A tuple of context IDs. Tuple may be empty on error, or if *contextID* does not have children. """ def callGetChildren(service, condition, val): """Asynchronous request to get context children. :param service: The TCF service proxy to send request to. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :param val: A TcfValue handling the request returned value. :returns: **None**, always. """ class DoneGetChildren(object): """Client callback class for <service>.getChildren() command.""" def doneGetChildren(self, token, error, ids): """Called when context list retrieval is done. :param token: pending command handle. :param error: error description if operation failed, **None** if succeeded. :param context_ids: array of available context IDs. """ if error: protocol.log("Error from " + service.getName() + \ ".getContext()", error) else: val.setValue(ids) with condition: condition.notify() # start the process itself service.getChildren(contextID, DoneGetChildren()) # create a condition to wait on, and a value to get the children ids lock = threading.Condition() value = TcfValue() with lock: # TCF requests must be called by the dispatch thread, wait for a # maximum of 10 seconds protocol.invokeLater(callGetChildren, service=service, condition=lock, val=value) lock.wait(10) # Return the retrieved children IDs, or an empty tuple return (tuple(value.getValue() or []))
def testProcesses(c): from tcf.services import processes, processes_v1 # @UnresolvedImport lock = threading.Condition() def processTest(): proc = c.getRemoteService(processes_v1.NAME) or \ c.getRemoteService(processes.NAME) if not proc: with lock: lock.notify() return class DoneGetChildren(processes.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): if error: protocol.log("Error from Processes.GetChildren", error) else: print("Processes: " + str(context_ids)) with lock: lock.notify() proc.getChildren(None, False, DoneGetChildren()) with lock: protocol.invokeLater(processTest) lock.wait(5)
def testMemory(c): lock = threading.Condition() from tcf.services import memory def getContexts(): mem = c.getRemoteService(memory.NAME) pending = [] class DoneGetContext(memory.DoneGetContext): def doneGetContext(self, token, error, context): pending.remove(token) if error: protocol.log("Error from Memory.getContext", error) else: print context if len(pending) == 0: with lock: lock.notify() class DoneGetChildren(memory.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log("Error from Memory.GetChildren", error) else: for c in context_ids: _memory.append(c) pending.append(mem.getContext(c, DoneGetContext())) pending.append(mem.getChildren(c, self)) if len(pending) == 0: with lock: lock.notify() pending.append(mem.getChildren(None, DoneGetChildren())) with lock: protocol.invokeLater(getContexts) lock.wait(5)
def testStackTrace(c): from tcf.services import stacktrace # @UnresolvedImport def stackTest(ctx_id): stack = c.getRemoteService(stacktrace.NAME) class DoneGetChildren(stacktrace.DoneGetChildren): def doneGetChildren(self, token, error, ctx_ids): if error: protocol.log("Error from StackTrace.getChildren", error) return class DoneGetContext(stacktrace.DoneGetContext): def doneGetContext(self, token, error, ctxs): if error: protocol.log("Error from StackTrace.getContext", error) return if ctxs: for ctx in ctxs: print(ctx) stack.getContext(ctx_ids, DoneGetContext()) stack.getChildren(ctx_id, DoneGetChildren()) for ctx_id in _suspended: protocol.invokeLater(stackTest, ctx_id)
def testSymbols(c): from tcf.services import symbols # @UnresolvedImport def symTest(ctx_id): syms = c.getRemoteService(symbols.NAME) class DoneList(symbols.DoneList): def doneList(self, token, error, ctx_ids): if error: protocol.log("Error from Symbols.list", error) return class DoneGetContext(symbols.DoneGetContext): def doneGetContext(self, token, error, ctx): if error: protocol.log("Error from Symbols.getContext", error) return print(ctx) if ctx_ids: for ctx_id in ctx_ids: syms.getContext(ctx_id, DoneGetContext()) syms.list(ctx_id, DoneList()) for ctx_id in _suspended: protocol.invokeLater(symTest, ctx_id)
def testStackTrace(c): from tcf.services import stacktrace def stackTest(ctx_id): stack = c.getRemoteService(stacktrace.NAME) class DoneGetChildren(stacktrace.DoneGetChildren): def doneGetChildren(self, token, error, ctx_ids): if error: protocol.log("Error from StackTrace.getChildren", error) return class DoneGetContext(stacktrace.DoneGetContext): def doneGetContext(self, token, error, ctxs): if error: protocol.log( "Error from StackTrace.getContext", error) return if ctxs: for ctx in ctxs: print ctx stack.getContext(ctx_ids, DoneGetContext()) stack.getChildren(ctx_id, DoneGetChildren()) for ctx_id in _suspended: protocol.invokeLater(stackTest, ctx_id)
def testSymbols(c): from tcf.services import symbols def symTest(ctx_id): syms = c.getRemoteService(symbols.NAME) class DoneList(symbols.DoneList): def doneList(self, token, error, ctx_ids): if error: protocol.log("Error from Symbols.list", error) return class DoneGetContext(symbols.DoneGetContext): def doneGetContext(self, token, error, ctx): if error: protocol.log( "Error from Symbols.getContext", error) return print ctx if ctx_ids: for ctx_id in ctx_ids: syms.getContext(ctx_id, DoneGetContext()) syms.list(ctx_id, DoneList()) for ctx_id in _suspended: protocol.invokeLater(symTest, ctx_id)
def testDataCache(c): from tcf.util import cache from tcf.services import runcontrol if not runcontrol.NAME in _services: return class ContextsCache(cache.DataCache): def startDataRetrieval(self): rc = self._channel.getRemoteService(runcontrol.NAME) if not rc: self.set(None, Exception("No RunControl service"), None) return cache = self pending = [] contexts = [] class DoneGetChildren(runcontrol.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log( "Error from RunControl.GetChildren", error) else: for c in context_ids: contexts.append(c) pending.append(rc.getChildren(c, self)) if len(pending) == 0: cache.set(None, None, contexts) pending.append(rc.getChildren(None, DoneGetChildren())) contextsCache = ContextsCache(c) def done(): print "ContextsCache is valid:", contextsCache.getData() protocol.invokeLater(contextsCache.validate, done)
def testRegisters(c): if not _suspended: return from tcf.services import registers lock = threading.Condition() def regTest(ctx_id): regs = c.getRemoteService(registers.NAME) pending = [] def onDone(): with lock: lock.notify() class DoneGetChildren(registers.DoneGetChildren): def doneGetChildren(self, token, error, ctx_ids): pending.remove(token) if error: protocol.log("Error from Registers.getChildren", error) if not pending: onDone() class DoneGetContext(registers.DoneGetContext): def doneGetContext(self, token, error, ctx): pending.remove(token) if error: protocol.log("Error from Registers.getContext", error) else: print ctx if ctx.isReadable() and not ctx.isReadOnce() and ctx.getSize() >= 2: locs = [] locs.append(registers.Location(ctx.getID(), 0, 1)) locs.append(registers.Location(ctx.getID(), 1, 1)) class DoneGetM(registers.DoneGet): def doneGet(self, token, error, value): pending.remove(token) if error: protocol.log("Error from Registers.getm", error) else: print "getm", ctx.getID(), map(ord, value) if not pending: onDone() pending.append(regs.getm(locs, DoneGetM())) if ctx.isWriteable() and not ctx.isWriteOnce() and ctx.getSize() >= 2: locs = [] locs.append(registers.Location(ctx.getID(), 0, 1)) locs.append(registers.Location(ctx.getID(), 1, 1)) class DoneSetM(registers.DoneSet): def doneGet(self, token, error): pending.remove(token) if error: protocol.log("Error from Registers.setm", error) if not pending: onDone() pending.append(regs.setm(locs, (255, 255), DoneSetM())) if not pending: onDone() if ctx_ids: for ctx_id in ctx_ids: pending.append(regs.getContext(ctx_id, DoneGetContext())) pending.append(regs.getChildren(ctx_id, DoneGetChildren())) with lock: for ctx_id in _suspended: protocol.invokeLater(regTest, ctx_id) lock.wait(5)
def testBreakpoints(c): from tcf.services import breakpoints # @UnresolvedImport def testBPQuery(): bps = c.getRemoteService(breakpoints.NAME) def doneGetIDs(token, error, ids): if error: protocol.log("Error from Breakpoints.getIDs", error) return print("Breakpoints : " + str(ids)) def doneGetProperties(token, error, props): if error: protocol.log("Error from Breakpoints.getProperties", error) return print("Breakpoint Properties: " + str(props)) def doneGetStatus(token, error, props): if error: protocol.log("Error from Breakpoints.getStatus", error) return print("Breakpoint Status: " + str(props)) for bpid in ids: bps.getProperties(bpid, doneGetProperties) bps.getStatus(bpid, doneGetStatus) bps.getIDs(doneGetIDs) protocol.invokeLater(testBPQuery) def testBPSet(): bpsvc = c.getRemoteService(breakpoints.NAME) class BPListener(breakpoints.BreakpointsListener): def breakpointStatusChanged(self, bpid, status): print("breakpointStatusChanged " + str(bpid) + " " + str(status)) def contextAdded(self, bps): print("breakpointAdded " + str(bps)) bpsvc.removeListener(self) def contextChanged(self, bps): print("breakpointChanged " + str(bps)) def contextRemoved(self, ids): print("breakpointRemoved " + str(ids)) bpsvc.addListener(BPListener()) def doneSet(token, error): if error: protocol.log("Error from Breakpoints.set", error) return bp = { breakpoints.PROP_ID: "python:1", breakpoints.PROP_ENABLED: True, breakpoints.PROP_LOCATION: "sysClkRateGet" } bpsvc.set([bp], doneSet) protocol.invokeLater(testBPSet)
def cancel(self): if not protocol.isDispatchThread(): protocol.invokeLater(self.cancel) return with self._lock: for cmd in self._pending.values(): cmd.token.cancel() del self._queue[:]
def subscribe(svc, streamType, listener): """Subscribe to a streams channel. :param svc: The TCF streams proxy to subscribe against. :param streamType: Type of the stream to register against. For now, I only know of 'Terminals', 'Processes' and 'ProcessesV1' types. :param listener: The listener to subscribe to *svc*. :type listener: tcf.services.streams.StreamsListener :returns: **None**, always. """ def callSubscribe(service, streamType, listener, condition): """Asynchronous request to subscribe a listener to streams service. :param service: The streams service to subscribe listener against. :param streamType: Type of the stream to register against. For now, I only know of 'Terminals', 'Processes' and 'ProcessesV1' types. :param listener: The listener to subscribe to *service*. :type listener: tcf.services.streams.StreamsListener :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :returns: **None**, always. """ class DoneSubscribe(streams.DoneSubscribe): """Call back interface for StreamsService.subscribe() command.""" def doneSubscribe(self, token, error): """Called when stream subscription is done. :param token: pending command handle :param error: error description if operation failed, **None** if succeeded. """ if error: protocol.log("Error from streams.subscribe()", error) with condition: condition.notify() # start the process itself service.subscribe(streamType, listener, DoneSubscribe()) # create a condition to wait on lock = threading.Condition() with lock: # TCF requests must be called by the dispatche thread, wait for a # maximum of 10 seconds protocol.invokeLater(callSubscribe, service=svc, streamType=streamType, listener=listener, condition=lock) lock.wait(10)
def testSysMonitor(c): cmd = sync.CommandControl(c) try: sm = cmd.SysMonitor except AttributeError: # no SysMonotor service return lock = threading.Condition() from tcf.services import sysmonitor # @UnresolvedImport processes = [] def getProcesses(): sm = c.getRemoteService(sysmonitor.NAME) pending = [] class DoneGetChildren(sysmonitor.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log("Error from SysMonitor.getChildren", error) else: class DoneGetContext(sysmonitor.DoneGetContext): def doneGetContext(self, token, error, context): pending.remove(token) if error: protocol.log( "Error from SysMonitor.getContext", error) else: processes.append(context) if not pending: with lock: lock.notify() for ctx_id in context_ids: pending.append(sm.getContext(ctx_id, DoneGetContext())) if not pending: with lock: lock.notify() pending.append(sm.getChildren(None, DoneGetChildren())) with lock: protocol.invokeLater(getProcesses) lock.wait(5) print("%d processes found:" % len(processes)) for p in processes: print(p) cmdl = sm.getCommandLine(p.getID()).get() if cmdl: print("Command line: " + str(cmdl)) envp = sm.getEnvironment(p.getID()).get() print("Environment: " + str(envp))
def _close(self, error): assert self.state != STATE_CLOSED self.state = STATE_CLOSED # Closing channel underlying streams can block for a long time, # so it needs to be done by a background thread. thread = threading.Thread(target=self.stop, name="TCF Channel Cleanup") thread.daemon = True thread.start() if error and isinstance(self.remote_peer, peer.AbstractPeer): self.remote_peer.onChannelTerminated() if self.registered_with_trasport: self.registered_with_trasport = False transport.channelClosed(self, error) if self.proxy: try: self.proxy.onChannelClosed(error) except Exception as x: protocol.log("Exception in channel listener", x) channel = self class Runnable(object): def __call__(self): if channel.out_tokens: x = None if isinstance(error, Exception): x = error elif error: x = Exception(error) else: x = IOError("Channel is closed") for msg in channel.out_tokens.values(): try: s = str(msg) if len(s) > 72: s = s[:72] + "...]" y = IOError("Command " + s + " aborted") # y.initCause(x) msg.token.getListener().terminated(msg.token, y) except Exception as e: protocol.log("Exception in command listener", e) channel.out_tokens.clear() if channel.channel_listeners: for l in channel.channel_listeners: if not l: break try: l.onChannelClosed(error) except Exception as x: protocol.log("Exception in channel listener", x) elif error: protocol.log("TCF channel terminated", error) if channel.trace_listeners: for l in channel.trace_listeners: try: l.onChannelClosed(error) except Exception as x: protocol.log("Exception in channel listener", x) protocol.invokeLater(Runnable())
def invoke(self, service, command, *args, **kwargs): cmd = None if not protocol.isDispatchThread(): if not kwargs.get("async"): cmd = protocol.invokeAndWait(self._invoke, service, command, *args, **kwargs) if cmd and self._interactive: return cmd.getE() else: with self._lock: self._queue.append((service, command, args, kwargs)) if len(self._queue) == 1: protocol.invokeLater(self._processQueue) return return cmd
def testProcesses(c): from tcf.services import processes, processes_v1 def processTest(): proc = c.getRemoteService(processes_v1.NAME) or c.getRemoteService(processes.NAME) if not proc: return class DoneGetChildren(processes.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): if error: protocol.log("Error from Processes.GetChildren", error) else: print "Processes:", context_ids proc.getChildren(None, False, DoneGetChildren()) protocol.invokeLater(processTest)
def testSysMonitor(c): cmd = sync.CommandControl(c) try: sm = cmd.SysMonitor except AttributeError: # no SysMonotor service return lock = threading.Condition() from tcf.services import sysmonitor processes = [] def getProcesses(): sm = c.getRemoteService(sysmonitor.NAME) pending = [] class DoneGetChildren(sysmonitor.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log("Error from SysMonitor.getChildren", error) else: class DoneGetContext(sysmonitor.DoneGetContext): def doneGetContext(self, token, error, context): pending.remove(token) if error: protocol.log( "Error from SysMonitor.getContext", error) else: processes.append(context) if not pending: with lock: lock.notify() for ctx_id in context_ids: pending.append( sm.getContext(ctx_id, DoneGetContext())) if not pending: with lock: lock.notify() pending.append(sm.getChildren(None, DoneGetChildren())) with lock: protocol.invokeLater(getProcesses) lock.wait(5) print "%d processes found:" % len(processes) for p in processes: print p cmdl = sm.getCommandLine(p.getID()).get() if cmdl: print "Command line: ", cmdl envp = sm.getEnvironment(p.getID()).get() print "Environment: ", envp
def testMemoryMap(c): if not _memory: return cmd = sync.CommandControl(c) try: mm = cmd.MemoryMap except AttributeError: # no MemoryMap service return map_id = _memory[0] lock = threading.Condition() from tcf.services import memorymap # @UnresolvedImport def getMap(): mm = c.getRemoteService(memorymap.NAME) class DoneGet(memorymap.DoneGet): def doneGet(self, token, error, mmap): if error: protocol.log("Error from MemoryMap.get", error) else: print(mmap) with lock: lock.notify() mm.get(map_id, DoneGet()) with lock: protocol.invokeLater(getMap) lock.wait(1) def setMap(): mm = c.getRemoteService(memorymap.NAME) class DoneSet(memorymap.DoneSet): def doneSet(self, token, error): if error: protocol.log("Error from MemoryMap.set", error) with lock: lock.notify() mm.set(map_id, {memorymap.PROP_FILE_NAME: "/tmp/system.elf"}, DoneSet()) with lock: protocol.invokeLater(setMap) lock.wait(1) mmap = mm.get(map_id).get() print("Memory map: " + str(mmap))
def __init__(self, channel, service, command, args): if isinstance(service, services.Service): service = service.getName() self.service = service self.command = command self.args = args t = None try: # TODO zero_copy #zero_copy = channel.isZeroCopySupported() t = channel.sendCommand(service, command, toJSONSequence(args), self) except Exception as y: t = Token() protocol.invokeLater(self._error, y) self.token = t
def testPathMap(c): cmd = sync.CommandControl(c) try: pm = cmd.PathMap except AttributeError: # no PathMap service return lock = threading.Condition() from tcf.services import pathmap # @UnresolvedImport def getMap(): pm = c.getRemoteService(pathmap.NAME) class DoneGet(pathmap.DoneGet): def doneGet(self, token, error, mmap): if error: protocol.log("Error from PathMap.get", error) else: print(mmap) with lock: lock.notify() pm.get(DoneGet()) with lock: protocol.invokeLater(getMap) lock.wait(1) def setMap(): pm = c.getRemoteService(pathmap.NAME) class DoneSet(pathmap.DoneSet): def doneSet(self, token, error): if error: protocol.log("Error from PathMap.set", error) with lock: lock.notify() pm.set({ pathmap.PROP_SOURCE: "/tmp", pathmap.PROP_DESTINATION: "/home" }, DoneSet()) with lock: protocol.invokeLater(setMap) lock.wait(1) mmap = pm.get().get() print("Path map: " + str(mmap))
def resume(context): """Resume a runcontrol context. The given *context* should be a RunControlContext, so that its resume() method may be called. :param context: A runcontrol context to resume. :type process: RunControlContext :returns: **None**, always. """ def callResume(context, condition): """Asynchronous request to resume runcontrol context. :param context: The TCF RunControlContext to resume. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :returns: **None**, always. """ class DoneResume(runcontrol.DoneCommand): """Client call back interface for RunControlContext.resume().""" def doneCommand(self, token, error): """Called when run control command execution is complete. :param token: pending command handle. :param error: command execution error or **None**. """ if error: protocol.log("Error from RunContext.resume", error) with condition: condition.notify() # Resume context with RM_RESUME mode, 1 time. No resume properties. context.resume(runcontrol.RM_RESUME, 1, {}, DoneResume()) # create a condition to wait on lock = threading.Condition() with lock: # TCF requests must be called by the dispatch thread, wait for a # maximum of 10 seconds protocol.invokeLater(callResume, context=context, condition=lock) lock.wait(10)
def record(self, service, enable=True): with self._lock: listener = self._listeners.get(service) if listener: if not enable: protocol.invokeLater(self._channel.removeEventListener, service, listener) elif enable: recorder = self class Listener(channel.EventListener): def event(self, name, data): e = Event(service, name, data) recorder._event(e) listener = Listener() self._listeners[service] = listener protocol.invokeLater(self._channel.addEventListener, service, listener) self._recording = enable
def interact(self, banner=None): try: try: ps1 = sys.ps1 # @UndefinedVariable except AttributeError: ps1 = None sys.ps1 = "tcf> " super(Shell, self).interact(banner) finally: if ps1: sys.ps1 = ps1 else: del sys.ps1 protocol.invokeLater(protocol.removeChannelOpenListener, self) protocol.shutdownDiscovery() protocol.getEventQueue().shutdown()
def testMemoryMap(c): if not _memory: return cmd = sync.CommandControl(c) try: mm = cmd.MemoryMap except AttributeError: # no MemoryMap service return map_id = _memory[0] lock = threading.Condition() from tcf.services import memorymap def getMap(): mm = c.getRemoteService(memorymap.NAME) class DoneGet(memorymap.DoneGet): def doneGet(self, token, error, mmap): if error: protocol.log("Error from MemoryMap.get", error) else: print mmap with lock: lock.notify() mm.get(map_id, DoneGet()) with lock: protocol.invokeLater(getMap) lock.wait(1) def setMap(): mm = c.getRemoteService(memorymap.NAME) class DoneSet(memorymap.DoneSet): def doneSet(self, token, error): if error: protocol.log("Error from MemoryMap.set", error) with lock: lock.notify() mm.set( 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
def __write_output(self): try: while True: msg = None last = False with self.out_lock: while len(self.out_queue) == 0: self.out_lock.wait() msg = self.out_queue.pop(0) if not msg: break last = len(self.out_queue) == 0 if msg.is_canceled: if last: self.flush() continue msg.is_sent = True if msg.trace: protocol.invokeLater(self.__traceMessageSent, msg) self.write(msg.type) self.write(0) if msg.token: self.write(msg.token.id) self.write(0) if msg.service: self.write(msg.service.encode("UTF8")) self.write(0) if msg.name: self.write(msg.name.encode("UTF8")) self.write(0) if msg.data: self.write(msg.data) self.write(EOM) delay = 0 level = self.remote_congestion_level if level > 0: delay = level * 10 if last or delay > 0: self.flush() if delay > 0: time.sleep(delay / 1000.0) #else yield() self.write(EOS) self.write(EOM) self.flush() except Exception as x: try: protocol.invokeLater(self.terminate, x) except: # TCF event dispatcher has shut down pass
def __init__(self, target=None, *args, **kwargs): """ Construct a TCF task object and schedule it for execution. """ if target: kwargs["done"] = self.__done else: target = self.run self._target = target self._args = args self._kwargs = kwargs self._lock = threading.Condition() self.__channel = kwargs.pop("channel", None) protocol.invokeLater(self.__doRun) timeout = kwargs.pop("timeout", None) if timeout: protocol.invokeLaterWithDelay(timeout, self.cancel)
def getService(connection, name): """Get a service proxy. The service proxy named *name* is retrieved from *connection*. If it exists (returned value is not **None**), it is then possible to send it TCF requests. :param connection: The connection to get service proxy from. :param name: The name of the service proxy to get from *connection*. :returns: A service proxy or **None**. """ def callGetService(connection, condition, val): """Asynchronous request to get service proxy. :param connection: The connection to get service proxy from. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :param val: A TcfValue handling the request returned value. :returns: **None**, always. """ svc = connection.getRemoteService(name) val.setValue(svc) with condition: condition.notify() # create a condition to wait on, and a value to get the service proxy lock = threading.Condition() value = TcfValue() with lock: # Asynchronously call for the callGetService function. protocol.invokeLater(callGetService, connection=connection, condition=lock, val=value) lock.wait(5) # Return TCF service proxy. May be None on timeout or missing service. return (value.getValue())
def test(): global _services protocol.startEventQueue() atexit.register(protocol.getEventQueue().shutdown) # testTimer() try: c = tcf.connect("TCP:127.0.0.1:1534") except Exception as e: protocol.log(e) sys.exit() assert c.state == channel.STATE_OPEN if __TRACE: protocol.invokeAndWait(c.addTraceListener, TraceListener()) _services = sorted(protocol.invokeAndWait(c.getRemoteServices)) print("services=" + str(_services)) if "RunControl" in _services: # RunControl must be first _services.remove("RunControl") _services.insert(0, "RunControl") for service in _services: testFct = globals().get("test" + service) if testFct: print("Testing service '%s'..." % service) try: testFct(c) 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) try: testSyncCommands(c) testTasks(c) testEvents(c) testDataCache(c) except Exception as e: protocol.log(e) if c.state == channel.STATE_OPEN: time.sleep(5) protocol.invokeLater(c.close) time.sleep(2)
def test(): global _services protocol.startEventQueue() atexit.register(protocol.getEventQueue().shutdown) # testTimer() try: c = tcf.connect("TCP:127.0.0.1:1534") except Exception as e: protocol.log(e) sys.exit() assert c.state == channel.STATE_OPEN if __TRACE: protocol.invokeAndWait(c.addTraceListener, TraceListener()) _services = protocol.invokeAndWait(c.getRemoteServices) print "services=", _services if "RunControl" in _services: # RunControl must be first _services.remove("RunControl") _services.insert(0, "RunControl") for service in _services: testFct = globals().get("test" + service) if testFct: print "Testing service '%s'..." % service try: testFct(c) 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 try: testSyncCommands(c) testTasks(c) testEvents(c) testDataCache(c) except Exception as e: protocol.log(e) if c.state == channel.STATE_OPEN: time.sleep(5) protocol.invokeLater(c.close) time.sleep(2)
def __init__(self, remote_peer, host, port): super(ChannelTCP, self).__init__(remote_peer) self.closed = False self.started = False channel = self class CreateSocket(object): def __call__(self): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) channel.socket = sock channel._onSocketConnected(None) except Exception as x: channel._onSocketConnected(x) protocol.invokeLater(CreateSocket())
def testPathMap(c): cmd = sync.CommandControl(c) try: pm = cmd.PathMap except AttributeError: # no PathMap service return lock = threading.Condition() from tcf.services import pathmap def getMap(): pm = c.getRemoteService(pathmap.NAME) class DoneGet(pathmap.DoneGet): def doneGet(self, token, error, mmap): if error: protocol.log("Error from PathMap.get", error) else: print mmap with lock: lock.notify() pm.get(DoneGet()) with lock: protocol.invokeLater(getMap) lock.wait(1) def setMap(): pm = c.getRemoteService(pathmap.NAME) class DoneSet(pathmap.DoneSet): def doneSet(self, token, error): if error: protocol.log("Error from PathMap.set", error) with lock: lock.notify() pm.set({pathmap.PROP_SOURCE: "/tmp", pathmap.PROP_DESTINATION: "/home"}, DoneSet()) with lock: protocol.invokeLater(setMap) lock.wait(1) mmap = pm.get().get() print "Path map:", mmap
def testMemory(c): lock = threading.Condition() from tcf.services import memory # @UnresolvedImport def getContexts(): mem = c.getRemoteService(memory.NAME) pending = [] class DoneGetContext(memory.DoneGetContext): def doneGetContext(self, token, error, context): pending.remove(token) if error: protocol.log("Error from Memory.getContext", error) else: print(context) if len(pending) == 0: with lock: lock.notify() class DoneGetChildren(memory.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log("Error from Memory.GetChildren", error) else: for c in context_ids: _memory.append(c) pending.append(mem.getContext(c, DoneGetContext())) pending.append(mem.getChildren(c, self)) if len(pending) == 0: with lock: lock.notify() pending.append(mem.getChildren(None, DoneGetChildren())) with lock: protocol.invokeLater(getContexts) lock.wait(5)
def testDataCache(c): from tcf.util import cache # @UnresolvedImport from tcf.services import runcontrol # @UnresolvedImport if runcontrol.NAME not in _services: return class ContextsCache(cache.DataCache): def startDataRetrieval(self): rc = self._channel.getRemoteService(runcontrol.NAME) if not rc: self.set(None, Exception("No RunControl service"), None) return cache = self pending = [] contexts = [] class DoneGetChildren(runcontrol.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log("Error from RunControl.GetChildren", error) else: for c in context_ids: contexts.append(c) pending.append(rc.getChildren(c, self)) if len(pending) == 0: cache.set(None, None, contexts) pending.append(rc.getChildren(None, DoneGetChildren())) contextsCache = ContextsCache(c) def done(): print("ContextsCache is valid: " + str(contextsCache.getData())) protocol.invokeLater(contextsCache.validate, done)
def testProcesses(c): from tcf.services import processes, processes_v1 lock = threading.Condition() def processTest(): proc = c.getRemoteService(processes_v1.NAME) or \ c.getRemoteService(processes.NAME) if not proc: with lock: lock.notify() return class DoneGetChildren(processes.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): if error: protocol.log("Error from Processes.GetChildren", error) else: print "Processes:", context_ids with lock: lock.notify() proc.getChildren(None, False, DoneGetChildren()) with lock: protocol.invokeLater(processTest) lock.wait(5)
def run(self): try: while True: n = self.channel.read() if n == EOM: continue if n == EOS: try: self.eos_err_report = self.readBytes(EOM) reportLen = len(self.eos_err_report) if reportLen == 0 or reportLen == 1 and self.eos_err_report[0] == 0: self.eos_err_report = None except: pass break msg = Message(n) if self.channel.read() != 0: self.error() typeCode = msg.type if typeCode == 'C': msg.token = Token(self.readBytes(0)) msg.service = self.readString() msg.name = self.readString() msg.data = self.readBytes(EOM) elif typeCode in 'PRN': msg.token = Token(self.readBytes(0)) msg.data = self.readBytes(EOM) elif typeCode == 'E': msg.service = self.readString() msg.name = self.readString() msg.data = self.readBytes(EOM) elif typeCode == 'F': msg.data = self.readBytes(EOM) else: self.error() protocol.invokeLater(self.handleInput, msg) delay = self.channel.local_congestion_level if delay > 0: time.sleep(delay / 1000.0) protocol.invokeLater(self.handleEOS) except Exception as x: try: x.tb = sys.exc_info()[2] protocol.invokeLater(self.channel.terminate, x) except: # TCF event dispatcher has shut down pass
def test(): protocol.startEventQueue() atexit.register(protocol.getEventQueue().shutdown) #testTimer() try: c = tcf.connect("TCP:127.0.0.1:1534") except Exception as e: protocol.log(e) sys.exit() assert c.state == channel.STATE_OPEN if __TRACE: protocol.invokeLater(c.addTraceListener, TraceListener()) def printServices(): print "services=", c.getRemoteServices() protocol.invokeLater(printServices) try: testRunControl(c) testStackTrace(c) testDisassembly(c) testBreakpoints(c) testSymbols(c) testRegisters(c) testExpressions(c) testLineNumbers(c) testSyncCommands(c) testTasks(c) testEvents(c) testDataCache(c) testProcesses(c) testFileSystem(c) testMemory(c) testMemoryMap(c) testPathMap(c) testSysMonitor(c) except Exception as e: protocol.log(e) if c.state == channel.STATE_OPEN: time.sleep(5) protocol.invokeLater(c.close) time.sleep(2)
def start(connection, path, *args): """Start a new process in suspended mode for the given connection. :param connection: The TCF connection to use services from. :param path: Path of the executable to start. :param args: command line arguments. """ def callStart(connection, condition, path, arguments, val): """Asynchronous request to start a process. :param connection: The TCF connection to get processes service from. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :param path: Path of the process to start on the target :param arguments: A list of program arguments for *path* :param val: A TcfValue handling the request returned value. :returns: **None**, always. """ # get connection's processes service proc = connection.getRemoteService(processes_v1.NAME) or \ connection.getRemoteService(processes.NAME) if not proc: with condition: print 'No processes service available' condition.notify() return class DoneStart(processes.DoneStart): """Client callback interface for ProcessesService.start().""" def doneStart(self, token, error, process): """Called when process start is done. :param token: pending command handle. :param error: error description if operation failed, **None** if succeeded. :param process: ProcessContext object representing the started process. """ if error: protocol.log("Error from Processes.start", error) else: val.setValue(process) with condition: condition.notify() # depending on the service, the start method only does 'doAttach', or # take a dictionnary of options if (proc.getName() == processes_v1.NAME): opts = {processes_v1.START_ATTACH: True, processes_v1.START_USE_TERMINAL: True} else: opts = True # start the process itself cmdLine = [path] if arguments: cmdLine += arguments proc.start(os.path.dirname(path), path, cmdLine, None, opts, DoneStart()) # create a condition to wait on, and a value to get the children ids lock = threading.Condition() value = TcfValue() with lock: # TCF requests must be called by the dispatch thread, wait for a # maximum of 10 seconds protocol.invokeLater(callStart, connection=connection, condition=lock, path=path, arguments=args, val=value) lock.wait(10) return (value.getValue())
def start(connection, path, *args): """Start a new process in suspended mode for the given connection. :param connection: The TCF connection to use services from. :param path: Path of the executable to start. :param args: command line arguments. """ def callStart(connection, condition, path, arguments, val): """Asynchronous request to start a process. :param connection: The TCF connection to get processes service from. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :param path: Path of the process to start on the target :param arguments: A list of program arguments for *path* :param val: A TcfValue handling the request returned value. :returns: **None**, always. """ # get connection's processes service proc = connection.getRemoteService(processes_v1.NAME) or \ connection.getRemoteService(processes.NAME) if not proc: with condition: print('No processes service available') condition.notify() return class DoneStart(processes.DoneStart): """Client callback interface for ProcessesService.start().""" def doneStart(self, token, error, process): """Called when process start is done. :param token: pending command handle. :param error: error description if operation failed, **None** if succeeded. :param process: ProcessContext object representing the started process. """ if error: protocol.log("Error from Processes.start", error) else: val.setValue(process) with condition: condition.notify() # depending on the service, the start method only does 'doAttach', or # take a dictionnary of options if (proc.getName() == processes_v1.NAME): opts = { processes_v1.START_ATTACH: True, processes_v1.START_USE_TERMINAL: True } else: opts = True # start the process itself cmdLine = [path] if arguments: cmdLine += arguments proc.start(os.path.dirname(path), path, cmdLine, None, opts, DoneStart()) # create a condition to wait on, and a value to get the children ids lock = threading.Condition() value = TcfValue() with lock: # TCF requests must be called by the dispatch thread, wait for a # maximum of 10 seconds protocol.invokeLater(callStart, connection=connection, condition=lock, path=path, arguments=args, val=value) lock.wait(10) return (value.getValue())
def state(context): """Get the state of a RunControlContext. Getting the state of a RunControlContext is asynchronous. :param context: The context to get state for. :type context: RunControlContext :returns: A tuple of four elements representing the RunControl context state : - A boolean stating if the context id suspended or not - An integer repesenting the program counter of the context (if it is suspended) - A string representing the reason why the context is suspended - A dictionary of properties stating why the suspended state properties (see runcontrol.STATE_*) """ def callGetState(context, condition, val): """Asynchronous request to get the context state. :param context: The RunControlContext to get state for. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :param val: A TcfValue handling the request returned value. :returns: **None**, always. """ class DoneGetState(runcontrol.DoneGetState): """Client call back class for RunControlContext.getState().""" def doneGetState(self, token, error, suspended, pc, reason, params): """Called when RunControlContext.getState() command execution is complete. :param token: pending command handle. :param error: command execution error or None. :param suspended: true if the context is suspended :param pc: program counter of the context (if suspended). :param reason: suspend reason (if suspended), see REASON_*. :param params: additional target specific data about context state, see STATE_*. """ if error: protocol.log("Error from runcontrol.getState()", error) else: val.setValue((suspended, pc, reason, params)) with condition: condition.notify() # start the process itself context.getState(DoneGetState()) # create a condition to wait on, and a value to get the children ids lock = threading.Condition() value = TcfValue() with lock: # TCF requests must be called by the dispatch thread, wait for a # maximum of 10 seconds protocol.invokeLater(callGetState, context=context, condition=lock, val=value) lock.wait(10) return (value.getValue())
def testRunControl(c): lock = threading.Condition() from tcf.services import runcontrol # @UnresolvedImport def getContexts(): rctrl = c.getRemoteService(runcontrol.NAME) pending = [] class DoneGetContext(runcontrol.DoneGetContext): def doneGetContext(self, token, error, context): pending.remove(token) if error: protocol.log("Error from RunControl.getContext", error) else: print(context) class DoneGetState(runcontrol.DoneGetState): def doneGetState(self, token, error, suspended, pc, reason, params): pending.remove(token) if error: protocol.log("Error from RunControl.getState", error) else: 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: with lock: lock.notify() if context and context.hasState(): pending.append(context.getState(DoneGetState())) if len(pending) == 0: with lock: lock.notify() class DoneGetChildren(runcontrol.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log("Error from RunControl.GetChildren", error) else: for c in context_ids: pending.append(rctrl.getContext(c, DoneGetContext())) pending.append(rctrl.getChildren(c, self)) if len(pending) == 0: with lock: lock.notify() pending.append(rctrl.getChildren(None, DoneGetChildren())) with lock: protocol.invokeLater(getContexts) lock.wait(5) def listenerTest(): rc = c.getRemoteService(runcontrol.NAME) class RCListener(runcontrol.RunControlListener): def contextSuspended(self, *args): print("context suspended: " + str(args)) rc.removeListener(self) def contextResumed(self, *args): print("context resumed: " + str(args)) def containerSuspended(self, *args): print("container suspended: " + str(args)) rc.removeListener(self) def containerResumed(self, *args): print("container resumed: " + str(args)) rc.addListener(RCListener()) class DoneGetContext(runcontrol.DoneGetContext): def doneGetContext(self, token, error, context): if error: protocol.log("Error from RunControl.getContext", error) with lock: lock.notify() return class DoneResume(runcontrol.DoneCommand): def doneCommand(self, token, error): if error: protocol.log("Error from RunControl.resume", error) else: context.suspend(runcontrol.DoneCommand()) with lock: lock.notify() context.resume(runcontrol.RM_RESUME, 1, None, DoneResume()) rc.getContext(_suspended[0], DoneGetContext()) if _suspended: with lock: protocol.invokeLater(listenerTest) lock.wait(5) _suspended.pop(0)
def testRunControl(c): lock = threading.Condition() from tcf.services import runcontrol def getContexts(): rctrl = c.getRemoteService(runcontrol.NAME) pending = [] class DoneGetContext(runcontrol.DoneGetContext): def doneGetContext(self, token, error, context): pending.remove(token) if error: protocol.log("Error from RunControl.getContext", error) else: print context class DoneGetState(runcontrol.DoneGetState): def doneGetState(self, token, error, suspended, pc, reason, params): pending.remove(token) if error: protocol.log( "Error from RunControl.getState", error) else: print "suspended: ", suspended print "pc: ", pc print "reason: ", reason print "params: ", params if suspended: _suspended.append(context.getID()) if len(pending) == 0: with lock: lock.notify() if context and context.hasState(): pending.append(context.getState(DoneGetState())) if len(pending) == 0: with lock: lock.notify() class DoneGetChildren(runcontrol.DoneGetChildren): def doneGetChildren(self, token, error, context_ids): pending.remove(token) if error: protocol.log("Error from RunControl.GetChildren", error) else: for c in context_ids: pending.append(rctrl.getContext(c, DoneGetContext())) pending.append(rctrl.getChildren(c, self)) if len(pending) == 0: with lock: lock.notify() pending.append(rctrl.getChildren(None, DoneGetChildren())) with lock: protocol.invokeLater(getContexts) lock.wait(5) def listenerTest(): rc = c.getRemoteService(runcontrol.NAME) class RCListener(runcontrol.RunControlListener): def contextSuspended(self, *args): print "context suspended: ", args rc.removeListener(self) def contextResumed(self, *args): print "context resumed: ", args def containerSuspended(self, *args): print "container suspended:", args rc.removeListener(self) def containerResumed(self, *args): print "container resumed:", args rc.addListener(RCListener()) class DoneGetContext(runcontrol.DoneGetContext): def doneGetContext(self, token, error, context): if error: protocol.log("Error from RunControl.getContext", error) with lock: lock.notify() return class DoneResume(runcontrol.DoneCommand): def doneCommand(self, token, error): if error: protocol.log("Error from RunControl.resume", error) else: context.suspend(runcontrol.DoneCommand()) with lock: lock.notify() context.resume(runcontrol.RM_RESUME, 1, None, DoneResume()) rc.getContext(_suspended[0], DoneGetContext()) if _suspended: with lock: protocol.invokeLater(listenerTest) lock.wait(5)
def testRegisters(c): if not _suspended: return from tcf.services import registers # @UnresolvedImport lock = threading.Condition() def regTest(ctx_id): regs = c.getRemoteService(registers.NAME) pending = [] def onDone(): with lock: lock.notify() class DoneGetChildren(registers.DoneGetChildren): def doneGetChildren(self, token, error, ctx_ids): pending.remove(token) if error: protocol.log("Error from Registers.getChildren", error) if not pending: onDone() class DoneGetContext(registers.DoneGetContext): def doneGetContext(self, token, error, ctx): pending.remove(token) if error: protocol.log("Error from Registers.getContext", error) else: print(ctx) if ctx.isReadable() and not ctx.isReadOnce() \ and ctx.getSize() >= 2: locs = [] locs.append( registers.Location(ctx.getID(), 0, 1)) locs.append( registers.Location(ctx.getID(), 1, 1)) class DoneGetM(registers.DoneGet): def doneGet(self, token, error, value): pending.remove(token) if error: protocol.log( "Error from Registers.getm", error) else: print("getm " + str(ctx.getID()) + " " + str(list(map(int, value)))) if not pending: onDone() pending.append(regs.getm(locs, DoneGetM())) if ctx.isWriteable() and not ctx.isWriteOnce() \ and ctx.getSize() >= 2: locs = [] locs.append( registers.Location(ctx.getID(), 0, 1)) locs.append( registers.Location(ctx.getID(), 1, 1)) class DoneSetM(registers.DoneSet): def doneGet(self, token, error): pending.remove(token) if error: protocol.log( "Error from Registers.setm", error) if not pending: onDone() pending.append( regs.setm(locs, (255, 255), DoneSetM())) if not pending: onDone() if ctx_ids: for ctx_id in ctx_ids: pending.append( regs.getContext(ctx_id, DoneGetContext())) pending.append(regs.getChildren(ctx_id, DoneGetChildren())) with lock: for ctx_id in _suspended: protocol.invokeLater(regTest, ctx_id) lock.wait(5)
def getContext(service, contextID): """Get a TCF context from a given service. As most of the TCF services have a **getContext()** command, this function is intended to define a generic **getContext()** call which can address any service. As the function returns a context object, it is up to the caller to use it appropriately. For example, for the runcontrol service, check if the runcontrol context is a container : .. code-block:: python import tcf import tcf.services.runcontrol as runcontrol c = tcf.connect("TCP:127.0.0.1:1534") rcSvc = getService(c, runcontrol.NAME) rcIDs = getChildren(rcSvc, None) rcContext = getContext(rcSvc, rcIDs[0]) 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* :returns: A context properties dictionnary, or **None** on error. """ def callGetContext(service, condition, val): """Asynchronous request to get context properties. :param service: The TCF service proxy to send request to. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :param val: A TcfValue handling the request returned value. :returns: **None**, always. """ class DoneGetContext(object): """Client callback class for <service>.getContext() command.""" def doneGetContext(self, token, error, context): """Called when context data retrieval is done. :param token: pending command handle. :param error: error description if operation failed, **None** if succeeded. :param context: context data. """ if error: protocol.log( "Error from " + service.getName() + ".getContext()", error) else: val.setValue(context) with condition: condition.notify() # start the process itself service.getContext(contextID, DoneGetContext()) # create a condition to wait on, and a value to get the children ids lock = threading.Condition() value = TcfValue() with lock: # TCF requests must be called by the dispatch thread, wait for a # maximum of 10 seconds protocol.invokeLater(callGetContext, service=service, condition=lock, val=value) lock.wait(10) # Return the context properties, or None on error return (value.getValue())
def getChildren(service, contextID=None): """Get a TCF context IDs from a given service. As many TCF services have a **getChildren()** command, this function is intended to implement a service-independant **getChildren()** command. :param service: The TCF service to get context list from. :param contextID: parent ID of the context list to get from *service*. :returns: A tuple of context IDs. Tuple may be empty on error, or if *contextID* does not have children. """ def callGetChildren(service, condition, val): """Asynchronous request to get context children. :param service: The TCF service proxy to send request to. :param condition: A threading.Condition the caller is pending on. Caller is released from waiting through a Condition.notify() call. :param val: A TcfValue handling the request returned value. :returns: **None**, always. """ class DoneGetChildren(object): """Client callback class for <service>.getChildren() command.""" def doneGetChildren(self, token, error, ids): """Called when context list retrieval is done. :param token: pending command handle. :param error: error description if operation failed, **None** if succeeded. :param context_ids: array of available context IDs. """ if error: protocol.log( "Error from " + service.getName() + ".getContext()", error) else: val.setValue(ids) with condition: condition.notify() # start the process itself service.getChildren(contextID, DoneGetChildren()) # create a condition to wait on, and a value to get the children ids lock = threading.Condition() value = TcfValue() with lock: # TCF requests must be called by the dispatch thread, wait for a # maximum of 10 seconds protocol.invokeLater(callGetChildren, service=service, condition=lock, val=value) lock.wait(10) # Return the retrieved children IDs, or an empty tuple return (tuple(value.getValue() or []))