mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 545053: IPDL/C++ test of hang detector.
This commit is contained in:
parent
7f56845cb9
commit
2d8c28e487
@ -66,6 +66,7 @@ IPDLTESTS = \
|
||||
TestLatency \
|
||||
TestRPCRaces \
|
||||
TestRacyRPCReplies \
|
||||
TestHangs \
|
||||
TestBlockChild \
|
||||
TestManyChildAllocs \
|
||||
TestDesc \
|
||||
|
28
ipc/ipdl/test/cxx/PTestHangs.ipdl
Normal file
28
ipc/ipdl/test/cxx/PTestHangs.ipdl
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
rpc protocol PTestHangs {
|
||||
both:
|
||||
rpc StackFrame();
|
||||
|
||||
child:
|
||||
rpc Hang();
|
||||
__delete__();
|
||||
|
||||
|
||||
state START:
|
||||
call StackFrame goto FRAME2;
|
||||
|
||||
// So as to test unwinding the RPC stack
|
||||
state FRAME2: answer StackFrame goto FRAME3;
|
||||
state FRAME3: call StackFrame goto FRAME4;
|
||||
state FRAME4: answer StackFrame goto HANG;
|
||||
state HANG: call Hang goto DEATH;
|
||||
|
||||
state DEATH:
|
||||
send __delete__;
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
99
ipc/ipdl/test/cxx/TestHangs.cpp
Normal file
99
ipc/ipdl/test/cxx/TestHangs.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include "base/process_util.h"
|
||||
|
||||
#include "TestHangs.h"
|
||||
|
||||
#include "IPDLUnitTests.h" // fail etc.
|
||||
|
||||
using base::KillProcess;
|
||||
|
||||
// XXX could drop this; very conservative
|
||||
static const int kTimeoutSecs = 5;
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parent
|
||||
|
||||
TestHangsParent::TestHangsParent() : mFramesToGo(2)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestHangsParent);
|
||||
}
|
||||
|
||||
TestHangsParent::~TestHangsParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestHangsParent);
|
||||
}
|
||||
|
||||
void
|
||||
TestHangsParent::Main()
|
||||
{
|
||||
SetReplyTimeoutMs(1000 * kTimeoutSecs);
|
||||
|
||||
if (CallStackFrame())
|
||||
fail("should have timed out!");
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
bool
|
||||
TestHangsParent::ShouldContinueFromReplyTimeout()
|
||||
{
|
||||
// If we kill the subprocess here, then the "channel error" event
|
||||
// posted by the IO thread will race with the |Close()| above, in
|
||||
// |Main()|. As killing the child process will probably be a
|
||||
// common action to take from ShouldContinue(), we need to ensure
|
||||
// that *Channel can deal.
|
||||
|
||||
// XXX: OtherProcess() is a semi-private API, but using it is
|
||||
// OK until we start worrying about inter-thread comm
|
||||
if (!KillProcess(OtherProcess(), 0, false))
|
||||
fail("terminating child process");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TestHangsParent::AnswerStackFrame()
|
||||
{
|
||||
if (--mFramesToGo) {
|
||||
if (CallStackFrame())
|
||||
fail("should have timed out!");
|
||||
}
|
||||
else {
|
||||
if (CallHang())
|
||||
fail("should have timed out!");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// child
|
||||
|
||||
TestHangsChild::TestHangsChild()
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestHangsChild);
|
||||
}
|
||||
|
||||
TestHangsChild::~TestHangsChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestHangsChild);
|
||||
}
|
||||
|
||||
bool
|
||||
TestHangsChild::AnswerHang()
|
||||
{
|
||||
puts(" (child process is hanging now)");
|
||||
|
||||
// XXX: pause() is right for this, but windows doesn't appear to
|
||||
// implement it. So sleep for 100,000 seconds instead.
|
||||
PR_Sleep(PR_SecondsToInterval(100000));
|
||||
|
||||
fail("should have been killed!");
|
||||
return false; // not reached
|
||||
}
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
74
ipc/ipdl/test/cxx/TestHangs.h
Normal file
74
ipc/ipdl/test/cxx/TestHangs.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef mozilla__ipdltest_TestHangs_h
|
||||
#define mozilla__ipdltest_TestHangs_h 1
|
||||
|
||||
#include "mozilla/_ipdltest/IPDLUnitTests.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestHangsParent.h"
|
||||
#include "mozilla/_ipdltest/PTestHangsChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
class TestHangsParent :
|
||||
public PTestHangsParent
|
||||
{
|
||||
public:
|
||||
TestHangsParent();
|
||||
virtual ~TestHangsParent();
|
||||
|
||||
void Main();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual bool ShouldContinueFromReplyTimeout();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual bool AnswerStackFrame();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (AbnormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
passed("ok");
|
||||
QuitParent();
|
||||
}
|
||||
|
||||
// XXX hack around lack of State()
|
||||
int mFramesToGo;
|
||||
};
|
||||
|
||||
|
||||
class TestHangsChild :
|
||||
public PTestHangsChild
|
||||
{
|
||||
public:
|
||||
TestHangsChild();
|
||||
virtual ~TestHangsChild();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual bool AnswerStackFrame()
|
||||
{
|
||||
if (!CallStackFrame())
|
||||
fail("shouldn't be able to observe this failure");
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual bool AnswerHang();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
fail("should have been mercilessly killed");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
#endif // ifndef mozilla__ipdltest_TestHangs_h
|
@ -6,6 +6,7 @@ IPDLSRCS = \
|
||||
PTestDesc.ipdl \
|
||||
PTestDescSub.ipdl \
|
||||
PTestDescSubsub.ipdl \
|
||||
PTestHangs.ipdl \
|
||||
PTestLatency.ipdl \
|
||||
PTestManyChildAllocs.ipdl \
|
||||
PTestManyChildAllocsSub.ipdl \
|
||||
|
Loading…
Reference in New Issue
Block a user