ptrace
を使用して、自分のプログラムによって生成されたプログラムがどのシステムコールを呼び出すかを確認します。私はthis tutorialから始めました。答えは私のprevious questionです。マルチスレッドアプリケーションからのptraceの使用
#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;
}
それはかなりうまく機能:私は、生成されたプロセスが作る呼び出し、私は(SLES 11 64ビット)を使用しているプラットフォームにそれを適応させることによって、コードを修正し、一緒にすべてのシステムを出力し、次のテストコードを置きます:プログラムで作成されたシステムコールのIDを表示します(実際にはエントリに1回、終了時に1回、それぞれ2回ずつ出力しますが、今は関係ありません)。しかし、私のプログラムはシステムコールをチェックする以外のことをする必要があるので、別のスレッドにチェックを移すことにしました(私は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
が子プロセスによって開始されたスレッドをトレースしないことを発見しましたが、それは後で取り上げる必要があります。別のtheradから子プロセスをチェックすることさえ可能ですか?
他の奇妙なことは、私の実際のアプリケーションでは、基本的には同じことです(ただし、はるかに複雑なコンテキスト(クラス、mutexなど)からです)。 ptrace
がエラーで返される代わりに、wait
は子プロセスのシステムコールを返しません(子プロセスも停止しません)。一方、子プロセスが終了すると、wait
は期待どおりに動作します。
私のプロセスに専用のスレッドを持つことが助けになりました。 – petersohn