2019-04-22 19:44:45 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
2019-05-02 16:51:39 +03:00
|
|
|
#include <string.h>
|
|
|
|
#include <signal.h>
|
2019-04-22 19:44:45 +03:00
|
|
|
#include <AK/Assertions.h>
|
|
|
|
#include <AK/Types.h>
|
|
|
|
#include <Kernel/Syscall.h>
|
|
|
|
|
2019-05-02 16:51:39 +03:00
|
|
|
static int usage()
|
|
|
|
{
|
|
|
|
printf("usage: strace [-p PID] [command...]\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-22 19:44:45 +03:00
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
2019-05-02 16:51:39 +03:00
|
|
|
if (argc == 1)
|
|
|
|
return usage();
|
|
|
|
|
|
|
|
pid_t pid = -1;
|
|
|
|
bool pid_is_child = false;
|
|
|
|
|
|
|
|
if (!strcmp(argv[1], "-p")) {
|
|
|
|
if (argc != 3)
|
|
|
|
return usage();
|
|
|
|
pid = atoi(argv[2]);
|
|
|
|
} else {
|
|
|
|
pid_is_child = true;
|
|
|
|
pid = fork();
|
|
|
|
if (!pid) {
|
|
|
|
kill(getpid(), SIGSTOP);
|
|
|
|
int rc = execvp(argv[1], &argv[1]);
|
|
|
|
if (rc < 0) {
|
|
|
|
perror("execvp");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ASSERT_NOT_REACHED();
|
|
|
|
}
|
|
|
|
}
|
2019-04-22 19:44:45 +03:00
|
|
|
|
|
|
|
int fd = systrace(pid);
|
|
|
|
if (fd < 0) {
|
|
|
|
perror("systrace");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-05-02 16:51:39 +03:00
|
|
|
if (pid_is_child) {
|
|
|
|
int rc = kill(pid, SIGCONT);
|
|
|
|
if (rc < 0) {
|
|
|
|
perror("kill(pid, SIGCONT)");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-22 19:44:45 +03:00
|
|
|
for (;;) {
|
|
|
|
dword call[5];
|
|
|
|
int nread = read(fd, &call, sizeof(call));
|
|
|
|
if (nread == 0)
|
|
|
|
break;
|
|
|
|
if (nread < 0) {
|
|
|
|
perror("read");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
ASSERT(nread == sizeof(call));
|
2019-05-02 16:51:39 +03:00
|
|
|
fprintf(stderr, "%s(%#x, %#x, %#x) = %#x\n", Syscall::to_string((Syscall::Function)call[0]), call[1], call[2], call[3], call[4]);
|
2019-04-22 19:44:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int rc = close(fd);
|
|
|
|
if (rc < 0) {
|
|
|
|
perror("close");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|