[英]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.