2013-05-27 82 views
1

我正在編寫一個監視系統調用(除其他外)的程序。但是我在使用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,這似乎表明我的問題是不是聞所未聞的。

回答

0

睡覺(1)有時候是不夠的;嘗試睡眠(5)。

0

爲什麼要在檢查進程是否停止之前做了PTRACE_SYSCALL?

理想情況下,在父線程中,您應該等待孩子通過使用等待來停止。

一旦孩子以WIFSTOPPED停止,那麼只能使用任何其他的ptrace調用。

看起來ESTRCH由PTRACE_SYSCALL返回。你能確認嗎

+0

我已經更新了我的答案,是的,我相信ESRCH是我得到的錯誤 – tay10r

+0

爲什麼你有這條線-if(!WIFSTOPPED(狀態))繼續;? 家長應該被阻止,直到它收到來自孩子的信號。 –

+0

我認爲它會確保在調用ptrace之前停止進程。無論如何,我想我已經找到了問題(我已經更新了我的問題)。 – tay10r