我正在編寫一個監視系統調用(除其他外)的程序。但是我在使用ptrace識別我傳遞給它的進程ID方面遇到了一些麻煩。在執行程序中,我得到這個錯誤信息:PTrace無法識別子進程
:No such process
但是,我已經將它打印到控制檯,並ps -all
驗證它在調用之前正確驗證的進程ID。
下面是一些代碼,可能是相關的(我可以發佈更多,如果需要的話):
標題子進程:
/* Call to be traced */
if (ptrace (PTRACE_TRACEME, 0, 0, 0) < 0){
perror ("Process couldn't be traced");
exit (-1);
}
/* Execute process image */
if (execv (ProcessArgs[0], &ProcessArgs[1]) < 0){
perror ("Couldn't execute process");
exit (-1);
}
在父進程的線程:
DbgdProcess * _Process = (DbgdProcess *) _ProcessPass;
int SystemCall = 0,
Status = 0;
/* I have tried sleep(1) here to wait for PTRACE_ME to no avail */
while (!_Process->CloseSignal){
if (wait (&Status) < 0) // error handler
if (WIFEXITED (Status)) // error handler
if (!WIFSTOPPED (Status)) continue;
SystemCall = ptrace (PTRACE_PEEKUSER, _Process->ID, 4 * ORIG_RAX, 0);
if (SystemCall < 0) // error handler
printf ("Process made system call %d\n", SystemCall);
if (ptrace (PTRACE_CONT, _Process->ID, 0, 0) < 0) // error handler
}
有人可以向我解釋這種行爲嗎?
一些額外的注意事項:
- 正在調試的進程是父的直接子
- 我敢肯定,這是一個64位編譯因爲SYS/reg.h只定義RAX
- 所有錯誤處理程序包括PERROR()消息
更新:
我已經從該名男子頁閱讀:
大多數ptrace的命令(除了PTRACE_ATTACH,PTRACE_SEIZE, PTRACE_TRACEME,PTRACE_INTERRUPT和PTRACE_KILL)要求tracee 是在ptrace的停止,否則他們ESRCH失敗。
ESRCH,我相信,給出的消息'沒有這樣的過程'。所以,當我進行ptrace調用時,這個過程可能不會被ptrace停止?
更新:
我在這個example測試代碼。我沒有得到它做下列工作後: - 從一個 更新數據庫頭 - 改變(eax_orig * 4)(rax_orig * 8)
但是這些變化,以及,在我的程序和它的還是行不通。
更新:
我有我的代碼工作。我不完全確定爲什麼,但是在使用ptrace(2)進行輪詢調用的同一線程中調用PTRACE_ATTACH後,它開始工作。我想這意味着ptrace必須在父進程的同一線程中使用,但我不完全確定。我現在的問題是,有人知道這是真的嗎?或者,如果沒有,爲什麼ptrace以這種方式表現?
更新:
我發現這個link,這似乎表明我的問題是不是聞所未聞的。
我已經更新了我的答案,是的,我相信ESRCH是我得到的錯誤 – tay10r
爲什麼你有這條線-if(!WIFSTOPPED(狀態))繼續;? 家長應該被阻止,直到它收到來自孩子的信號。 –
我認爲它會確保在調用ptrace之前停止進程。無論如何,我想我已經找到了問題(我已經更新了我的問題)。 – tay10r