[英]How can I create a testing script with GDB
我有一组输入,我想用它们来测试我的程序,以便查看哪些输入会遇到断点。 我想创建一个脚本来一一测试这些输入,如果它达到断点,则将结果打印或保存到文件中。 请让我知道是否可能,如果是,我该怎么做。 谢谢你。
我不确定我是否完全理解你的要求。 但是如果我理解正确的话,你想编写一个程序:
我不知道这是否可以使用gdb
,但可以编写自己的调试器:
fork
和exec
函数之一(例如execlp
)启动要测试的程序exec
函数调用ptrace(PTRACE_TRACEME,0,0,0)
waitpid
; 如果exec
成功,程序将立即停止。 waitpid
返回的“状态代码”(第二个参数)将为 0x57F(假设为 x86 CPU)。waitpid
返回另一个退出代码,则exec
失败并且您无法继续。ptrace(PTRACE_PEEKTEXT,...)
和ptrace(PTRACE_POKETEXT,...)
修改程序:通过用“断点”指令替换该地址处的指令(在 x86 CPU 上: int3
这是字节0xCC
)ptrace()
将0xCC
写入每个地址。 因为PTRACE_POKETEXT
一次只能修改 4 个字节 (x86_32) 或 8 个字节 (x86_64),所以您首先必须使用PTRACE_PEEKTEXT
读取这 4 个或 8 个字节的旧值,修改 4 个或 8 个字节中的 1 个并写入所有 4 个或 8 个字节背部。PTRACE_PEEKUSER
):它应该是程序入口点的(实际)地址。ptrace(PTRACE_CONT,pid,0,0)
启动被测程序waitpid
等待程序停止或退出waitpid
返回 0x57F 作为“状态代码”,则您处于断点处。 您现在可以使用kill(pid, SIGKILL)
来停止您的程序。PTRACE_PEEKUSER
检查程序计数器的值(x86-64 上的rip
),以便您知道哪个断点被命中。 请注意,程序计数器可能是断点的地址加 1 ,因此如果在地址 0x12340000 处的断点被命中,则rip
可能是 0x12340001。waitpid
返回低字节 0x7F 的任何其他值,则程序导致异常。 您应该使用kill(pid,SIGKILL)
来最终停止它。waitpid
返回的低字节不是0x7F),程序就结束了,不会引发异常,也不会碰到任何断点。这里有一些示例代码:
int pid, code;
long tmpLong;
pid=fork();
if(!pid)
{
ptrace(PTRACE_TRACEME,0,0,0);
execlp("program_to_be_tested","program_to_be_tested",NULL);
exit(123);
}
waitpid(pid,&code,0);
if(code!=0x57F)
{
/* Starting the program failed ... */
}
else
{
/* Set breakpoints - here assuming x86-64 */
tmpLong=ptrace(PTRACE_PEEKDATA,pid,(void *)(address&~7),0);
((char *)&tmpLong)[address&7]=0xCC;
ptrace(PTRACE_POKEDATA,pid,(void *)(address&~7),(void *)tmpLong);
/* Continue the program */
ptrace(PTRACE_CONT,pid,0,0);
waitpid(pid,&code,0);
if((code&0xFF)!=0x7F)
{
/* Program did not hit a breakpoint
* and did not cause an exception */
}
else if(code==0x57F)
{
/* Breakpoint hit */
kill(pid,SIGKILL);
}
else
{
/* Program caused an exception */
kill(pid,SIGKILL);
}
}
要将输入传递给您的程序,您有两种可能的选择:
多次运行调试器:
echo "Input to be tested" | ./myDebugger
因为您的调试器不从 STDIN 读取,所以输入将传递给要测试的程序。
创建子进程时使用pipe
和dup2
:
... pipe(pipes); pid=fork(); if(!pid) { dup2(pipes[0],0); close(pipes[0]); close(pipes[1]); ... } close(pipes[0]); write(pipes[1],"Input to be sent to program", ...); ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.