C   27

exit c

Guest on 30th May 2022 01:55:11 AM

  1. #include <sys/param.h>
  2. #include <sys/types.h>
  3. #include <sys/ptrace.h>
  4. #include <sys/sysctl.h>
  5. #include <sys/wait.h>
  6. #include <assert.h>
  7. #include <err.h>
  8. #include <errno.h>
  9. #include <stdbool.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <unistd.h>
  13.  
  14. #define ATF_REQUIRE(a) assert(a)
  15. #define CHILD_REQUIRE(a) assert(a)
  16.  
  17. #define FORKEE_ASSERTX(x)                                                       \
  18. do {                                                                            \
  19.         int ret = (x);                                                          \
  20.         if (!ret)                                                               \
  21.                 errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",      \
  22.                      __FILE__, __LINE__, __func__, #x);                         \
  23. } while (0)
  24.  
  25. #define FORKEE_ASSERT(x)                                                        \
  26. do {                                                                            \
  27.         int ret = (x);                                                          \
  28.         if (!ret)                                                               \
  29.                 err(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",       \
  30.                      __FILE__, __LINE__, __func__, #x);                         \
  31. } while (0)
  32.  
  33. #ifndef nitemps
  34. #define nitems(x)   (sizeof((x)) / sizeof((x)[0]))
  35. #endif
  36.  
  37. #if defined(linux)
  38. #define WALLSIG __WALL
  39. #define sys_signame sys_siglist
  40. #endif
  41.  
  42. static void
  43. wait_for_zombie(pid_t pid)
  44. {
  45.         printf("KR!!! %s(): %s:%d\n", __func__, __FILE__, __LINE__);
  46.         /*
  47.          * Wait for a process to exit.  This is kind of gross, but
  48.          * there is not a better way.
  49.          */
  50.         for (;;) {
  51.                 printf("KR!!! %s(): %s:%d\n", __func__, __FILE__, __LINE__);
  52. #if defined(__FreeBSD__) || defined(__NetBSD__)
  53. #if defined(__NetBSD__)
  54.                 struct kinfo_proc2 kp;
  55. #elif defined(__FreeBSD__)
  56.                 struct kinfo_proc kp;
  57. #endif
  58.                 size_t len;
  59.                 int mib[4];
  60.  
  61.                 mib[0] = CTL_KERN;
  62.                 mib[1] = KERN_PROC;
  63.                 mib[2] = KERN_PROC_PID;
  64.                 mib[3] = pid;
  65. #if defined(__NetBSD__)
  66.                 mib[4] = sizeof(kp);
  67.                 mib[5] = 1;
  68. #endif
  69.                 len = sizeof(kp);
  70.                 if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) {
  71.                         /* The KERN_PROC_PID sysctl fails for zombies. */
  72.                         ATF_REQUIRE(errno == ESRCH);
  73.                         break;
  74.                 }
  75. #elif defined(linux)
  76.         printf("KR!!! %s(): %s:%d\n", __func__, __FILE__, __LINE__);
  77. bool iszombie = false;
  78. // open the /proc/*/stat file
  79. char pbuf[32];
  80. snprintf(pbuf, sizeof(pbuf), "/proc/%d/stat", (int)pid);
  81. FILE* fpstat = fopen(pbuf, "r");
  82. if (!fpstat) {
  83. break;
  84. };
  85. {
  86.   int rpid =0; char rcmd[32]; char rstatc = 0;
  87.   fscanf(fpstat, "%d %30s %c", &rpid, rcmd, &rstatc);
  88.   iszombie = rstatc == 'Z';
  89. }
  90. fclose(fpstat);
  91. if (iszombie == true)
  92.         break;
  93. #endif
  94.                 usleep(5000);
  95.         }
  96.         printf("KR!!! %s(): %s:%d pid=%d zombie!\n", __func__, __FILE__, __LINE__, getpid());
  97. }
  98.  
  99. int
  100. main(int argc, char **argv)
  101. {
  102.         pid_t child, debugger, wpid;  
  103.         int cpipe[2], dpipe[2], status;
  104.         char c = '0';
  105.         int tmp;
  106.  
  107.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  108.  
  109.         ATF_REQUIRE(pipe(cpipe) == 0);
  110.         ATF_REQUIRE((child = fork()) != -1);
  111.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  112.         if (child == 0) {
  113.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  114.                 /* Child process. */
  115.                 close(cpipe[1]);
  116.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  117.                
  118.                 /* Wait for parent to be ready. */
  119.                 FORKEE_ASSERTX(read(cpipe[0], &c, sizeof(c)) == sizeof(c)); // assert
  120.  
  121.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  122.                 _exit(1);
  123.         }
  124.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  125.         ATF_REQUIRE(pipe(dpipe) == 0);
  126.         ATF_REQUIRE((debugger = fork()) != -1);
  127.  
  128.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  129.         if (debugger == 0) {
  130.                 close(cpipe[0]);
  131.                 close(cpipe[1]);
  132.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  133.                 /* Debugger process. */
  134.                 FORKEE_ASSERT(ptrace(PT_ATTACH, child, NULL, 0) != -1); // assert
  135.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  136.  
  137.                 wpid = waitpid(child, &status, 0);
  138.                 CHILD_REQUIRE(wpid == child);
  139.                 CHILD_REQUIRE(WIFSTOPPED(status));
  140.                 CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP);
  141.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  142.                 FORKEE_ASSERT(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1);
  143.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  144.                 /* Signal parent that debugger is attached. */
  145.                 char debug1 = 'd';
  146.                 printf("KR!!! %s(): %s:%d pid=%d trying to write to pipe character '%c'\n", __func__, __FILE__, __LINE__, getpid(), debug1);
  147.                 FORKEE_ASSERT(write(dpipe[1], &debug1, sizeof(debug1)) == sizeof(debug1));
  148.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  149.                 /* Wait for parent's failed wait. */
  150.                 sleep(1);
  151. /*
  152.                 tmp = read(dpipe[0], &c, sizeof(c));
  153.                 if (tmp != 0)
  154.                         printf("KR!!! %s(): %s:%d pid=%d got a character '%c'\n", __func__, __FILE__, __LINE__, getpid(), c);
  155.                 else
  156.                         printf("KR!!! %s(): %s:%d pid=%d no character!\n", __func__, __FILE__, __LINE__, getpid());
  157.                 FORKEE_ASSERT(tmp == 0);
  158. */
  159.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  160.                 wpid = waitpid(child, &status, 0);
  161.                 CHILD_REQUIRE(wpid == child);                                                                                        
  162.                 CHILD_REQUIRE(WIFEXITED(status));
  163.                 CHILD_REQUIRE(WEXITSTATUS(status) == 1);
  164.                 printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  165.                 _exit(0);
  166.         }
  167.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  168. //        close(dpipe[0]);
  169.         /* Parent process. */
  170.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  171.  
  172.         /* Wait for the debugger to attach to the child. */
  173.         ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c));
  174.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  175.         /* Release the child. */
  176.         ATF_REQUIRE(write(cpipe[1], &c, sizeof(c)) == sizeof(c));
  177.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  178.         //ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0);
  179.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  180.         close(cpipe[0]);
  181.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  182.         close(cpipe[1]);
  183.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  184.                                                                                                                                      
  185.         wait_for_zombie(child);
  186.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  187.  
  188.         /*
  189.          * This wait should return a pid of 0 to indicate no status to
  190.          * report.  The parent should see the child as non-exited
  191.          * until the debugger sees the exit.
  192.          */
  193.         wpid = waitpid(child, &status, WNOHANG);
  194.         ATF_REQUIRE(wpid == 0);
  195.  
  196.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  197.         /* Signal the debugger to wait for the child. */
  198.         close(dpipe[0]);
  199.         close(dpipe[1]);
  200.  
  201.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  202.         /* Wait for the debugger. */
  203.         wpid = waitpid(debugger, &status, 0);
  204.         ATF_REQUIRE(wpid == debugger);
  205.         ATF_REQUIRE(WIFEXITED(status));                                                                                              
  206.         ATF_REQUIRE(WEXITSTATUS(status) == 0);
  207.  
  208.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  209.         /* The child process should now be ready. */
  210.         wpid = waitpid(child, &status, WNOHANG);
  211.         ATF_REQUIRE(wpid == child);
  212.         ATF_REQUIRE(WIFEXITED(status));
  213.         ATF_REQUIRE(WEXITSTATUS(status) == 1);
  214.         printf("KR!!! %s(): %s:%d pid=%d\n", __func__, __FILE__, __LINE__, getpid());
  215.  
  216.  
  217.         printf("dziala!!\n");
  218.         return 0;
  219. }

Raw Paste


Login or Register to edit or fork this paste. It's free.