我想用ptrace
檢查什麼系統調用我的計劃催生了一個程序使得使用ptrace的。我從this tutorial開始,因爲它是在對我的previous question的回答中解釋的。我被它適應我使用的平臺修改代碼(SLES 11 64位),並放在一起打印出每一個系統下面的測試代碼中調用產生的進程,使得:從多線程應用程序
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/reg.h>
#include <sys/syscall.h> /* For SYS_write etc */
pid_t child;
void run()
{
long orig_eax;
int status;
while(1) {
int pid = wait(&status);
if (pid == -1) {
perror("wait");
kill(child, SIGKILL);
return;
}
printf("Got event from %d.\n", pid);
if(WIFEXITED(status))
break;
orig_eax = ptrace(PTRACE_PEEKUSER,
pid, 8 * ORIG_RAX, NULL);
if (orig_eax == -1) {
perror("ptrace");
kill(child, SIGKILL);
return;
} else {
printf("Syscall %ld called.\n", orig_eax);
}
ptrace(PTRACE_SYSCALL,
pid, NULL, NULL);
}
}
int main(int /*argc*/, char* argv[])
{
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl(argv[1], argv[1], NULL);
}
else {
printf("Child process id = %d.\n", child);
run();
}
return 0;
}
它工作得很好:它打印由程序進行的系統調用的ID(實際上它打印每個兩次,一次在入口處,一次用於退出,但現在無關緊要)。但是,除了檢查系統調用之外,我的程序還需要做其他事情,所以我決定將檢查移至單獨的線程中(我比C更適合使用C++,所以我使用C++方式,但是我不要以爲重要)。當然,在這個最新的程序中,我只啓動線程然後加入它。
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/reg.h>
#include <sys/syscall.h> /* For SYS_write etc */
#include <boost/thread.hpp>
pid_t child;
void run()
{
long orig_eax;
int status;
while(1) {
int pid = wait(&status);
if (pid == -1) {
perror("wait");
kill(child, SIGKILL);
return;
}
printf("Got event from %d.\n", pid);
if(WIFEXITED(status))
break;
orig_eax = ptrace(PTRACE_PEEKUSER,
pid, 8 * ORIG_RAX, NULL);
if (orig_eax == -1) {
perror("ptrace");
kill(child, SIGKILL);
return;
} else {
printf("Syscall %ld called.\n", orig_eax);
}
ptrace(PTRACE_SYSCALL,
pid, NULL, NULL);
}
}
int main(int /*argc*/, char* argv[])
{
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl(argv[1], argv[1], NULL);
}
else {
printf("Child process id = %d.\n", child);
boost::thread t(run);
t.join();
}
return 0;
}
這一次,我得到一個錯誤信息:
Child process id = 24682.
Got event from 24682.
ptrace: No such process
這是爲什麼?我試圖尋找答案,但沒有發現這樣的事情。我發現ptrace
不會跟蹤由子進程啓動的線程,但這是另一件事情需要以後處理。這甚至有可能從一個不同的戰場檢查孩子進程嗎?
另一個奇怪的是,我在實際應用中我做的基本上是同樣的事情(但是從一個更復雜的背景:類,互斥等),我也得到一個不同類型的錯誤。而不是ptrace
返回一個錯誤,wait
甚至不會返回子進程上的系統調用(並且子進程甚至不會停止)。另一方面,當子進程退出時,wait
按預期工作。
有一個專門的線程來處理我的幫助。 – petersohn