[PATCH xorg-gtest 10/11] process: terminate the child if the parent dies

Chase Douglas chase.douglas at canonical.com
Thu Aug 16 08:39:40 PDT 2012


On 08/15/2012 11:36 PM, Peter Hutterer wrote:
> It's annoying to have the forked X server linger around when the test
> segfaults, so make sure we take it down with us.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>   src/process.cpp       |  5 +++++
>   test/process-test.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 50 insertions(+)
>
> diff --git a/src/process.cpp b/src/process.cpp
> index 4e903d6..d962a4c 100644
> --- a/src/process.cpp
> +++ b/src/process.cpp
> @@ -27,6 +27,7 @@
>
>   #include "xorg/gtest/xorg-gtest-process.h"
>
> +#include <sys/prctl.h>
>   #include <sys/types.h>
>   #include <sys/wait.h>
>   #include <unistd.h>
> @@ -81,6 +82,10 @@ void xorg::testing::Process::Start(const std::string &program, const std::vector
>         close(2);
>       }
>
> +#ifdef __linux
> +    prctl(PR_SET_PDEATHSIG, SIGTERM);
> +#endif

I had been looking around for this ^^ for a while! It's just what we 
need to fully clean things up. Good find :).

> +
>       std::vector<char*> args;
>       std::vector<std::string>::const_iterator it;
>
> diff --git a/test/process-test.cpp b/test/process-test.cpp
> index dc5402c..183b9f8 100644
> --- a/test/process-test.cpp
> +++ b/test/process-test.cpp
> @@ -1,3 +1,5 @@
> +#include <errno.h>
> +#include <unistd.h>
>   #include <sys/types.h>
>   #include <sys/wait.h>
>
> @@ -63,6 +65,49 @@ TEST(Process, TerminationFailure)
>     ASSERT_EQ(p.GetState(), Process::FINISHED_FAILURE);
>   }
>
> +TEST(Process, ChildTearDown)
> +{
> +  SCOPED_TRACE("TESTCASE: ensure child process dies when parent does");
> +
> +  int pipefd[2];
> +  ASSERT_NE(pipe(pipefd), -1);
> +
> +  /* Fork, the child will spawn a Process, write that Process's PID to a
> +     pipe and then kill itself. The parent checks that the child was
> +     terminated when the parent was killed.
> +   */
> +  pid_t pid = fork();
> +  if (pid == 0) { /* child */
> +    close(pipefd[0]);
> +
> +    Process p;
> +    p.Start("sleep", "1000", NULL); /* forks another child */
> +    ASSERT_GT(p.Pid(), 0);
> +
> +    char *buffer;
> +    ASSERT_GT(asprintf(&buffer, "%d", p.Pid()), 0);
> +    ASSERT_EQ(write(pipefd[1], buffer, strlen(buffer)), (int)strlen(buffer));
> +    close(pipefd[1]);
> +
> +    raise(SIGKILL);
> +  } else { /* parent */
> +    close(pipefd[1]);
> +
> +    char buffer[20] = {0};
> +    ASSERT_GT(read(pipefd[0], buffer, sizeof(buffer)), 0);
> +    close(pipefd[0]);
> +
> +    pid_t child_pid = atoi(buffer);
> +    for (int i = 0; i < 10; i++) {
> +      if (kill(child_pid, 0) != -1)
> +        usleep(100);
> +
> +    }
> +    ASSERT_EQ(kill(child_pid, 0), -1);
> +    ASSERT_EQ(errno, ESRCH);
> +  }
> +}
> +
>
>   int main(int argc, char *argv[]) {
>     testing::InitGoogleTest(&argc, argv);

Reviewed-by: Chase Douglas <chase.douglas at canonical.com>


More information about the xorg-devel mailing list