From ced5e33c0a851d9fac51d9c92bd3ae5996f4688c Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 23 Nov 2016 13:40:04 -0800 Subject: [PATCH] Bug 1319910 - Crash child, not parent, on FatalError in TestActorPunning and TestBadActor. r=billm The parent process crashes if it gets a bad message from the child, but that makes it hard to test. This patch overrides the fatal error handling method and uses the old behavior, that kills the child. I copied the code to kill the child from TestHangs. MozReview-Commit-ID: 3YgqaCgHGI0 --HG-- extra : rebase_source : cbecee2742014e969c641b89833cff5f46b99a33 --- ipc/ipdl/test/cxx/TestActorPunning.cpp | 24 ++++++++++++++++++++++++ ipc/ipdl/test/cxx/TestActorPunning.h | 4 +++- ipc/ipdl/test/cxx/TestBadActor.cpp | 24 ++++++++++++++++++++++++ ipc/ipdl/test/cxx/TestBadActor.h | 2 ++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/ipc/ipdl/test/cxx/TestActorPunning.cpp b/ipc/ipdl/test/cxx/TestActorPunning.cpp index 0fa797e26df2..fff0fe38a818 100644 --- a/ipc/ipdl/test/cxx/TestActorPunning.cpp +++ b/ipc/ipdl/test/cxx/TestActorPunning.cpp @@ -25,6 +25,30 @@ TestActorPunningParent::RecvPun(PTestActorPunningSubParent* a, const Bad& bad) return IPC_OK(); } +// By default, fatal errors kill the parent process, but this makes it +// hard to test, so instead we use the previous behavior and kill the +// child process. +void +TestActorPunningParent::HandleFatalError(const char* aProtocolName, const char* aErrorMsg) const +{ + if (!!strcmp(aProtocolName, "PTestActorPunningParent")) { + fail("wrong protocol hit a fatal error"); + } + + if (!!strcmp(aErrorMsg, "Error deserializing 'PTestActorPunningSubParent'")) { + fail("wrong fatal error"); + } + + ipc::ScopedProcessHandle otherProcessHandle; + if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle.rwget())) { + fail("couldn't open child process"); + } else { + if (!base::KillProcess(otherProcessHandle, 0, false)) { + fail("terminating child process"); + } + } +} + PTestActorPunningPunnedParent* TestActorPunningParent::AllocPTestActorPunningPunnedParent() { diff --git a/ipc/ipdl/test/cxx/TestActorPunning.h b/ipc/ipdl/test/cxx/TestActorPunning.h index 9a3bcf219c78..5e283ce2cefa 100644 --- a/ipc/ipdl/test/cxx/TestActorPunning.h +++ b/ipc/ipdl/test/cxx/TestActorPunning.h @@ -35,10 +35,12 @@ protected: virtual void ActorDestroy(ActorDestroyReason why) override { if (NormalShutdown == why) - fail("should have died from error!"); + fail("should have died from error!"); passed("ok"); QuitParent(); } + + virtual void HandleFatalError(const char* aProtocolName, const char* aErrorMsg) const override; }; class TestActorPunningPunnedParent : diff --git a/ipc/ipdl/test/cxx/TestBadActor.cpp b/ipc/ipdl/test/cxx/TestBadActor.cpp index 686e0a7282bd..8e01a9c284cb 100644 --- a/ipc/ipdl/test/cxx/TestBadActor.cpp +++ b/ipc/ipdl/test/cxx/TestBadActor.cpp @@ -19,6 +19,30 @@ TestBadActorParent::Main() Unused << child->Call__delete__(child); } +// By default, fatal errors kill the parent process, but this makes it +// hard to test, so instead we use the previous behavior and kill the +// child process. +void +TestBadActorParent::HandleFatalError(const char* aProtocolName, const char* aErrorMsg) const +{ + if (!!strcmp(aProtocolName, "PTestBadActorSubParent")) { + fail("wrong protocol hit a fatal error"); + } + + if (!!strcmp(aErrorMsg, "incoming message racing with actor deletion")) { + fail("wrong fatal error"); + } + + ipc::ScopedProcessHandle otherProcessHandle; + if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle.rwget())) { + fail("couldn't open child process"); + } else { + if (!base::KillProcess(otherProcessHandle, 0, false)) { + fail("terminating child process"); + } + } +} + PTestBadActorSubParent* TestBadActorParent::AllocPTestBadActorSubParent() { diff --git a/ipc/ipdl/test/cxx/TestBadActor.h b/ipc/ipdl/test/cxx/TestBadActor.h index fc94a0db0e01..267f206af078 100644 --- a/ipc/ipdl/test/cxx/TestBadActor.h +++ b/ipc/ipdl/test/cxx/TestBadActor.h @@ -33,6 +33,8 @@ protected: QuitParent(); } + virtual void HandleFatalError(const char* aProtocolName, const char* aErrorMsg) const override; + virtual PTestBadActorSubParent* AllocPTestBadActorSubParent() override;