mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:32:45 +00:00 
			
		
		
		
	strace: Allow "strace command" to trace a process from start to finish.
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. :^)
This commit is contained in:
		
							parent
							
								
									25ddcd1022
								
							
						
					
					
						commit
						2a65f0ee4f
					
				
					 1 changed files with 40 additions and 4 deletions
				
			
		|  | @ -1,22 +1,58 @@ | |||
| #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 < 2) | ||||
|         return 1; | ||||
|     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 pid = atoi(argv[1]); | ||||
|     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)); | ||||
|  | @ -27,7 +63,7 @@ int main(int argc, char** argv) | |||
|             return 1; | ||||
|         } | ||||
|         ASSERT(nread == sizeof(call)); | ||||
|         printf("%s(%#x, %#x, %#x) = %#x\n", Syscall::to_string((Syscall::Function)call[0]), call[1], call[2], call[3], call[4]); | ||||
|         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); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling