大运天成赖搏击

进步最重要

导航

gdb+gdbserver远程串行协议[zz]

转载地址:http://blog.sina.com.cn/s/blog_71ed04f70100qhxc.html

 

gdbserver --debug --remote-debug /mount/hello
Usage:  gdbserver [OPTIONS] COMM PROG [ARGS ...]
        gdbserver [OPTIONS] --attach COMM PID
        gdbserver [OPTIONS] --multi COMM

COMM may either be a tty device (for serial debugging), or
HOST:PORT to listen for a TCP connection.

Options:
  --debug               Enable general debugging output.
  --remote-debug        Enable remote protocol debugging output.
  --version             Display version information and exit.
  --wrapper WRAPPER --  Run WRAPPER to start new programs.
[root@GX3200 /]# gdbserver --debug --remote-debug :3456 /mount/hello
my_waitpid (474, 0x0)
my_waitpid (474, 0x0): status(137f), 474
my_waitpid (474, 0x0)
my_waitpid (474, 0x0): status(1057f), 474
my_waitpid (475, 0x0)
my_waitpid (475, 0x0): status(137f), 475
my_waitpid (475, 0x0)
my_waitpid (475, 0x0): status(9), 475
my_waitpid (474, 0x0)
my_waitpid (474, 0x0): status(117f), 474
my_waitpid (474, 0x0)
my_waitpid (474, 0x0): status(9), 474
new_argv[0] = "/mount/hello"
Process /mount/hello created; pid = 476
sigchld_handler
linux_wait: [Process 476]
linux_wait_for_lwp: <all threads>
my_waitpid (-1, 0x40000000)
my_waitpid (-1, 0x1): status(57f), 476
Got an event from 476 (57f)
stop pc is 400009c0
pc is 0x400009c0
stop pc is 0x400009c0
stop pc is 400009c0
linux_wait_for_lwp: pc is 0x400009c0
Hit a non-gdbserver trap event.
wait_for_sigstop: LWP 476 already stopped
Checking whether LWP 476 needs to move out of the jump pad...no
linux_wait ret = LWP 476.476, 1, 5
Listening on port 3456
handling possible accept event
Remote debugging from host 192.168.1.224
linux_async (0), previous=0
handling possible serial event
[getpkt: discarding char '+']
getpkt ("Hc-1");  [sending ack]
[sent ack]
putpkt ("$E01#a6"); [looking for ack]
[received '+' (0x2b)]
handling possible serial event
getpkt ("qC");  [sending ack]
[sent ack]
putpkt ("$QC1dc#8c"); [looking for ack]
[received '+' (0x2b)]
handling possible serial event
getpkt ("qOffsets");  [sending ack]
[sent ack]
putpkt ("$#00"); [looking for ack]
[received '+' (0x2b)]
handling possible serial event
getpkt ("?");  [sending ack]
[sent ack]
wait_for_sigstop: LWP 476 already stopped
Checking whether LWP 476 needs to move out of the jump pad...no
Writing resume reply for LWP 476.476:1

putpkt ("$T050b:0*"00;0d:403ea0be;0f:c0090040;thread:1dc;core:0;#f7"); [looking for ack]
[received '+' (0x2b)]
handling possible serial event
readchar: Got EOF
[getpkt: discarding char 'ÿ']
Remote side has terminated connection.  GDBserver will reopen the connection.
Listening on port 3456

===========================================================================================

gdb规定目标端起码应该实现:’g’ ‘G’ ‘m’ ‘M’ ‘c’ ’s’,kgdb当然也有实现了,而且还不
止这些,有一些是和体系结构没有太紧密的关系,比如断点的设置和删除,kgdb只是记录
起这个地址,和设置这个断点的状态;内存的读取和修改,也许这个和体系结构有关,但是
具体实现内核已经搞定,kgdb不用关心。另外一方面一些比如’s’单步执行这种命令就和体
系结构关系十分密切,x86上是通过设置标志寄存器的Trap标记,让cpu运行完下一条指令
后触发一个debug中断,其他的体系结构的做法都有所不同。

‘g’
格式:$g#67
描述:gdb向目标端发送这个命令来获取目标机当前寄存器的值
回复:+ $123456789abcdef0…#xx
‘+’用来应答’g'这个命令,表明目标端正确地收到这个命令,然后就是目标端的回复包,
gdb规定用8十六进制个数字来表示一个寄存器的值,所以第一个寄存器的值为
12345678,第二个为9abcdef0,依此类推,而具体每个寄存器的含义和寄存器个数又体系
结构决定,定义在gdb的代码中. 当然这里8个数字是对32位系统来说的,为什么是8位?
限于我们这个协议是基于ASCII的,一个十六进制数只能标记4位,那32位自然是8个十六进制数了。

‘G’
格式:$GXXXXXXXXXXX…#xx
描述:和g相反,这个命令用来设置目标机当前寄存器的值
回复: + $OK#9a
OK表示设置成功,后面我们会讲到不成功的情况.

‘m’
格式:$m6a1bbb,2#b9
描述:读取一段内存的值,这里是读取以6a1bbb位起始地址的两个字节
回复: + $f488#0a 目标端把值返回.

‘M’
格式:$Mccc5cc,2:a340#01
描述:设置一段内存的值,这里是把以ccc5cc位开始地址的两个字节设成a340
回复: + $OK#9a

’s’
格式:$sADDR#xx
描述:用户进行单步调试时用到,ADDR指明了程序将从那个地址恢复运行,如果忽略ADDR,程序就从断点处继续运行.
回复:+ 目标端会马上返回数据正确或错误接收,但不会马上返回信息,具体信息要到下一次断点被触发时才会返回.下面会提到.

‘c’
格式:$cADDR#xx
描述:让程序恢复正常运行
回复:和’s’一样.

‘Z’
格式: $ZTADDR,LENGTH#xx
‘Z’命令用来设置断点或watch点,用过gdb的同志应该不会陌生了
‘T’字段定义了这个命令的对象,0:软件断点,1:硬件断点,2:写watch点,3:读watch点,4:访问watch点.
‘ADDR’就是我们所关心的内存地址,’LENGTH’,对于软件中断它指明被断点指令覆盖
的内存长度,kgdb对于软件断点忽略掉它,因为触发 kgdb的指令与体系结构相关,已经定义
在kgdb这边,就如x86的int3在内存里面的二进制指令为”0xcc”;对于硬件断点和watch 点,
‘LENGTH’指明gdb关注的内存长度.

‘z’
格式: $zTADDR,LENGTH#xx
各项与’Z'相同.用来取消断点。

回复:
错误回复:
格式:+ $E01#a6
描述:如果目标端在执行gdb的命令时出错时返回错误回复,比如访问内存时出错.E后面根
两位的错误码,错误码在gdb里面没有定义,没有定义其实更加方便,可以让开发端和目标端
对错误码的使用带来灵活.

空回复:
格式:+ $#00
描述:当目标端不认识gdb发来的命令时,返回空回复表示自己不支持这个命令.

对’c',’s’的回复:
有好几种对’c',’s’的回复,其中比较常见的是’S'和’T’
‘S’
格式: $SAA#b8
作用: AA表明触发这次通信的那个异常相关的信号,这个信号就是posix标准中的信号.

‘T’
格式: $TAAN..:R..;N..:R..#xx
作用: AA同样是信号号, N..:R.. 这表明一个寄存器和它的值,N标记寄存器号,R是它对应的
值,其中,如果N不是一个16进制数而是”thread”,那么后面R的值就指明当前的进程号.如果
是其它的字符串gdb会省略.

Kgdb在回复’s’,'c’时选用了’T'的方式,不过在’T'消息里面只有thread一个字段,没
有给gdb传更多的寄存器信息.

posted on 2013-03-01 15:27  linucos  阅读(1186)  评论(0编辑  收藏  举报