mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1345978, part 2 - Check build ids early in content startup. r=billm
If Firefox is updated while it is running, the content process can end up being a different version than the parent process. This can cause odd crashes, that will happen repeatedly until the user restarts Firefox. To handle this better, this patch adds a special build ID message that is sent early in content process startup. The parent process intentionally crashes if the build ID for the child process does not match that of the parent process. MozReview-Commit-ID: 7D3ggkaLxNS --HG-- extra : rebase_source : 1f8d917ce01919524f949dd5bedfbbbd557f7ed3
This commit is contained in:
parent
3cb01b77f0
commit
b46bfc918b
@ -578,6 +578,11 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_A11Y_REENTRY);
|
||||
#endif
|
||||
|
||||
// This must be sent before any IPDL message, which may hit sentinel
|
||||
// errors due to parent and content processes having different
|
||||
// versions.
|
||||
GetIPCChannel()->SendBuildID();
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// Send the parent our X socket to act as a proxy reference for our X
|
||||
// resources.
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsAppRunner.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
@ -819,6 +820,45 @@ MessageChannel::Send(Message* aMsg)
|
||||
return true;
|
||||
}
|
||||
|
||||
class BuildIDMessage : public IPC::Message
|
||||
{
|
||||
public:
|
||||
BuildIDMessage()
|
||||
: IPC::Message(MSG_ROUTING_NONE, BUILD_ID_MESSAGE_TYPE)
|
||||
{
|
||||
}
|
||||
void Log(const std::string& aPrefix, FILE* aOutf) const
|
||||
{
|
||||
fputs("(special `Build ID' message)", aOutf);
|
||||
}
|
||||
};
|
||||
|
||||
// Send the parent a special async message to allow it to detect if
|
||||
// this process is running a different build. This is a minor
|
||||
// variation on MessageChannel::Send(Message* aMsg).
|
||||
void
|
||||
MessageChannel::SendBuildID()
|
||||
{
|
||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||
nsAutoPtr<BuildIDMessage> msg(new BuildIDMessage());
|
||||
nsCString buildID(mozilla::PlatformBuildID());
|
||||
IPC::WriteParam(msg, buildID);
|
||||
|
||||
MOZ_RELEASE_ASSERT(!msg->is_sync());
|
||||
MOZ_RELEASE_ASSERT(msg->nested_level() != IPC::Message::NESTED_INSIDE_SYNC);
|
||||
|
||||
AssertWorkerThread();
|
||||
mMonitor->AssertNotCurrentThreadOwns();
|
||||
// Don't check for MSG_ROUTING_NONE.
|
||||
|
||||
MonitorAutoLock lock(*mMonitor);
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel", msg);
|
||||
MOZ_CRASH();
|
||||
}
|
||||
mLink->SendMessage(msg.forget());
|
||||
}
|
||||
|
||||
class CancelMessage : public IPC::Message
|
||||
{
|
||||
public:
|
||||
@ -835,6 +875,22 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
MOZ_NEVER_INLINE static void
|
||||
CheckChildProcessBuildID(const IPC::Message& aMsg)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
nsCString childBuildID;
|
||||
PickleIterator msgIter(aMsg);
|
||||
MOZ_ALWAYS_TRUE(IPC::ReadParam(&aMsg, &msgIter, &childBuildID));
|
||||
aMsg.EndRead(msgIter);
|
||||
|
||||
nsCString parentBuildID(mozilla::PlatformBuildID());
|
||||
|
||||
// This assert can fail if the child process has been updated
|
||||
// to a newer version while the parent process was running.
|
||||
MOZ_RELEASE_ASSERT(parentBuildID == childBuildID);
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::MaybeInterceptSpecialIOMessage(const Message& aMsg)
|
||||
{
|
||||
@ -856,6 +912,10 @@ MessageChannel::MaybeInterceptSpecialIOMessage(const Message& aMsg)
|
||||
CancelTransaction(aMsg.transaction_id());
|
||||
NotifyWorkerThread();
|
||||
return true;
|
||||
} else if (BUILD_ID_MESSAGE_TYPE == aMsg.type()) {
|
||||
IPC_LOG("Build ID message");
|
||||
CheckChildProcessBuildID(aMsg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -153,6 +153,8 @@ class MessageChannel : HasResultCodes
|
||||
// Asynchronously send a message to the other side of the channel
|
||||
bool Send(Message* aMsg);
|
||||
|
||||
void SendBuildID();
|
||||
|
||||
// Asynchronously deliver a message back to this side of the
|
||||
// channel
|
||||
bool Echo(Message* aMsg);
|
||||
|
@ -46,6 +46,7 @@ namespace {
|
||||
// protocol 0. Oops! We can get away with this until protocol 0
|
||||
// starts approaching its 65,536th message.
|
||||
enum {
|
||||
BUILD_ID_MESSAGE_TYPE = kuint16max - 7,
|
||||
CHANNEL_OPENED_MESSAGE_TYPE = kuint16max - 6,
|
||||
SHMEM_DESTROYED_MESSAGE_TYPE = kuint16max - 5,
|
||||
SHMEM_CREATED_MESSAGE_TYPE = kuint16max - 4,
|
||||
|
Loading…
Reference in New Issue
Block a user