From mboxrd@z Thu Jan 1 00:00:00 1970 From: Quality Quorum To: Andrew Cagney Cc: jtc@redback.com, gdb@sources.redhat.com Subject: Re: Current (non-) state of gdbserver Date: Fri, 13 Jul 2001 07:53:00 -0000 Message-id: References: <3B4DFE5D.6090403@cygnus.com> X-SW-Source: 2001-07/msg00131.html On Thu, 12 Jul 2001, Andrew Cagney wrote: > > > > Quality> It will be nice to add thread support rightaway. > > > > Indeed. All of these primitives need to be context/process/thread aware. > > > Starting at the frame we have: > > a frame has a thread > a thread has a target > > so a target could potentially manage one or more threads. > Makeing sense? Sounding good in theory? My thoughts (and experience) are summarized in the document below > > Andrew > Thanks, Aleksey ===================================================================== . A. Romanov The GDB Remote Serial Protocol Specification (rev 1.3) 0. Changes to Previous Version o Changes to versin 1.2 GDB internals does not allow for per thread break points on the stub side, spec reflects this sad truth. Cleaned up z-packet descriptions Added description of 'zz' packet. Restored acidently deleted 'writeSingleRegister'. Clarified length valuess in many instances. o Changes to version 1.1 Removed run-length encoding: queries can contain '*', so there is not way of reliable detection 'Z' protocol clarified: minimum amount of supported break points and error codes o Changes to version 1.0 Depreciated 'isThreadAlive' Fixed wrong descritpion of 'addBWPoint' and 'removeBWPoint' o Changes to version 0.4 Added 'waitForEvent', improved description of 'setControlThread' and 'setGeneralThread' o Changes to version 0.3 Expanded description of stub operating environment Fixed thread description Fixed signal range Split thread support into thread information and thread control Resurrected address part of continue and step signals, due to popular demand Added description of 'Z' and 'z' requests Added section on gdb side (self-) configuration. o Changes to version 0.2 Added section on backward compatibility. o Changes to version 0.1 Low case hex encoding is mandatory for byte arrays. Added section on signals. Added comment about retrying requests returned unexpected reply. Added 'restart', 'remoteCmd', 'rawQuery', 'userQuery' Dropped 'FromAddr' from all continue and step requests - it is not used by gdb anyway. Restructured description of optional elements. 1. Introduction This is a first attempt to formally specify the GDB Remote Serial Protocol (the protocol). This protocol is used by various gdb implementations to communicate with target resident software called stub over serial line or TCP stream. There is a well established way in making oneself familiar with the protocol by reading/porting/developing source code implementing both sides of the connection. However, it seems apparent that absence of formal specification negatively affects development and interoperability along with support for advanced features on the stub side. 2. Remote GDB Stub Execution Environment Let us start from describing environment where remote stub is executed. Threads comprising the system under debugging (the system) can have common data and text sections (e.g. embedded environments or user space threads), can share data segments only (e.g. Linux threads) and can have both data and text separate (e.g. Unix like processes). It seems that the only thread model which could be supported by gdb-4.18 is one with common data and text sections. In this case a stub is executed in exception handling context with all threads in the system stopped until stub receives a command from gdb to continue. Stubs optionally supports thread information functions allowing to retrieve inforamtion about threads: list, thread name and information strings, thread registers. It is highly desirable for this environment to support optional step operation. Break points are always not thread specific due to internal gdb limitations. When processor exception happens, stub enters 'exception entry state' where register operations are performed on registers associtated with stopped thread. 3. Data Types And Formats 3.1. Byte Arrays 3.1.1. Byte Array (ba) Byte array is used to transfer memory and register data and to send printable message to gdb console. It is encoded as a sequence of hex digits represented by ASCII characters [0-9a-f]. Each byte is represented by two characters with most significant nibble coming fist. In all cases order of bytes in the array are ordered in the byte order of the target. In all cases this stream is delimited by protocol elements represented by non-hex-digit characters. Character sequences of odd length or shorter than 2 are considered invalid. We will use 'ba' to designate protocol data in this format. This format is mandatory for both gdb and stub sides. Note: this specification required low case encoding. It is generally established practice so there are no compatibility problems here. 3.1.2. Partially Available Byte Arrays (bp) It is conceivable that in some system stub will not be able to access all registers requested by gdb. In this case unavailable bytes of byte array are encoded as 'xx'. This is the only difference between Byte Array and Partially available byte array. We will use 'bp' to designate protocol data in this format. Gdb never sends data in this format. Stub uses this format for register data only, unaccessible memory or other data should be reported as error condition or unsupported feature. This format is mandatory for gdb side. Note: this format is not supported by gdb-4.17 and earlier. 3.1.3. Binary Data Array (bx) The name tells all, this byte array is binary encoded with characters '$', '#' and 0x7d escaped by inserting 0x7d before them. Note: byte arrays require 8-bit clean communication channel. Stub never uses this format. Gdb uses it to speed up big downloads. We designate this format 'bx'. This format is optional for both gdb and stub sides. Gdb has a reliable way to detect whether this format is supported by stub. 3.1.4. String (ls) Stream of ASCII characters, the length is provided as a part of the message. We designate this format as (ls). It is mandatory on the gdb side, it is mandatory on stub size if Thread Info Query is implemented. 3.2. Integers GDB uses unsigned integers to convey information about address, length, register numbers, signals and other parameters. 3.2.1. Fixed Width Integers (0wx) These integers are encoded by sprintf(out_buf, "%0wx", value) or its equivalent (w is width). For example, signals are usually encoded as sprintf(out_buf, "%02x", value). GDB never uses this format to encode more than 32-bit unsigned integer and it never uses width greater than 8. This format is designated as '0wx', e.g. '08x'. This format is required on the gdb side, it is required on the stub side only if stub supports requests utilizing this format. 3.2.2. Normal Integers (x) These integers are encoded by sprintf(out_buf, "%Lx", value) or its equivalent. It acceptable to pad the output with zeros on the left. This format is used primarily to pass address, length and register number information. We designate this format as (x). This format is mandatory for both gdb and stub sides. Gdb will under no conditions will send anything more than 32-bit unsigned integer to the 32-bit stub. 64-bit stubs are interoperable with pre-5.0 implementations as long as they do not address memory beyond 4GB. 64-bit stubs with higher requirements should be debugged by gdb-5.0 or newer. 32-bit stubs are interoperable both with old and new implementations. 3.3. Threads Gdb allows stub to select its own way of identifying threads. It allocates 64-bit unsigned integers for thread representation. There is an internal restriction in current gdb implementations to use thread id below 0x80000000. Thread_id 0 should not be used, gdb reserves it to set special case of generic thread. Gdb also reserves threads 0xffffffff and 0xffffffffffffffff for its internal use. These values should never be seen on the wire. 3.3.1 Variable Length Tread_Id (vt) Thread id 0 is encoded as '0' in this format, all other threads are encoded by sprintf(out_buf, "%Lx", thread_id) or its equivalent. It is acceptable to pad values with zeros on the left, however, it is strongly discouraged. We designate this format 'vt'. This format is required on gdb side and it is required on the stub side if it supports threads. 3.3.2. Fixed Length Thread_Id (ft) Thread id 0 is never used in this format, all other threads are encoded as sprintf(out_buf, "%016Lx", thread_id) or its equivalent. The format is required on gdb side and it is required on the stub side it supports threads and thread query operations. 3.4. Signals Signals are unsigned integers with 1-255 range. They are always encoded by sprintf(out_buf, "%02x", signal) or its equivalent. Gdb follows standard Unix signal definitions and interpretation, normally both gdb and stub sides are aware about peer signal interpretation. We will not use format designation when describing signals. 3.5. Packet Formats Packet format is '$data#csum', where data is a sequence of ASCII characters, a csum is single byte checksum encoded as two hex digits. Receiver acknowledges properly received packet with '+' and corrupted packet with '-'. This packet format is mandatory for both gdb and stub side. Packet '$Xdata#csum' may contain non-ASCII data. This packet format is optional. Packet '$ss:data#csum' adds two byte sequence 'ss' to the picture, receiver acknowledges properly received packet with '+ss' and corrupted packet with '-'. This format is implemented by receivers but is not used by senders. Packet length is limited to 400 bytes, there are attempts to allow 400 bytes of data, there are number of bugs there, so the safe bet is to accept 407 bytes and never send more than 400 bytes for the whole packet. The only exception are cases where stub needs more than 400 bytes to to pack all its registers. Gdb has a reliable method to detect this case. Stubs supporting threads should be able to support packets of 1000 bytes. 4. Protocol Operations Protocol operations are asymmetric gdb side issues requests and stub side responds. There is only one unsolicited message defined so far, which could be sent by stub side. All elements are packed into ASCII encoded packet, unless noted otherwise. We will use '' notation to designate value 'v' in format 'f'. For example '' means address encoded in format 'x', described in section 3.2.2. Angle brackets are used as delimiters and are not part of the packet. For example, if we have format described as 'm,' then for address 0x1234 and length 0x20, the packet will look like '$m1234,20#c5'. Optional parts will be placed in square brackets, e.g. 'C[;]'. We will use '...' to designate optional more of the same. It seems reasonable for gdb side to retry operations which yielded unexpected response: simple checksum used in the protocol is not strong enough, however, combined with 3 retries it will be quite reliable to eliminate any spurious errors introduced by line noise. 4.1. Mandatory Elements There is a small but extremely powerful set of mandatory features. 4.1.1. Standard Responses o 'noSupport': tells gdb that last request is not supported. Format: Empty packet o 'error': tells gdb that last request caused some error. Format: EXX 'XX' could be anything and of any length: usually XX is two hex-characters or two 'N' characters. Gdb side considers any packet starting from 'E' an error indication. o 'ok': tells gdb that last request was successful Format: OK o 'statusString': there are four status string formats defined. Two of them are mandatory and two are optional in the sense that at least one of them of them should be implemented. Format: W system under debugging exited with status 'exit_status' Format: X system under debugging was terminated by signal 'signal' Format: S system under debugging was stopped by signal where signal is the value of signal or T:;...[thread:;] if thread is present, it means that thread identified by 'thread_id' was stopped by signal 'signal'. If thread is not present, it means that some thread was stopped by signal 'signal'. In all cases :; provide value 'reg_val' of a relevant register 'reg_no'. Note: 'thread' should not be present if threads are not supported by stub. o 'displayOutput': unsolicited message from the running system requesting to display the string on the gdb console. Format: O This one is mandatory only on gdb side. 4.1.2 Mandatory Requests Note: receiving something beyond reply listed below is considered fatal by gdb. For gdb side step support is a configuration time parameter. So, gdb assumes that target should support steps, then 'step' is mandatory. o 'getLastStatus': retrieve current status from the system Format: ? Reply: 'statusString' o 'readAllRegisters': retrieve data from all available registers Format: g Reply: Note: Register data are packed in the byte order of target. This is the only known use of format 'bx'. o 'writeAllRegisters': set registers Format: G Reply: OK Note: It is fine to have register_data, shorter than full register block. o 'readMemory': read memory Format: m, Reply: or 'error' Note: Memory data are packed in the byte order of the target. Gdb considers any error to be a memory access ones. Note: stub can return a smaller chunk of memory than was requested, it is a responsibility of the stub to ensure that response will fit into 400 bytes. Length could not be 0 and it could not be greater than 0x7fffffff, so stub implementors can safely use integer to hold it. o 'writeMemory': write memory Format: M,: Reply: 'ok' or 'error' Memory data are packed in the byte order of the target. Gdb considers any error to be a memory access ones. o 'continue': continue from current address Format: c Reply: 'statusString' Note: No reply until system will be stopped again by breakpoint, signal or interrupt from the debugger (if supported). Between request and response running system may issue unlimited number of 'displayString' messages. o 'step': step from current address Format: s Reply: 'statusString' Note: no reply until system will be stopped again by breakpoint, signal or interrupt from the debugger (if supported). Between request and response running system may issue unlimited number of 'displayString' messages. o 'kill' : kill request. in many cases it is no-op for embedded systems, it has to be supported because gdb does not expect any response in the case, hence it requires special attention. Format: k Reply: Note: No response indeed. If z-breaks are supported, stub have to remove all existing breakpoints And these are all mandatory requests, isn't it amazing ? 4.2. Optional Elements 'noSupport' or response listed below are fine, anything else is a fatal error. 4.2.1. Extended Operations Requests These requests should be either both supported or both unsupported. o 'setExtendedOps': Format: ! Reply: 'ok' or 'statusString' Note: accepting extended operation is a promise to honor 'restart' request. o 'restart': restart the system under debugging Format: r00 Reply: 'statusString' 4.2.2. Thread Information Requests These requests should be either all supported or all unsupported. It assumed that gdb issuing such request knows what it is doing and is able to accept long messages associated with 'threadInfoQuery' and 'threadListQuery'. o 'currentThreadQuery': get thread which is stopped Format: qC Reply: QC Notes: Gdb uses this request in order to figure out whether thread information is supported or not o 'threadInfoQuery': get information about specified thread Format: qP Reply: qQ[...] or 'error' Note: mask is or-ed combination of following the tags, each tag has its own meaning and value. tag value meaning 0x1 id of the thread 0x2 exists is 1 if thread exists 0x4 human readable info to display 0x8 name of the thread 0x10 more information to display o 'threadListQuery': suck a list of threads, starting from the first one if first is not 0, of from the thread after the arg_thread. Format: qL Reply: qM[...] or 'error' o 'setGeneralTrhead': registers and breakpoints will be related to this thread. Format: Hg Reply: 'ok' Note: It is a responsibility of a gdb side to ensure that thread being set does exist. This operation is not sticky: it will not survive over 'continue', 'step', 'waitForEvent' etc operations. "Hg0" is a switch to 'exception entry state': register operations are performed on registers of the stopped thread. 4.2.3. Other Optional Requests o 'writeSingleRegister': set single register Format: P= Reply: OK o 'continueFromAddr': continue from specified address Format: c Reply: 'statusString' Note: no reply until system will be stopped again by breakpoint, signal or interrupt from the debugger (if supported). Between request and response running system may issue unlimited number of 'displayString' messages. o 'continueWithSignal': continue with signal delivered, if address is not specified it will continue from current address Format: Csig[;] Reply: 'statusString' Note: no reply until system will be stopped again by breakpoint, signal or interrupt from the debugger (if supported). Between request and response running system may issue unlimited number of 'displayString' messages. o 'stepFromAddr': step from address Format: s Reply: 'statusString' Note: no reply until system will be stopped again by breakpoint, signal or interrupt from the debugger (if supported). Between request and response running system may issue unlimited number of 'displayString' messages. o 'stepWithSignal': step with signal delivered, if address not specified it will start from current address. Format: Ssig[;] Reply: 'statusString' Note: no reply until system will be stopped again by breakpoint, signal or interrupt from the debugger (if supported). Between request and response running system may issue unlimited number of 'displayString' messages. o 'offsetsQuery': get offsets of program segments Format: qOffsets Reply: Text=;Data=;Bss= o 'crcQuery': get CRC32 of specified memory area Format: qCRC:, Reply: 'error' or C Note: Gdb considers any error to be memory access one. Length could be really big here. o 'writeSingleRegister': write single register Format: P= Reply: 'ok' o 'writeMemoryBin': use binary format to write memory Format: X,: Reply: 'ok' or 'error' Note: Memory data are packed in the byte order of the target. Gdb considers any error to be a memory access ones. Length could not be 0 and it could not be greater than 0x7fffffff, so stub implementors can safely use integer to hold it. o 'remoteCommand': send command to the stub and print out out on the console Format: qRcmd, Reply: sequence of zero or more 'displayString' packets, zero or more packets terminated by 'ok' or 'error' o 'addBWPoint': add break/watch-point Format: Z,, type: 0 - add software breakpoint, at address, length is the number of bytes to be replaced. type: 1 - add hardware break point at address, length is the length of breakpoint. type: 2 - add read watchpoint for address, length combination. type: 3 - add write watchpoint for address, length combination. type: 4 - add access watchpoint for address, length combination. Reply: 'ok' or 'error' if out of resources Note: 'noSupport' means that particular type is not supported, for example target can support software break points and not support hardware break points. Amount of possible hardware break/watch points is usually detemined by the target type and is known by the gdb. Gdb can theoretically set unlimited number of software break points. Any `non-special-case' stub has to have capacity to set 1024 software break points. It is expected that gdb side is always informed about `special-case' limitations either through target configuration or through user input. Length should match stub expectations. For example, i386-stub expects type 0 length to be 1. o 'removeBWPoint': remove break point Format: z,, type: 0 - remove software breakpoint, at address, length is the number of bytes to be replaced. type: 1 - remove hardware break point at address, length is the length of breakpoint. type: 2 - remove read watchpoint for address, length combination. type: 3 - remove write watchpoint for address, length combination. type: 4 - remove access watchpoint for address, length combination. Reply: 'ok' or 'error' if there is no such break. o 'removeAllBWPoints': remove all break points Format: zz Reply: 'ok' Note: removes all currently inserted break point. It is supposed to be issued at the very beginning of the new session. 4.2.4. Proposed Optional Elements o 'rawQuery': a mechanism to extend current protocols Format: qz[] Reply: QZ[] or 'ok' or 'error' Note: ids are assigned by new versions of GDB protocol specs o 'userQuery': a mechanism to provide user specific extensions Format: qu[] Reply: QU[] or 'ok' or 'error' Note: It is similar to qRcmd, however, it is expected that Rcmd will interpreted mostly by user, and this response will be interpreted by interpreted by local gdb extensions 4.2.5. Depreciated Elements o 'isTheadAlive': check whether thread in question still exist Format: T Reply: 'ok', 'error' Note: 'ok' means alive, 'error' means not alive. This command is depreciated recently, however, a lot of gdbs will still emit it. Who cares ? Just make sure that gdb will never send a depreciated request. 4.2.5. Obsolete Elements Who cares ? 5. Backward Compatibility Issues 5.1. Old Gdb and New Stub This is a less important issue, it seems reasonably simple for anybody to update gdb. Moreover, it seems like there are not going to be any interoperability problems between new stubs and pre-4.19 gdbs. Note: all pre-4.18 gdbs are not able to process partially available byte arrays (bp). 5.2. New Gdb and Old Stub