1+ from abc import ABC , abstractmethod
12import ctypes
23import errno
34import io
45import threading
56import socket
67import traceback
78from lldbsuite .support import seven
9+ from typing import Optional , List , Tuple
810
911
1012def checksum (message ):
@@ -86,7 +88,7 @@ class MockGDBServerResponder:
8688 handles any packet not recognized in the common packet handling code.
8789 """
8890
89- registerCount = 40
91+ registerCount : int = 40
9092
9193 class RESPONSE_DISCONNECT :
9294 pass
@@ -95,7 +97,7 @@ class RESPONSE_NONE:
9597 pass
9698
9799 def __init__ (self ):
98- self .packetLog = []
100+ self .packetLog : List [ str ] = []
99101
100102 def respond (self , packet ):
101103 """
@@ -241,7 +243,7 @@ def qProcessInfo(self):
241243 def qHostInfo (self ):
242244 return "ptrsize:8;endian:little;"
243245
244- def qEcho (self ):
246+ def qEcho (self , num : int ):
245247 return "E04"
246248
247249 def qQueryGDBServer (self ):
@@ -262,10 +264,10 @@ def A(self, packet):
262264 def D (self , packet ):
263265 return "OK"
264266
265- def readRegisters (self ):
267+ def readRegisters (self ) -> str :
266268 return "00000000" * self .registerCount
267269
268- def readRegister (self , register ) :
270+ def readRegister (self , register : int ) -> str :
269271 return "00000000"
270272
271273 def writeRegisters (self , registers_hex ):
@@ -305,7 +307,9 @@ def haltReason(self):
305307 # SIGINT is 2, return type is 2 digit hex string
306308 return "S02"
307309
308- def qXferRead (self , obj , annex , offset , length ):
310+ def qXferRead (
311+ self , obj : str , annex : str , offset : int , length : int
312+ ) -> Tuple [Optional [str ], bool ]:
309313 return None , False
310314
311315 def _qXferResponse (self , data , has_more ):
@@ -373,15 +377,17 @@ class UnexpectedPacketException(Exception):
373377 pass
374378
375379
376- class ServerChannel :
380+ class ServerChannel ( ABC ) :
377381 """
378382 A wrapper class for TCP or pty-based server.
379383 """
380384
381- def get_connect_address (self ):
385+ @abstractmethod
386+ def get_connect_address (self ) -> str :
382387 """Get address for the client to connect to."""
383388
384- def get_connect_url (self ):
389+ @abstractmethod
390+ def get_connect_url (self ) -> str :
385391 """Get URL suitable for process connect command."""
386392
387393 def close_server (self ):
@@ -393,10 +399,12 @@ def accept(self):
393399 def close_connection (self ):
394400 """Close all resources used by the accepted connection."""
395401
396- def recv (self ):
402+ @abstractmethod
403+ def recv (self ) -> bytes :
397404 """Receive a data packet from the connected client."""
398405
399- def sendall (self , data ):
406+ @abstractmethod
407+ def sendall (self , data : bytes ) -> None :
400408 """Send the data to the connected client."""
401409
402410
@@ -427,11 +435,11 @@ def close_connection(self):
427435 self ._connection .close ()
428436 self ._connection = None
429437
430- def recv (self ):
438+ def recv (self ) -> bytes :
431439 assert self ._connection is not None
432440 return self ._connection .recv (4096 )
433441
434- def sendall (self , data ) :
442+ def sendall (self , data : bytes ) -> None :
435443 assert self ._connection is not None
436444 return self ._connection .sendall (data )
437445
@@ -443,21 +451,21 @@ def __init__(self):
443451 )[0 ]
444452 super ().__init__ (family , type , proto , addr )
445453
446- def get_connect_address (self ):
454+ def get_connect_address (self ) -> str :
447455 return "[{}]:{}" .format (* self ._server_socket .getsockname ())
448456
449- def get_connect_url (self ):
457+ def get_connect_url (self ) -> str :
450458 return "connect://" + self .get_connect_address ()
451459
452460
453461class UnixServerSocket (ServerSocket ):
454462 def __init__ (self , addr ):
455463 super ().__init__ (socket .AF_UNIX , socket .SOCK_STREAM , 0 , addr )
456464
457- def get_connect_address (self ):
465+ def get_connect_address (self ) -> str :
458466 return self ._server_socket .getsockname ()
459467
460- def get_connect_url (self ):
468+ def get_connect_url (self ) -> str :
461469 return "unix-connect://" + self .get_connect_address ()
462470
463471
@@ -471,7 +479,7 @@ def __init__(self):
471479 self ._primary = io .FileIO (primary , "r+b" )
472480 self ._secondary = io .FileIO (secondary , "r+b" )
473481
474- def get_connect_address (self ):
482+ def get_connect_address (self ) -> str :
475483 libc = ctypes .CDLL (None )
476484 libc .ptsname .argtypes = (ctypes .c_int ,)
477485 libc .ptsname .restype = ctypes .c_char_p
@@ -484,7 +492,7 @@ def close_server(self):
484492 self ._secondary .close ()
485493 self ._primary .close ()
486494
487- def recv (self ):
495+ def recv (self ) -> bytes :
488496 try :
489497 return self ._primary .read (4096 )
490498 except OSError as e :
@@ -493,8 +501,8 @@ def recv(self):
493501 return b""
494502 raise
495503
496- def sendall (self , data ) :
497- return self ._primary .write (data )
504+ def sendall (self , data : bytes ) -> None :
505+ self ._primary .write (data )
498506
499507
500508class MockGDBServer :
@@ -527,18 +535,21 @@ def stop(self):
527535 self ._thread .join ()
528536 self ._thread = None
529537
530- def get_connect_address (self ):
538+ def get_connect_address (self ) -> str :
539+ assert self ._socket is not None
531540 return self ._socket .get_connect_address ()
532541
533- def get_connect_url (self ):
542+ def get_connect_url (self ) -> str :
543+ assert self ._socket is not None
534544 return self ._socket .get_connect_url ()
535545
536546 def run (self ):
547+ assert self ._socket is not None
537548 # For testing purposes, we only need to worry about one client
538549 # connecting just one time.
539550 try :
540551 self ._socket .accept ()
541- except :
552+ except Exception :
542553 traceback .print_exc ()
543554 return
544555 self ._shouldSendAck = True
@@ -553,7 +564,7 @@ def run(self):
553564 self ._receive (data )
554565 except self .TerminateConnectionException :
555566 pass
556- except Exception as e :
567+ except Exception :
557568 print (
558569 "An exception happened when receiving the response from the gdb server. Closing the client..."
559570 )
@@ -586,7 +597,9 @@ def _parsePacket(self):
586597 Once a complete packet is found at the front of self._receivedData,
587598 its data is removed form self._receivedData.
588599 """
600+ assert self ._receivedData is not None
589601 data = self ._receivedData
602+ assert self ._receivedDataOffset is not None
590603 i = self ._receivedDataOffset
591604 data_len = len (data )
592605 if data_len == 0 :
@@ -639,10 +652,13 @@ def _parsePacket(self):
639652 self ._receivedDataOffset = 0
640653 return packet
641654
642- def _sendPacket (self , packet ):
643- self ._socket .sendall (seven .bitcast_to_bytes (frame_packet (packet )))
655+ def _sendPacket (self , packet : str ):
656+ assert self ._socket is not None
657+ framed_packet = seven .bitcast_to_bytes (frame_packet (packet ))
658+ self ._socket .sendall (framed_packet )
644659
645660 def _handlePacket (self , packet ):
661+ assert self ._socket is not None
646662 if packet is self .PACKET_ACK :
647663 # Ignore ACKs from the client. For the future, we can consider
648664 # adding validation code to make sure the client only sends ACKs
0 commit comments