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
810
911
1012def checksum (message ):
@@ -86,8 +88,8 @@ class MockGDBServerResponder:
8688 handles any packet not recognized in the common packet handling code.
8789 """
8890
89- registerCount = 40
90- packetLog = None
91+ registerCount : int = 40
92+ packetLog : Optional [ list [ str ]] = None
9193
9294 class RESPONSE_DISCONNECT :
9395 pass
@@ -103,6 +105,7 @@ def respond(self, packet):
103105 Return the unframed packet data that the server should issue in response
104106 to the given packet received from the client.
105107 """
108+ assert self .packetLog is not None
106109 self .packetLog .append (packet )
107110 if packet is MockGDBServer .PACKET_INTERRUPT :
108111 return self .interrupt ()
@@ -242,7 +245,7 @@ def qProcessInfo(self):
242245 def qHostInfo (self ):
243246 return "ptrsize:8;endian:little;"
244247
245- def qEcho (self ):
248+ def qEcho (self , _ : int ):
246249 return "E04"
247250
248251 def qQueryGDBServer (self ):
@@ -263,10 +266,10 @@ def A(self, packet):
263266 def D (self , packet ):
264267 return "OK"
265268
266- def readRegisters (self ):
269+ def readRegisters (self ) -> str :
267270 return "00000000" * self .registerCount
268271
269- def readRegister (self , register ) :
272+ def readRegister (self , register : int ) -> str :
270273 return "00000000"
271274
272275 def writeRegisters (self , registers_hex ):
@@ -306,7 +309,8 @@ def haltReason(self):
306309 # SIGINT is 2, return type is 2 digit hex string
307310 return "S02"
308311
309- def qXferRead (self , obj , annex , offset , length ):
312+ def qXferRead (self , obj : str , annex : str , offset : int ,
313+ length : int ) -> tuple [str | None , bool ]:
310314 return None , False
311315
312316 def _qXferResponse (self , data , has_more ):
@@ -374,15 +378,17 @@ class UnexpectedPacketException(Exception):
374378 pass
375379
376380
377- class ServerChannel :
381+ class ServerChannel ( ABC ) :
378382 """
379383 A wrapper class for TCP or pty-based server.
380384 """
381385
382- def get_connect_address (self ):
386+ @abstractmethod
387+ def get_connect_address (self ) -> str :
383388 """Get address for the client to connect to."""
384389
385- def get_connect_url (self ):
390+ @abstractmethod
391+ def get_connect_url (self ) -> str :
386392 """Get URL suitable for process connect command."""
387393
388394 def close_server (self ):
@@ -394,10 +400,12 @@ def accept(self):
394400 def close_connection (self ):
395401 """Close all resources used by the accepted connection."""
396402
397- def recv (self ):
403+ @abstractmethod
404+ def recv (self ) -> bytes :
398405 """Receive a data packet from the connected client."""
399406
400- def sendall (self , data ):
407+ @abstractmethod
408+ def sendall (self , data : bytes ) -> None :
401409 """Send the data to the connected client."""
402410
403411
@@ -428,11 +436,11 @@ def close_connection(self):
428436 self ._connection .close ()
429437 self ._connection = None
430438
431- def recv (self ):
439+ def recv (self ) -> bytes :
432440 assert self ._connection is not None
433441 return self ._connection .recv (4096 )
434442
435- def sendall (self , data ) :
443+ def sendall (self , data : bytes ) -> None :
436444 assert self ._connection is not None
437445 return self ._connection .sendall (data )
438446
@@ -444,21 +452,21 @@ def __init__(self):
444452 )[0 ]
445453 super ().__init__ (family , type , proto , addr )
446454
447- def get_connect_address (self ):
455+ def get_connect_address (self ) -> str :
448456 return "[{}]:{}" .format (* self ._server_socket .getsockname ())
449457
450- def get_connect_url (self ):
458+ def get_connect_url (self ) -> str :
451459 return "connect://" + self .get_connect_address ()
452460
453461
454462class UnixServerSocket (ServerSocket ):
455463 def __init__ (self , addr ):
456464 super ().__init__ (socket .AF_UNIX , socket .SOCK_STREAM , 0 , addr )
457465
458- def get_connect_address (self ):
466+ def get_connect_address (self ) -> str :
459467 return self ._server_socket .getsockname ()
460468
461- def get_connect_url (self ):
469+ def get_connect_url (self ) -> str :
462470 return "unix-connect://" + self .get_connect_address ()
463471
464472
@@ -472,7 +480,7 @@ def __init__(self):
472480 self ._primary = io .FileIO (primary , "r+b" )
473481 self ._secondary = io .FileIO (secondary , "r+b" )
474482
475- def get_connect_address (self ):
483+ def get_connect_address (self ) -> str :
476484 libc = ctypes .CDLL (None )
477485 libc .ptsname .argtypes = (ctypes .c_int ,)
478486 libc .ptsname .restype = ctypes .c_char_p
@@ -485,7 +493,7 @@ def close_server(self):
485493 self ._secondary .close ()
486494 self ._primary .close ()
487495
488- def recv (self ):
496+ def recv (self ) -> bytes :
489497 try :
490498 return self ._primary .read (4096 )
491499 except OSError as e :
@@ -494,8 +502,8 @@ def recv(self):
494502 return b""
495503 raise
496504
497- def sendall (self , data ) :
498- return self ._primary .write (data )
505+ def sendall (self , data : bytes ) -> None :
506+ self ._primary .write (data )
499507
500508
501509class MockGDBServer :
@@ -528,18 +536,21 @@ def stop(self):
528536 self ._thread .join ()
529537 self ._thread = None
530538
531- def get_connect_address (self ):
539+ def get_connect_address (self ) -> str :
540+ assert self ._socket is not None
532541 return self ._socket .get_connect_address ()
533542
534- def get_connect_url (self ):
543+ def get_connect_url (self ) -> str :
544+ assert self ._socket is not None
535545 return self ._socket .get_connect_url ()
536546
537547 def run (self ):
548+ assert self ._socket is not None
538549 # For testing purposes, we only need to worry about one client
539550 # connecting just one time.
540551 try :
541552 self ._socket .accept ()
542- except :
553+ except Exception :
543554 traceback .print_exc ()
544555 return
545556 self ._shouldSendAck = True
@@ -554,7 +565,7 @@ def run(self):
554565 self ._receive (data )
555566 except self .TerminateConnectionException :
556567 pass
557- except Exception as e :
568+ except Exception :
558569 print (
559570 "An exception happened when receiving the response from the gdb server. Closing the client..."
560571 )
@@ -587,7 +598,9 @@ def _parsePacket(self):
587598 Once a complete packet is found at the front of self._receivedData,
588599 its data is removed form self._receivedData.
589600 """
601+ assert self ._receivedData is not None
590602 data = self ._receivedData
603+ assert self ._receivedDataOffset is not None
591604 i = self ._receivedDataOffset
592605 data_len = len (data )
593606 if data_len == 0 :
@@ -640,10 +653,13 @@ def _parsePacket(self):
640653 self ._receivedDataOffset = 0
641654 return packet
642655
643- def _sendPacket (self , packet ):
644- self ._socket .sendall (seven .bitcast_to_bytes (frame_packet (packet )))
656+ def _sendPacket (self , packet : str ):
657+ assert self ._socket is not None
658+ framed_packet = seven .bitcast_to_bytes (frame_packet (packet ))
659+ self ._socket .sendall (framed_packet )
645660
646661 def _handlePacket (self , packet ):
662+ assert self ._socket is not None
647663 if packet is self .PACKET_ACK :
648664 # Ignore ACKs from the client. For the future, we can consider
649665 # adding validation code to make sure the client only sends ACKs
0 commit comments