(root)/
strace-6.5/
tests-mx32/
strace--decode-pids-comm.c
       1  /*
       2   * Test -Y/--decode-pids=comm option.
       3   *
       4   * Copyright (c) 2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  /*
      11   * The executable built from this source file should
      12   * have a long name (> 16) to test how strace reports
      13   * the initial value of /proc/$pid/comm.
      14   * Even if linux returns a longer name, strace should
      15   * not crash.
      16   */
      17  
      18  #include "tests.h"
      19  #include "scno.h"
      20  
      21  #include <errno.h>
      22  #include <signal.h>
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <string.h>
      26  #include <sys/prctl.h>
      27  #include <unistd.h>
      28  #include <sys/types.h>
      29  #include <sys/wait.h>
      30  
      31  #define NEW_NAME "0123456789abcdefghijklmnopqrstuvwxyz"
      32  
      33  static int
      34  do_default_action(void)
      35  {
      36  	static const char proc_self_exe[] = "/proc/self/exe";
      37  	skip_if_unavailable(proc_self_exe);
      38  
      39  	char comm[sizeof(NEW_NAME)];
      40  	if (prctl(PR_GET_NAME, comm))
      41  		perror_msg_and_skip("PR_GET_NAME");
      42  	char ocomm[sizeof(comm)];
      43  	strcpy(ocomm, comm);
      44  
      45  	pid_t pid  = getpid();
      46  	pid_t ppid = getppid();
      47  
      48  	printf("%u<%s> getppid() = %d<%s>\n", pid, comm, ppid, "strace");
      49  	fflush(stdout);
      50  
      51  	pid_t child = fork();
      52  	if (child < 0)
      53  		perror_msg_and_fail("fork");
      54  	else if (child == 0) {
      55  		pid = getpid();
      56  		ppid = getppid();
      57  		printf("%u<%s> getppid() = %d<%s>\n", pid, comm, ppid, ocomm);
      58  
      59  		const char *names[] = {
      60  			"foo\33[2Jbar",
      61  			"foo<bar>",
      62  			NEW_NAME,
      63  		};
      64  		for (size_t i = 0; i < ARRAY_SIZE(names); ++i) {
      65  			strcpy(comm, names[i]);
      66  			prctl(PR_SET_NAME, comm);
      67  			prctl(PR_GET_NAME, comm);
      68  
      69  			ppid = getppid();
      70  			printf("%u<", pid);
      71  			print_quoted_memory_ex(comm, strlen(comm), 0, "<>");
      72  			printf("> getppid() = %d<%s>\n", ppid, ocomm);
      73  
      74  			long rc = syscall(__NR_tgkill, pid, pid, SIGCONT);
      75  			printf("%u<", pid);
      76  			print_quoted_memory_ex(comm, strlen(comm), 0, "<>");
      77  			printf("> tgkill(%d<", pid);
      78  			print_quoted_memory_ex(comm, strlen(comm), 0, "<>");
      79  			printf(">, %d<", pid);
      80  			print_quoted_memory_ex(comm, strlen(comm), 0, "<>");
      81  			printf(">, SIGCONT) = %s\n", sprintrc(rc));
      82  		}
      83  
      84  		long rc = syscall(__NR_tgkill, ppid, ppid, SIGCONT);
      85  		printf("%u<%s> tgkill(%d<%s>, %d<%s>, SIGCONT) = %s\n",
      86  		       pid, comm, ppid, ocomm, ppid, ocomm, sprintrc(rc));
      87  
      88  		fflush(stdout);
      89  		char *args[] = { (char *) "unused", (char *) "execve", NULL };
      90  		execve(proc_self_exe, args, NULL);
      91  		perror_msg_and_fail("execve: %s", proc_self_exe);
      92  	} else {
      93  		int status;
      94  		while ((waitpid(child, &status, 0)) != child) {
      95  			if (errno == EINTR)
      96  				continue;
      97  			perror_msg_and_fail("waitpid: %d", child);
      98  		}
      99  		printf("%u<exe> +++ exited with 0 +++\n", child);
     100  
     101  		ppid = getppid();
     102  		printf("%u<%s> getppid() = %d<%s>\n", pid, comm, ppid, "strace");
     103  		printf("%u<%s> +++ exited with 0 +++\n", pid, comm);
     104  		return WEXITSTATUS(status);
     105  	}
     106  	return 0;
     107  }
     108  
     109  static int
     110  do_execve_action(int argc, char **argv)
     111  {
     112  	return 0;
     113  }
     114  
     115  int
     116  main(int argc, char **argv)
     117  {
     118  	if (argc < 2)
     119  		return do_default_action();
     120  	else if (strcmp(argv[1], "execve") == 0)
     121  		return do_execve_action(argc, argv);
     122  	error_msg_and_fail("unexpected argument: %s", argv[1]);
     123  }