13.1 File-IO 概述

目标机可以使用宿主机的文件系统以及控制台IO来执行系统调用。

目标机上的系统调用被翻译成一个远程协议包到达宿主机,然后宿主机执行相应的操作,向目标系统返回处理结果。

gdb执行能够执行系统调用的条件:gdb在等待‘C’,‘c’,‘S’,‘s’的回复。

当gdb处理系统调用时,目标机停止,使得gdb能够访问目标机的内存。因此,FILE-IO是不能够被目标机的信号打断的。但是,用户可以通过在gdb端输入(crtl-c)来中断。

这句话的意思是,如果gdb在处理系统调用时,目标机是不能终止这个操作的,只能在宿主机上执行ctrl-c来终止

 (gdb) continue
       <- target requests 'system call X'
       target is stopped, gdb executes system call
       -> gdb returns result
       ... target continues, gdb returns to wait for the target
       <- target hits breakpoint and sends a Txx packet

意思是:如果在宿主机端执行c命令,此时,宿主机将等待目标机端的系统调用请求,然后gdb返回响应。然后目标机端继续执行直到命中断点。

系统调用只可能发生在gdb等待目标机执行‘c’命令或者‘s’命令的过程中。

gdb远程协议的实现过程:


1、如果远程链接已经建立,宿主机首先必须知道RSP协议支持的包的大小(qSupported)。(我们知道,最大的包就是‘G’命令),总共281个字节,即0x119.(PacketSize=119)。

2、然后宿主机询问目标机挂起的原因(?),此时目标机返回的一定不能是W(exit)或者X(terminated with signal)。通常情况下是trap异常。(S05)。

3、下来,宿主机向目标机发送(Hc-1),表明step/continue将用于所有进程。然后目标机返回(ok)

4、然后,宿主机发送(qC)命令,询问当前正在运行的进行号。如果当前还没有牵扯到进程的概念,则返回(empty)

5、宿主机发送(qOffsets)查询装载代码的offset。此时返回Text=0;Data=0;Bss=0;

6、此时,宿主机发送(Hg-1),表明后续操作适用于所有线程,然后,目标机返回(ok)

7、宿主机发送‘g’命令查询所有当前寄存器的值,然后,目标机返回相应的数据包。

下面我们来分析一下远程协议中的‘s’命令是怎么实现的。

在此例中,执行的是main()函数的第一条语句。

1、宿主机发送(s)命令,然后目标机返回(S05)。

2、然后宿主机发送(g)命令,目标机返回所有寄存器的值,如此重复。

3、然后使用m命令读取目标机上的内存。

总结,一个简单的gdb命令是对应着许多个远程协议命令的。