eric6/Debugger/DebugServer.py

branch
maintenance
changeset 7286
7eb04391adf7
parent 6989
8b8cadf8d7e9
parent 7251
bc5b1b00560a
child 7362
028bf21bb5a2
equal deleted inserted replaced
7226:babe80d84a3e 7286:7eb04391adf7
5 5
6 """ 6 """
7 Module implementing the debug server. 7 Module implementing the debug server.
8 """ 8 """
9 9
10 from __future__ import unicode_literals
11 try:
12 str = unicode
13 except NameError:
14 pass
15 10
16 import os 11 import os
17 import sys 12 import sys
18 13
19 from PyQt5.QtCore import pyqtSignal, QModelIndex 14 from PyQt5.QtCore import pyqtSignal, QModelIndex
20 from PyQt5.QtNetwork import QTcpServer, QHostAddress, QHostInfo, \ 15 from PyQt5.QtNetwork import (
21 QNetworkInterface 16 QTcpServer, QHostAddress, QHostInfo, QNetworkInterface
17 )
22 18
23 from E5Gui.E5Application import e5App 19 from E5Gui.E5Application import e5App
24 from E5Gui import E5MessageBox 20 from E5Gui import E5MessageBox
25 21
26 from .BreakPointModel import BreakPointModel 22 from .BreakPointModel import BreakPointModel
183 # the value 179 # the value
184 180
185 # create our models 181 # create our models
186 self.breakpointModel = BreakPointModel(self) 182 self.breakpointModel = BreakPointModel(self)
187 self.watchpointModel = WatchPointModel(self) 183 self.watchpointModel = WatchPointModel(self)
188 self.watchSpecialCreated = \ 184 self.watchSpecialCreated = self.tr(
189 self.tr("created", "must be same as in EditWatchpointDialog") 185 "created", "must be same as in EditWatchpointDialog")
190 self.watchSpecialChanged = \ 186 self.watchSpecialChanged = self.tr(
191 self.tr("changed", "must be same as in EditWatchpointDialog") 187 "changed", "must be same as in EditWatchpointDialog")
192 188
193 self.networkInterface = Preferences.getDebugger("NetworkInterface") 189 self.networkInterface = Preferences.getDebugger("NetworkInterface")
194 if self.networkInterface == "all": 190 if self.networkInterface == "all":
195 hostAddress = QHostAddress("0.0.0.0") # QHostAddress.Any) 191 hostAddress = QHostAddress("0.0.0.0") # QHostAddress.Any)
196 elif self.networkInterface == "allv6": 192 elif self.networkInterface == "allv6":
197 hostAddress = QHostAddress("::") # QHostAddress.AnyIPv6) 193 hostAddress = QHostAddress("::") # QHostAddress.AnyIPv6)
198 else: 194 else:
199 hostAddress = QHostAddress(self.networkInterface) 195 hostAddress = QHostAddress(self.networkInterface)
200 self.networkInterfaceName, self.networkInterfaceIndex = \ 196 self.networkInterfaceName, self.networkInterfaceIndex = (
201 self.__getNetworkInterfaceAndIndex(self.networkInterface) 197 self.__getNetworkInterfaceAndIndex(self.networkInterface))
202 198
203 if not preventPassiveDebugging and \ 199 if (not preventPassiveDebugging and
204 Preferences.getDebugger("PassiveDbgEnabled"): 200 Preferences.getDebugger("PassiveDbgEnabled")):
205 sock = Preferences.getDebugger("PassiveDbgPort") # default: 42424 201 sock = Preferences.getDebugger("PassiveDbgPort") # default: 42424
206 self.listen(hostAddress, sock) 202 self.listen(hostAddress, sock)
207 self.passive = True 203 self.passive = True
208 self.passiveClientExited = False 204 self.passiveClientExited = False
209 else: 205 else:
215 self.debuggerInterface = None 211 self.debuggerInterface = None
216 self.debugging = False 212 self.debugging = False
217 self.running = False 213 self.running = False
218 self.clientProcess = None 214 self.clientProcess = None
219 self.clientInterpreter = "" 215 self.clientInterpreter = ""
220 self.clientType = \ 216 self.clientType = Preferences.Prefs.settings.value('DebugClient/Type')
221 Preferences.Prefs.settings.value('DebugClient/Type')
222 if self.clientType is None: 217 if self.clientType is None:
223 if sys.version_info[0] == 2: 218 self.clientType = 'Python3'
224 self.clientType = 'Python2'
225 else:
226 self.clientType = 'Python3'
227 # Change clientType if dependent interpreter does not exist anymore 219 # Change clientType if dependent interpreter does not exist anymore
228 # (maybe deinstalled,...) 220 # (maybe deinstalled,...)
229 elif self.clientType == 'Python2' and Preferences.getDebugger( 221 elif self.clientType == 'Python2' and Preferences.getDebugger(
230 "Python2VirtualEnv") == '' and sys.version_info[0] == 3: 222 "Python2VirtualEnv") == '' and sys.version_info[0] >= 3:
231 self.clientType = 'Python3' 223 self.clientType = 'Python3'
232 elif self.clientType == 'Python3' and Preferences.getDebugger( 224 elif self.clientType == 'Python3' and Preferences.getDebugger(
233 "Python3VirtualEnv") == '' and sys.version_info[0] == 2: 225 "Python3VirtualEnv") == '' and sys.version_info[0] == 2:
234 self.clientType = 'Python2' 226 self.clientType = 'Python2'
235 227
293 if address not in ["all", "allv6"]: 285 if address not in ["all", "allv6"]:
294 for networkInterface in QNetworkInterface.allInterfaces(): 286 for networkInterface in QNetworkInterface.allInterfaces():
295 addressEntries = networkInterface.addressEntries() 287 addressEntries = networkInterface.addressEntries()
296 if len(addressEntries) > 0: 288 if len(addressEntries) > 0:
297 for addressEntry in addressEntries: 289 for addressEntry in addressEntries:
298 if addressEntry.ip().toString().lower() == \ 290 if (addressEntry.ip().toString().lower() ==
299 address.lower(): 291 address.lower()):
300 return networkInterface.humanReadableName(), \ 292 return (networkInterface.humanReadableName(),
301 networkInterface.index() 293 networkInterface.index())
302 294
303 return "", 0 295 return "", 0
304 296
305 def preferencesChanged(self): 297 def preferencesChanged(self):
306 """ 298 """
307 Public slot to handle the preferencesChanged signal. 299 Public slot to handle the preferencesChanged signal.
308 """ 300 """
309 registeredInterfaces = {} 301 registeredInterfaces = {}
310 for interfaceName in self.__debuggerInterfaces: 302 for interfaceName in self.__debuggerInterfaces:
311 registeredInterfaces[interfaceName] = \ 303 registeredInterfaces[interfaceName] = (
312 self.__debuggerInterfaces[interfaceName] 304 self.__debuggerInterfaces[interfaceName])
313 305
314 self.__debuggerInterfaceRegistry = {} 306 self.__debuggerInterfaceRegistry = {}
315 for interfaceName, getRegistryData in registeredInterfaces.items(): 307 for interfaceName, getRegistryData in registeredInterfaces.items():
316 self.registerDebuggerInterface(interfaceName, getRegistryData, 308 self.registerDebuggerInterface(interfaceName, getRegistryData,
317 reregister=True) 309 reregister=True)
344 336
345 if not reregister: 337 if not reregister:
346 self.__debuggerInterfaces[interfaceName] = getRegistryData 338 self.__debuggerInterfaces[interfaceName] = getRegistryData
347 registryDataList = getRegistryData() 339 registryDataList = getRegistryData()
348 if registryDataList: 340 if registryDataList:
349 for clientLanguage, clientCapabilities, clientExtensions, \ 341 for (clientLanguage, clientCapabilities, clientExtensions,
350 interfaceCreator in registryDataList: 342 interfaceCreator) in registryDataList:
351 self.__debuggerInterfaceRegistry[clientLanguage] = [ 343 self.__debuggerInterfaceRegistry[clientLanguage] = [
352 clientCapabilities, clientExtensions, interfaceCreator, 344 clientCapabilities, clientExtensions, interfaceCreator,
353 interfaceName] 345 interfaceName]
354 346
355 def unregisterDebuggerInterface(self, interfaceName): 347 def unregisterDebuggerInterface(self, interfaceName):
359 @param interfaceName interfaceName of the debugger interface 351 @param interfaceName interfaceName of the debugger interface
360 @type str 352 @type str
361 """ 353 """
362 if interfaceName in self.__debuggerInterfaces: 354 if interfaceName in self.__debuggerInterfaces:
363 clientLanguages = [] 355 clientLanguages = []
364 for clientLanguage, registryData in \ 356 for clientLanguage, registryData in (
365 self.__debuggerInterfaceRegistry.items(): 357 self.__debuggerInterfaceRegistry.items()):
366 if interfaceName == registryData[-1]: 358 if interfaceName == registryData[-1]:
367 clientLanguages.append(clientLanguage) 359 clientLanguages.append(clientLanguage)
368 for clientLanguage in clientLanguages: 360 for clientLanguage in clientLanguages:
369 del self.__debuggerInterfaceRegistry[clientLanguage] 361 del self.__debuggerInterfaceRegistry[clientLanguage]
370 del self.__debuggerInterfaces[interfaceName] 362 del self.__debuggerInterfaces[interfaceName]
410 languages.remove("None") 402 languages.remove("None")
411 except ValueError: 403 except ValueError:
412 pass # it is not in the list 404 pass # it is not in the list
413 405
414 if shellOnly: 406 if shellOnly:
415 languages = \ 407 languages = [lang for lang in languages
416 [lang for lang in languages 408 if self.__debuggerInterfaceRegistry[lang][0] &
417 if self.__debuggerInterfaceRegistry[lang][0] & 409 DebugClientCapabilities.HasShell]
418 DebugClientCapabilities.HasShell]
419 410
420 return languages[:] 411 return languages[:]
421 412
422 def getExtensions(self, language): 413 def getExtensions(self, language):
423 """ 414 """
428 (tuple of strings) 419 (tuple of strings)
429 """ 420 """
430 if language in self.__debuggerInterfaceRegistry: 421 if language in self.__debuggerInterfaceRegistry:
431 return tuple(self.__debuggerInterfaceRegistry[language][1]) 422 return tuple(self.__debuggerInterfaceRegistry[language][1])
432 else: 423 else:
433 return tuple() 424 return ()
434 425
435 def __createDebuggerInterface(self, clientType=None): 426 def __createDebuggerInterface(self, clientType=None):
436 """ 427 """
437 Private slot to create the debugger interface object. 428 Private slot to create the debugger interface object.
438 429
440 """ 431 """
441 if self.lastClientType != self.clientType or clientType is not None: 432 if self.lastClientType != self.clientType or clientType is not None:
442 if clientType is None: 433 if clientType is None:
443 clientType = self.clientType 434 clientType = self.clientType
444 if clientType in self.__debuggerInterfaceRegistry: 435 if clientType in self.__debuggerInterfaceRegistry:
445 self.debuggerInterface = \ 436 self.debuggerInterface = (
446 self.__debuggerInterfaceRegistry[clientType][2]( 437 self.__debuggerInterfaceRegistry[clientType][2](
447 self, self.passive) 438 self, self.passive))
448 else: 439 else:
449 self.debuggerInterface = \ 440 self.debuggerInterface = (
450 self.__debuggerInterfaceRegistry["None"][2]( 441 self.__debuggerInterfaceRegistry["None"][2](
451 self, self.passive) 442 self, self.passive))
452 self.clientType = "None" 443 self.clientType = "None"
453 444
454 def __setClientType(self, clType): 445 def __setClientType(self, clType):
455 """ 446 """
456 Private method to set the client type. 447 Private method to set the client type.
507 self.__forProject = forProject 498 self.__forProject = forProject
508 self.__createDebuggerInterface() 499 self.__createDebuggerInterface()
509 if forProject: 500 if forProject:
510 project = e5App().getObject("Project") 501 project = e5App().getObject("Project")
511 if not project.isDebugPropertiesLoaded(): 502 if not project.isDebugPropertiesLoaded():
512 self.clientProcess, isNetworked, clientInterpreter = \ 503 self.clientProcess, isNetworked, clientInterpreter = (
513 self.debuggerInterface.startRemote( 504 self.debuggerInterface.startRemote(
514 self.serverPort(), runInConsole, venvName, 505 self.serverPort(), runInConsole, venvName,
515 self.__originalPathString, workingDir=workingDir) 506 self.__originalPathString, workingDir=workingDir))
516 else: 507 else:
517 self.clientProcess, isNetworked, clientInterpreter = \ 508 self.clientProcess, isNetworked, clientInterpreter = (
518 self.debuggerInterface.startRemoteForProject( 509 self.debuggerInterface.startRemoteForProject(
519 self.serverPort(), runInConsole, venvName, 510 self.serverPort(), runInConsole, venvName,
520 self.__originalPathString, workingDir=workingDir) 511 self.__originalPathString, workingDir=workingDir))
521 else: 512 else:
522 self.clientProcess, isNetworked, clientInterpreter = \ 513 self.clientProcess, isNetworked, clientInterpreter = (
523 self.debuggerInterface.startRemote( 514 self.debuggerInterface.startRemote(
524 self.serverPort(), runInConsole, venvName, 515 self.serverPort(), runInConsole, venvName,
525 self.__originalPathString, workingDir=workingDir) 516 self.__originalPathString, workingDir=workingDir))
526 517
527 if self.clientProcess: 518 if self.clientProcess:
528 self.clientProcess.readyReadStandardError.connect( 519 self.clientProcess.readyReadStandardError.connect(
529 self.__clientProcessError) 520 self.__clientProcessError)
530 self.clientProcess.readyReadStandardOutput.connect( 521 self.clientProcess.readyReadStandardOutput.connect(
588 @param end end row (integer) 579 @param end end row (integer)
589 """ 580 """
590 if self.debugging: 581 if self.debugging:
591 for row in range(start, end + 1): 582 for row in range(start, end + 1):
592 index = self.breakpointModel.index(row, 0, parentIndex) 583 index = self.breakpointModel.index(row, 0, parentIndex)
593 fn, lineno = \ 584 fn, lineno = (
594 self.breakpointModel.getBreakPointByIndex(index)[0:2] 585 self.breakpointModel.getBreakPointByIndex(index)[0:2])
595 self.remoteBreakpoint(fn, lineno, False) 586 self.remoteBreakpoint(fn, lineno, False)
596 587
597 def __changeBreakPoints(self, startIndex, endIndex): 588 def __changeBreakPoints(self, startIndex, endIndex):
598 """ 589 """
599 Private slot to set changed breakpoints. 590 Private slot to set changed breakpoints.
626 @param end end row (integer) 617 @param end end row (integer)
627 """ 618 """
628 if self.debugging: 619 if self.debugging:
629 for row in range(start, end + 1): 620 for row in range(start, end + 1):
630 index = self.breakpointModel.index(row, 0, parentIndex) 621 index = self.breakpointModel.index(row, 0, parentIndex)
631 fn, line, cond, temp, enabled, ignorecount = \ 622 fn, line, cond, temp, enabled, ignorecount = (
632 self.breakpointModel.getBreakPointByIndex(index)[:6] 623 self.breakpointModel.getBreakPointByIndex(index)[:6])
633 self.remoteBreakpoint(fn, line, True, cond, temp) 624 self.remoteBreakpoint(fn, line, True, cond, temp)
634 if not enabled: 625 if not enabled:
635 self.__remoteBreakpointEnable(fn, line, False) 626 self.__remoteBreakpointEnable(fn, line, False)
636 if ignorecount: 627 if ignorecount:
637 self.__remoteBreakpointIgnore(fn, line, ignorecount) 628 self.__remoteBreakpointIgnore(fn, line, ignorecount)
693 @param end end row (integer) 684 @param end end row (integer)
694 """ 685 """
695 if self.debugging: 686 if self.debugging:
696 for row in range(start, end + 1): 687 for row in range(start, end + 1):
697 index = self.watchpointModel.index(row, 0, parentIndex) 688 index = self.watchpointModel.index(row, 0, parentIndex)
698 cond, special = \ 689 cond, special = (
699 self.watchpointModel.getWatchPointByIndex(index)[0:2] 690 self.watchpointModel.getWatchPointByIndex(index)[0:2])
700 cond = self.__makeWatchCondition(cond, special) 691 cond = self.__makeWatchCondition(cond, special)
701 self.__remoteWatchpoint(cond, False) 692 self.__remoteWatchpoint(cond, False)
702 693
703 def __watchPointDataAboutToBeChanged(self, startIndex, endIndex): 694 def __watchPointDataAboutToBeChanged(self, startIndex, endIndex):
704 """ 695 """
721 @param end end row (integer) 712 @param end end row (integer)
722 """ 713 """
723 if self.debugging: 714 if self.debugging:
724 for row in range(start, end + 1): 715 for row in range(start, end + 1):
725 index = self.watchpointModel.index(row, 0, parentIndex) 716 index = self.watchpointModel.index(row, 0, parentIndex)
726 cond, special, temp, enabled, ignorecount = \ 717 cond, special, temp, enabled, ignorecount = (
727 self.watchpointModel.getWatchPointByIndex(index)[:5] 718 self.watchpointModel.getWatchPointByIndex(index)[:5])
728 cond = self.__makeWatchCondition(cond, special) 719 cond = self.__makeWatchCondition(cond, special)
729 self.__remoteWatchpoint(cond, True, temp) 720 self.__remoteWatchpoint(cond, True, temp)
730 if not enabled: 721 if not enabled:
731 self.__remoteWatchpointEnable(cond, False) 722 self.__remoteWatchpointEnable(cond, False)
732 if ignorecount: 723 if ignorecount:

eric ide

mercurial