首页 > 其他分享 >GDB Remote Serial Protocol —— RSP协议解析

GDB Remote Serial Protocol —— RSP协议解析

时间:2022-11-01 14:56:05浏览次数:51  
标签:Remote 响应 eg 目标 命令 GDB 寄存器 Protocol

简介

   这篇文章翻译看看也是不错的

      https://tatsuo.medium.com/implement-gdb-remote-debug-protocol-stub-from-scratch-3-e87a697ca48c

 

      GDB Remote Serial Protocol——GDB的标准远程通信协议。

       当你已经熟悉你的处理器是如何处理断点和其他异常时,再了解一点基本的远程穿行通信协议的知识,你就可以在你的嵌入式平台上实现与主机GDB的通信。(即远程调试)

   

协议定义

        GDB RemoteSerial Protocol(RSP)是一种简单的,通过串口线、网络等至少支持半双工通信的媒介进行ASCII消息传输的协议。

        RSP包以$符号作为数据包的开始,后跟一个或多个用于组成要发送的消息的ASCII字节,并以#作为数据包的结束。再#后,还有两个16进制的ASCII字符作为要发送的消息的校验和。一个完整的RSP协议数据包如下:

$m4015bc,2#5a

        消息的接收方会立即返回‘+’表示正确接收数据,或‘-’表示没有正确接收数据。当返回‘-’时,GDB会将错误码返回给用户,并无条件挂起GDB进程。

目标机按接收到的指令次序,依次将信息输出在GDB的console中。除非GDB进程中有其他的命令正在执行,否则来自目标机的信息将会在任意时刻输出在console中。

RSP必须实现的命令

       根据功能划分,可将GDB发送来的信息,分成三种命令:寄存器相关(register-)、内存相关(memory-based)和程序控制命令。

寄存器相关

       主要是对寄存器进行读、写操作。

     读寄存器组:(“g”)

       eg:$g#67

       当GDB想获取当前目标机的寄存器信息时,就会像目标机发送(“g”)命令,目标机会返回如下信息:

       +$123456789abcdef0…#xx

       (Register 0 的值为0x12345678,1 的值为0xabcdef0….等等)

       目标机根据平台的大小端返回相应的字节流,关于大小端的定义,可以在目标平台的gdb宏文件中找到,eg:gdb/config/<arch>tm-<arch>.h (不同版本可能不一样,我就没找到)

     写寄存器组:(“G”)

       eg:$G123456789abcdef0…#xx

     (设置register0 的值为0x12345678,1 为 0xabcdef0…等等)

       使用这个命令,GDB会在程序恢复运行前,按照平台的字节序将数据存储在相应的寄存器中。同时目标平台也会回应给GDB反馈信息,如成功返回+$OK#9a。

     写寄存器:(“P”)

       eg:$p10=0040149c#b3

     (设置16号寄存器的值为0x40149c)

       当GDB仅仅想设置一个或二个寄存器时,GDB会发送这条指令(代替(“G”)命令)给目标机。寄存器的号与读写寄存器组的号是一样的。同时,若成功,目标机会返回+$OK#9a。

内存相关

      读内存:(“m”)

        eg: $4015bc,2#5a

       (从0x4015bc这个地址开始读2个字节的数据)

        GDB发送的读命令会确定局部变量和全局变量的值,并用断点指令替代opcode,及其他用户需要的信息。GDB是知道目标平台的大小端的,因此目标机只需返回字符流即可,GDB会适当的对它们进行重组。

        目标机的调试桩根据目标机的数据宽度对读写内存指令进行了优化,例如日立SH-2处理器的外设配置寄存器只能通过16位/32位进行读写。因此,在任何时刻,调试桩都只用16位/32位进行访问。目标机会返回如下信息:

        +$2f86#-06

      写内存:(“M”)

        eg:M4015cc,2:c320#6d

      (向地址0x4015cc写入数据0xc320)

  

        如果正确,目标机返回+$OK#9a。

程序控制命令

  

        程序控制命令是GDB用来控制被调试程序行为的命令。相对寄存器相关命令和内存相关命令,控制命令的实现难度大些。

      获取最后的信号(“?”)

        eg:$?#3f

        这个命令用来确定目标是如何达到当前的状态的。接收到的响应同最后的信号(“last signal”),后面会介绍。

      单步命令(“s”)

        eg:$s#73

        当GDB想让目标精确的执行一条汇编指令时,GDB会向目标机发送这条命令。(用户在GDB的console中输入step和stepi),接收到的响应见continue。

      继续命令(“c”)

        eg:$C#63

        当用户在console下执行continue命令时,GDB回向目标机发送此命令。目标机成功解析此命令后,GDB会释放控制权,使被调试目标机全速运行。

   

        调试桩除了返回“+”消息包,表示正确收到信息外,不会立即响应step和continue命令。相反,只有当下一个断点到达时,被请求的指令已经执行完(ste,p时的情况),一个异常发生,或者程序退出时,桩才进行响应。

        有两种方式响应这些命令:一种是简单的(“last signal”),另一种是多用途的(“expedited response”)。

 

      Last Signal 响应(“S”)

        eg:+$050#b8

        这是最简单的响应lastsignal(“?”)step和continue命令。“05”可以用作使用POSIX标准的signal函数的任意信号值的响应。“5”是断点异常,“10”是总线错误,等等。

      快速响应(Expeditedresponse (“T”))

        eg:$T0510:1238;F:FFE0…#xx

        这条信息将最后的信号响应(例子是“05”)和一些GDB可能立刻会读取的寄存器进行结合。为了在代码单步执行时,提高GDB调试性能,这条信息使GDB直接获取该寄存器的值(通常是PC和状态寄存器),避免发出读寄存器的命令。

        寄存器号的格式与读写寄存器命令相同。在这个例子中,寄存器16(hex 10)的值是0x1238,寄存器15(F hex)的值为0xffe0。

其他命令:

 

      Console 输出(“O“)——可自定义的

        eg:$0x48656c6cf2c20776f726c64210a#55

       (在GDB console中输出“Hello, world!\n“)

        这个命令允许调试桩向GDBconsole发送文本信息。文本会被按照16进制显示在console中,并且GDB会一直输出信息,直到它遇到(‘\n’, 0xa)字符。

        这个信息通常是由目标机发起,GDB绝不会发送一个console output信息给目标机。

 

      空响应(““)

        当目标机调试桩遇见一个它不支持或不理解的命令时,它将返回空响应。这允许GDB选择一个替代命令如果另一个命令是有效的。

        eg:<an unrecognized command>

        目标机响应:+$#00

      错误响应(“E“)

        当目标机调试桩在执行命令时遇到一个错误时,它将会给GDB返回错误信息。例如总线错误或进行非法地址访问时,会生成这样的错误。

        eg:<a command that produces an error>

 

      目标机响应:+$E01##

        在GDB中没有任何预定义的错误码,因此当GDB接收到错误信息时,会将错误信息输出在console中,并且挂起当前进程。

标签:Remote,响应,eg,目标,命令,GDB,寄存器,Protocol
From: https://www.cnblogs.com/cfas/p/16847682.html

相关文章

  • C语言: GDB调试技术(一)
    启动GDB的方法有以下几种:1、gdb<program>program也就是你的执行文件,一般在当然目录下。’例如我写了一个简单的helloword程序#include<stdio.h>intmain(){inta=1;......
  • C语言:---gdb多线程调试
    1)恢复程序运行和单步调试当程序被停住了,你可以用continue命令恢复程序的运行直到程序结束,或下一个断点到来。也可以使用step或next命令单步跟踪程序。continue[ignore-coun......
  • C语言: ---gdb查看内存和寄存器内容
    gdb没有CodeWarrior强大,但是也提供了查看寄存器的命令:(gdb)inforegisterr1r1            0xbffffb40   3221224256(gdb)inforegistersr0     ......
  • GDB全过程详细讲解
    摘自:https://blog.csdn.net/guo_lei_lamant/article/details/83787730 4.堆栈查看调用堆栈(callstack)无疑是调试过程中非常重要的事情。(gdb)where#查看调用堆栈......
  • gdb 查看函数调用堆栈(frame概念)
    摘自:https://www.cnblogs.com/xiaoshiwang/p/12893748.html1,使用bt(backtrace)命令查看当前堆栈(gdb)bt#0muduo::Poller::poll(this=0x62e010,timeoutMs=10000,......
  • GDB 备忘
    objdump-dtarget反编译targetgdbtarget开始调试targetr(run)运行b(break)funName在函数funName处设置断点b0x000001在地址0x000001处设置断点i(info)b显示......
  • gdb
    断点设置断点break+offsetbreak-offset(在当前行号的前面或后面的offset行停住。)breakfilename:linenum在源文件filename的linenum行处停住。breakfilename:func......
  • remote: HTTP Basic: Access denied. The provided password or token is incorrect o
    具体错误:$gitpush--set-upstreamoriginquantum6remote:HTTPBasic:Accessdenied.Theprovidedpasswordortokenisincorrectoryouraccounthas2FAenabled......
  • gdb调试基本操作
    38P-gdb调试基础指令使用gdb之前,要求对文件进行编译时增加-g参数,加了这个参数过后生成的编译文件会大一些,这是因为增加了gdb调试内容gdb调试工具:大前提:程序是你自己写的......
  • gdb usage
    gdbusageattachprocessgdbattach$pid查看进程内的所有线程infothread切换跟踪线程thread$thread_id  #此thread_id为infothread结果行首的threadid查看......