--- a/DebugClients/Python/ThreadExtension.py Thu Oct 06 22:28:12 2016 +0200 +++ b/DebugClients/Python/ThreadExtension.py Thu Oct 06 22:51:04 2016 +0200 @@ -37,7 +37,7 @@ self.clientLock = threading.RLock() # dictionary of all threads running {id: DebugBase} - self.threads = {} + self.threads = {_thread.get_ident(): self} # the "current" thread, basically for variables view self.currentThread = self @@ -59,40 +59,42 @@ # if hasattr(sys, 'breakpoint): sys.breakpoint() sys.breakpoint = self.set_trace - def attachThread(self, target=None, args=None, kwargs=None, + def attachThread(self, target=None, args=None, kwargs={}, mainThread=False): """ - Public method to setup a thread for DebugClient to debug. + Public method to setup a standard thread for DebugClient to debug. If mainThread is True, then we are attaching to the already started mainthread of the app and the rest of the args are ignored. - @param target the start function of the target thread (i.e. the - user code) + @param target the start function of the target thread (i.e. the user + code) @param args arguments to pass to target @param kwargs keyword arguments to pass to target @param mainThread True, if we are attaching to the already started mainthread of the app @return identifier of the created thread """ - return - try: - self.lockClient() - newThread = DebugThread(self, target, args, kwargs, mainThread) - ident = -1 - if mainThread: - ident = _thread.get_ident() - self.mainThread = newThread - if self.debugging: - sys.setprofile(newThread.profile) - else: - ident = _original_start_thread(newThread.bootstrap, ()) - if self.mainThread is not None: - self.tracePython = self.mainThread.tracePython - newThread.set_ident(ident) - self.threads[newThread.get_ident()] = newThread - finally: - self.unlockClient() + if mainThread: + ident = _thread.get_ident() + name = 'MainThread' + newThread = self.mainThread + newThread._mainThread = True + if self.debugging: + sys.setprofile(newThread.profile) + + else: + newThread = DebugBase(self) + ident = self._original_start_new_thread( + newThread.bootstrap, (target, args, kwargs)) + name = 'Thread-{0}'.format(self.threadNumber) + self.threadNumber += 1 + + newThread.id = ident + newThread.name = name + + self.threads[ident] = newThread + return ident def threadTerminated(self, dbgThread): @@ -152,24 +154,26 @@ Public method to send the list of threads. """ threadList = [] - if self.threads and self.currentThread: - # indication for the threaded debugger - currentId = self.currentThread.get_ident() - for t in self.threads.values(): - d = {} - d["id"] = t.get_ident() - d["name"] = t.get_name() - d["broken"] = t.isBroken + if len(self.threads) > 1: + currentId = _thread.get_ident() + # update thread names set by user (threading.setName) + threadNames = {t.ident: t.getName() for t in threading.enumerate()} + + for id, thd in self.threads.items(): + d = {"id": id} + try: + d["name"] = threadNames.get(id, thd.name) + d["broken"] = thd.isBroken + except Exception: + d["name"] = 'UnknownThread' + d["broken"] = False + threadList.append(d) else: currentId = -1 - d = {} - d["id"] = -1 + d = {"id": -1} d["name"] = "MainThread" - if hasattr(self, "isBroken"): - d["broken"] = self.isBroken - else: - d["broken"] = False + d["broken"] = self.isBroken threadList.append(d) self.sendJsonCommand("ResponseThreadList", {