mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-29 11:00:29 +00:00
2a65f0ee4f
Tracing a specific pid is now done via "strace -p PID". To ensure we don't miss any syscalls, we fork and have the child immediately SIGSTOP itself. Then when the parent has set up the systrace() fd, we send SIGCONT to the child which then execs the command. :^)
76 lines
1.6 KiB
C++
76 lines
1.6 KiB
C++
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <AK/Assertions.h>
|
|
#include <AK/Types.h>
|
|
#include <Kernel/Syscall.h>
|
|
|
|
static int usage()
|
|
{
|
|
printf("usage: strace [-p PID] [command...]\n");
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
|
|
int fd = systrace(pid);
|
|
if (fd < 0) {
|
|
perror("systrace");
|
|
return 1;
|
|
}
|
|
|
|
if (pid_is_child) {
|
|
int rc = kill(pid, SIGCONT);
|
|
if (rc < 0) {
|
|
perror("kill(pid, SIGCONT)");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
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));
|
|
fprintf(stderr, "%s(%#x, %#x, %#x) = %#x\n", Syscall::to_string((Syscall::Function)call[0]), call[1], call[2], call[3], call[4]);
|
|
}
|
|
|
|
int rc = close(fd);
|
|
if (rc < 0) {
|
|
perror("close");
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|