Bug 1966936 - Switch various IPC IDs to 64-bits, r=ipc-reviewers,mccr8,jld a=RyanVM

This changes a few IDs which have historically been 32-bit integers to
instead be 64-bit integers, reducing the chance of the value
overflowing.

Differential Revision: https://phabricator.services.mozilla.com/D250502
This commit is contained in:
Nika Layzell
2025-05-29 19:22:10 +00:00
committed by rvandermeulen@mozilla.com
parent 2b681a7411
commit 31a3ea2fb1
34 changed files with 346 additions and 362 deletions

14
dom/cache/Manager.cpp vendored
View File

@@ -370,14 +370,16 @@ class Manager::Factory {
}
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
static void RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId) {
static void RecordMayNotDeleteCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
if (sFactory) {
sFactory->mPotentiallyUnreleasedCSCP.AppendElement(
aCacheStreamControlParentId);
}
}
static void RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId) {
static void RecordHaveDeletedCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
if (sFactory) {
sFactory->mPotentiallyUnreleasedCSCP.RemoveElement(
aCacheStreamControlParentId);
@@ -519,7 +521,7 @@ class Manager::Factory {
// trigger the deletion of the factory while still executing this loop.
bool mInSyncAbortOrShutdown;
nsTArray<int32_t> mPotentiallyUnreleasedCSCP;
nsTArray<mozilla::ipc::ActorId> mPotentiallyUnreleasedCSCP;
};
// static
@@ -1691,11 +1693,13 @@ bool Manager::IsShutdownAllComplete() {
}
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
void Manager::RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId) {
void Manager::RecordMayNotDeleteCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
Factory::RecordMayNotDeleteCSCP(aCacheStreamControlParentId);
}
void Manager::RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId) {
void Manager::RecordHaveDeletedCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
Factory::RecordHaveDeletedCSCP(aCacheStreamControlParentId);
}
#endif

5
dom/cache/Manager.h vendored
View File

@@ -199,8 +199,9 @@ class Manager final : public SafeRefCounted<Manager>, public Stringifyable {
nsCOMPtr<nsIInputStream>&& aBodyStream);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
void RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId);
void RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId);
void RecordMayNotDeleteCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId);
void RecordHaveDeletedCSCP(mozilla::ipc::ActorId aCacheStreamControlParentId);
#endif
private:

View File

@@ -227,7 +227,7 @@ void OffscreenCanvas::GetContext(
return;
}
Maybe<int32_t> childId;
Maybe<mozilla::ipc::ActorId> childId;
MOZ_ASSERT(mCurrentContext);
switch (mCurrentContextType) {

View File

@@ -90,7 +90,7 @@ RefPtr<layers::ImageContainer> OffscreenCanvasDisplayHelper::GetImageContainer()
void OffscreenCanvasDisplayHelper::UpdateContext(
OffscreenCanvas* aOffscreenCanvas, RefPtr<ThreadSafeWorkerRef>&& aWorkerRef,
CanvasContextType aType, const Maybe<int32_t>& aChildId) {
CanvasContextType aType, const Maybe<mozilla::ipc::ActorId>& aChildId) {
RefPtr<layers::ImageContainer> imageContainer =
MakeRefPtr<layers::ImageContainer>(
layers::ImageUsageType::OffscreenCanvas,

View File

@@ -11,6 +11,7 @@
#include "GLContextTypes.h"
#include "mozilla/dom/CanvasRenderingContextHelper.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
@@ -45,7 +46,8 @@ class OffscreenCanvasDisplayHelper final {
void UpdateContext(OffscreenCanvas* aOffscreenCanvas,
RefPtr<ThreadSafeWorkerRef>&& aWorkerRef,
CanvasContextType aType, const Maybe<int32_t>& aChildId);
CanvasContextType aType,
const Maybe<mozilla::ipc::ActorId>& aChildId);
void FlushForDisplay();
@@ -83,7 +85,7 @@ class OffscreenCanvasDisplayHelper final {
OffscreenCanvasDisplayData mData MOZ_GUARDED_BY(mMutex);
CanvasContextType mType MOZ_GUARDED_BY(mMutex) = CanvasContextType::NoContext;
Maybe<uint32_t> mContextManagerId MOZ_GUARDED_BY(mMutex);
Maybe<int32_t> mContextChildId MOZ_GUARDED_BY(mMutex);
Maybe<mozilla::ipc::ActorId> mContextChildId MOZ_GUARDED_BY(mMutex);
const mozilla::layers::ImageContainer::ProducerID mImageProducerID;
mozilla::layers::ImageContainer::FrameID mLastFrameID MOZ_GUARDED_BY(mMutex) =
0;

View File

@@ -1032,7 +1032,7 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
// process as the WebGL canvas. Query it for the surface.
const auto& sdc = sd.get_SurfaceDescriptorCanvasSurface();
uint32_t managerId = sdc.managerId();
int32_t canvasId = sdc.canvasId();
mozilla::ipc::ActorId canvasId = sdc.canvasId();
uintptr_t surfaceId = sdc.surfaceId();
surf = gfx::CanvasManagerParent::GetCanvasSurface(
webgl->GetContentId(), managerId, canvasId, surfaceId);

View File

@@ -159,10 +159,12 @@ GetStatsPromiseForThisProcess(const nsAString& aPcIdFilter) {
std::move(UnwrapUniquePtrs));
}
static std::map<int32_t, dom::Sequence<nsString>>& GetWebrtcGlobalLogStash() {
static StaticAutoPtr<std::map<int32_t, dom::Sequence<nsString>>> sStash;
static std::map<mozilla::ipc::ActorId, dom::Sequence<nsString>>&
GetWebrtcGlobalLogStash() {
static StaticAutoPtr<std::map<mozilla::ipc::ActorId, dom::Sequence<nsString>>>
sStash;
if (!sStash) {
sStash = new std::map<int32_t, dom::Sequence<nsString>>();
sStash = new std::map<mozilla::ipc::ActorId, dom::Sequence<nsString>>();
ClearOnShutdown(&sStash);
}
return *sStash;

View File

@@ -229,7 +229,7 @@ layers::ActiveResourceTracker* CanvasManagerChild::GetActiveResourceTracker() {
}
already_AddRefed<DataSourceSurface> CanvasManagerChild::GetSnapshot(
uint32_t aManagerId, int32_t aProtocolId,
uint32_t aManagerId, ActorId aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId, SurfaceFormat aFormat,
bool aPremultiply, bool aYFlip) {

View File

@@ -38,7 +38,7 @@ class CanvasManagerChild final : public PCanvasManagerChild {
uint32_t aId);
uint32_t Id() const { return mId; }
already_AddRefed<DataSourceSurface> GetSnapshot(
uint32_t aManagerId, int32_t aProtocolId,
uint32_t aManagerId, ActorId aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId, SurfaceFormat aFormat,
bool aPremultiply, bool aYFlip);

View File

@@ -178,7 +178,7 @@ CanvasManagerParent::AllocPCanvasParent() {
}
mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
const uint32_t& aManagerId, const int32_t& aProtocolId,
const uint32_t& aManagerId, const ActorId& aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId,
webgl::FrontBufferSnapshotIpc* aResult) {
@@ -240,7 +240,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
}
/* static */ mozilla::ipc::IProtocol* CanvasManagerParent::GetCanvasActor(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId) {
dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId) {
IProtocol* actor = nullptr;
for (CanvasManagerParent* i : sManagers) {
if (i->mContentId == aContentId && i->mId == aManagerId) {
@@ -253,7 +253,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
/* static */ already_AddRefed<DataSourceSurface>
CanvasManagerParent::GetCanvasSurface(dom::ContentParentId aContentId,
uint32_t aManagerId, int32_t aCanvasId,
uint32_t aManagerId, ActorId aCanvasId,
uintptr_t aSurfaceId) {
IProtocol* actor = GetCanvasActor(aContentId, aManagerId, aCanvasId);
if (!actor) {

View File

@@ -47,16 +47,16 @@ class CanvasManagerParent final : public PCanvasManagerParent {
mozilla::ipc::IPCResult RecvInitialize(const uint32_t& aId);
mozilla::ipc::IPCResult RecvGetSnapshot(
const uint32_t& aManagerId, const int32_t& aProtocolId,
const uint32_t& aManagerId, const ActorId& aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId,
webgl::FrontBufferSnapshotIpc* aResult);
static mozilla::ipc::IProtocol* GetCanvasActor(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId);
dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId);
static already_AddRefed<DataSourceSurface> GetCanvasSurface(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId,
dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId,
uintptr_t aSurfaceId);
private:

View File

@@ -10,6 +10,7 @@ include protocol PCanvas;
include protocol PWebGL;
include protocol PWebGPU;
using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h";
using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h";
using mozilla::webgl::FrontBufferSnapshotIpc from "mozilla/dom/WebGLIpdl.h";
using mozilla::webgpu::RawId from "mozilla/webgpu/WebGPUTypes.h";
@@ -46,7 +47,7 @@ parent:
// intended to be used by the main thread in the content process to block
// reading without having to block on the worker thread that owns the context
// instance.
sync GetSnapshot(uint32_t aManagerId, int32_t aProtocolId, RemoteTextureOwnerId? ownerId, RawId? commandEncoderId) returns (FrontBufferSnapshotIpc ret);
sync GetSnapshot(uint32_t aManagerId, ActorId aProtocolId, RemoteTextureOwnerId? ownerId, RawId? commandEncoderId) returns (FrontBufferSnapshotIpc ret);
};
} // gfx

View File

@@ -765,7 +765,7 @@ already_AddRefed<gfx::SourceSurface> CanvasChild::SnapshotExternalCanvas(
RecordedResolveExternalSnapshot(syncId, gfx::ReferencePtr(surface)));
uint32_t managerId = static_cast<gfx::CanvasManagerChild*>(Manager())->Id();
int32_t canvasId = aActor->Id();
ActorId canvasId = aActor->Id();
// Actually send the request via IPDL to snapshot the external WebGL canvas.
SendSnapshotExternalCanvas(syncId, managerId, canvasId);

View File

@@ -1660,7 +1660,7 @@ void CanvasTranslator::SyncTranslation(uint64_t aSyncId) {
}
mozilla::ipc::IPCResult CanvasTranslator::RecvSnapshotExternalCanvas(
uint64_t aSyncId, uint32_t aManagerId, int32_t aCanvasId) {
uint64_t aSyncId, uint32_t aManagerId, ActorId aCanvasId) {
if (NS_WARN_IF(!IsInTaskQueue())) {
return IPC_FAIL(this,
"RecvSnapshotExternalCanvas used outside of task queue.");

View File

@@ -196,7 +196,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
*/
mozilla::ipc::IPCResult RecvSnapshotExternalCanvas(uint64_t aSyncId,
uint32_t aManagerId,
int32_t aCanvasId);
ActorId aCanvasId);
/**
* Resolves the given sync-id from the recording stream to a snapshot from

View File

@@ -33,6 +33,7 @@ using mozilla::layers::CompositeProcessFencesHolderId from "mozilla/layers/Layer
using mozilla::wr::ExternalImageSource from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::layers::SurfaceDescriptorRemoteDecoderId from "mozilla/layers/LayersTypes.h";
using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h";
[MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h";
namespace mozilla {
@@ -207,7 +208,7 @@ struct SurfaceDescriptorShared
[Comparable] struct SurfaceDescriptorCanvasSurface {
uint32_t managerId;
int32_t canvasId;
ActorId canvasId;
uintptr_t surfaceId;
};

View File

@@ -12,6 +12,7 @@ include "mozilla/layers/CanvasTranslator.h";
using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h";
using mozilla::layers::TextureType from "mozilla/layers/LayersTypes.h";
using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h";
[MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h";
[MoveOnly] using mozilla::ipc::MutableSharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h";
@@ -69,7 +70,7 @@ parent:
/**
* Snapshot an external canvas and label it for later lookup under a sync-id.
*/
async SnapshotExternalCanvas(uint64_t aSyncId, uint32_t aManagerId, int32_t aCanvasId);
async SnapshotExternalCanvas(uint64_t aSyncId, uint32_t aManagerId, ActorId aCanvasId);
async __delete__();

View File

@@ -127,6 +127,7 @@ Pickle::Pickle(uint32_t header_size, size_t segment_capacity)
DCHECK(static_cast<memberAlignmentType>(header_size) >= sizeof(Header));
DCHECK(header_size_ <= kHeaderSegmentCapacity);
header_ = reinterpret_cast<Header*>(buffers_.Start());
memset(header_, 0, header_size_);
header_->payload_size = 0;
}

View File

@@ -217,6 +217,8 @@ class Pickle {
struct Header {
uint32_t payload_size; // Specifies the size of the payload.
};
static_assert(std::has_unique_object_representations_v<Header>,
"Header must not contain padding bytes");
// Returns the header, cast to a user-specified type T. The type T must be a
// subclass of Header and its size must correspond to the header_size passed

View File

@@ -21,7 +21,7 @@ const mojo::core::ports::UserMessage::TypeInfo Message::kUserMessageTypeInfo{};
Message::~Message() { MOZ_COUNT_DTOR(IPC::Message); }
Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity,
Message::Message(routeid_t routing_id, msgid_t type, uint32_t segment_capacity,
HeaderFlags flags)
: UserMessage(&kUserMessageTypeInfo),
Pickle(sizeof(Header), segment_capacity) {
@@ -37,6 +37,7 @@ Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity,
header()->num_send_rights = 0;
#endif
header()->event_footer_size = 0;
header()->_padding = 0;
}
Message::Message(const char* data, int data_len)
@@ -46,7 +47,7 @@ Message::Message(const char* data, int data_len)
}
/*static*/ mozilla::UniquePtr<Message> Message::IPDLMessage(
int32_t routing_id, msgid_t type, uint32_t segment_capacity,
routeid_t routing_id, msgid_t type, uint32_t segment_capacity,
HeaderFlags flags) {
return mozilla::MakeUnique<Message>(routing_id, type, segment_capacity,
flags);

View File

@@ -50,7 +50,9 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
public:
static const TypeInfo kUserMessageTypeInfo;
typedef uint32_t msgid_t;
using routeid_t = int64_t;
using msgid_t = uint32_t;
using seqno_t = int64_t;
enum NestedLevel {
NOT_NESTED = 1,
@@ -175,8 +177,8 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
// Initialize a message with a user-defined type, priority value, and
// destination WebView ID.
Message(int32_t routing_id, msgid_t type,
uint32_t segmentCapacity = 0, // 0 for the default capacity.
Message(routeid_t routing_id, msgid_t type,
uint32_t segment_capacity = 0, // 0 for the default capacity.
HeaderFlags flags = HeaderFlags());
Message(const char* data, int data_len);
@@ -190,7 +192,7 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
// the write latency of messages) of IPDL message creation. This helps
// move the malloc and some of the parameter setting out of autogenerated
// code.
static mozilla::UniquePtr<Message> IPDLMessage(int32_t routing_id,
static mozilla::UniquePtr<Message> IPDLMessage(routeid_t routing_id,
msgid_t type,
uint32_t segmentCapacity,
HeaderFlags flags);
@@ -219,17 +221,17 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
msgid_t type() const { return header()->type; }
int32_t routing_id() const { return header()->routing; }
routeid_t routing_id() const { return header()->routing; }
void set_routing_id(int32_t new_id) { header()->routing = new_id; }
void set_routing_id(routeid_t new_id) { header()->routing = new_id; }
int32_t transaction_id() const { return header()->txid; }
seqno_t transaction_id() const { return header()->txid; }
void set_transaction_id(int32_t txid) { header()->txid = txid; }
void set_transaction_id(seqno_t txid) { header()->txid = txid; }
int32_t seqno() const { return header()->seqno; }
seqno_t seqno() const { return header()->seqno; }
void set_seqno(int32_t aSeqno) { header()->seqno = aSeqno; }
void set_seqno(seqno_t aSeqno) { header()->seqno = aSeqno; }
const char* name() const { return StringFromIPCMessageType(type()); }
@@ -369,22 +371,25 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
#endif
struct Header : Pickle::Header {
int32_t routing; // ID of the view that this message is destined for
// Pickle::Header contains a 32-bit payload_size field
msgid_t type; // specifies the user-defined message type
HeaderFlags flags; // specifies control flags for the message
uint32_t event_footer_size; // Size of the message's event footer
routeid_t routing; // ID of the view that this message is destined for
seqno_t txid; // For sync messages, a transaction ID for message ordering.
seqno_t seqno; // Sequence number
uint32_t num_handles; // the number of handles included with this message
#if defined(XP_DARWIN)
uint32_t cookie; // cookie to ACK that the descriptors have been read.
uint32_t num_send_rights; // the number of mach send rights included with
// this message
#endif
// For sync messages, a transaction ID for message ordering.
int32_t txid;
// Sequence number
int32_t seqno;
// Size of the message's event footer
uint32_t event_footer_size;
uint32_t _padding;
};
static_assert(std::has_unique_object_representations_v<Header>,
"Header must not contain padding bytes");
Header* header() { return headerT<Header>(); }
const Header* header() const { return headerT<Header>(); }
@@ -423,15 +428,12 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
} // namespace IPC
enum SpecialRoutingIDs {
enum SpecialRoutingIDs : IPC::Message::routeid_t {
// indicates that we don't have a routing ID yet.
MSG_ROUTING_NONE = kint32min,
MSG_ROUTING_NONE = INT64_MIN,
// indicates a general message not sent to a particular tab.
MSG_ROUTING_CONTROL = kint32max
MSG_ROUTING_CONTROL = INT64_MAX
};
#define IPC_REPLY_ID 0xFFF0 // Special message id for replies
#define IPC_LOGGING_ID 0xFFF1 // Special message id for logging
#endif // CHROME_COMMON_IPC_MESSAGE_H__

View File

@@ -84,7 +84,7 @@ bool UntypedManagedEndpoint::BindCommon(IProtocol* aActor,
return false;
}
int32_t id = mInner->mId;
ActorId id = mInner->mId;
mInner.reset();
// Our typed caller will insert the actor into the managed container.

View File

@@ -231,9 +231,9 @@ class UntypedManagedEndpoint {
RefPtr<WeakActorLifecycleProxy> mOtherSide;
RefPtr<WeakActorLifecycleProxy> mToplevel;
int32_t mId = 0;
ActorId mId = 0;
ProtocolId mType = LastMsgIndex;
int32_t mManagerId = 0;
ActorId mManagerId = 0;
ProtocolId mManagerType = LastMsgIndex;
};
Maybe<Inner> mInner;

View File

@@ -133,9 +133,10 @@ bool MessageChannel::sIsPumpingMessages = false;
class AutoEnterTransaction {
public:
explicit AutoEnterTransaction(MessageChannel* aChan, int32_t aMsgSeqno,
int32_t aTransactionID, int aNestedLevel)
MOZ_REQUIRES(*aChan->mMonitor)
explicit AutoEnterTransaction(MessageChannel* aChan,
IPC::Message::seqno_t aMsgSeqno,
IPC::Message::seqno_t aTransactionID,
int aNestedLevel) MOZ_REQUIRES(*aChan->mMonitor)
: mChan(aChan),
mActive(true),
mOutgoing(true),
@@ -234,12 +235,12 @@ class AutoEnterTransaction {
return mNestedLevel;
}
int32_t SequenceNumber() const {
IPC::Message::seqno_t SequenceNumber() const {
MOZ_RELEASE_ASSERT(mActive);
return mSeqno;
}
int32_t TransactionID() const {
IPC::Message::seqno_t TransactionID() const {
MOZ_RELEASE_ASSERT(mActive);
return mTransaction;
}
@@ -248,7 +249,7 @@ class AutoEnterTransaction {
MOZ_RELEASE_ASSERT(aMessage->seqno() == mSeqno);
MOZ_RELEASE_ASSERT(aMessage->transaction_id() == mTransaction);
MOZ_RELEASE_ASSERT(!mReply);
IPC_LOG("Reply received on worker thread: seqno=%d", mSeqno);
IPC_LOG("Reply received on worker thread: seqno=%" PRId64, mSeqno);
mReply = std::move(aMessage);
MOZ_RELEASE_ASSERT(IsComplete());
}
@@ -297,8 +298,8 @@ class AutoEnterTransaction {
// Properties of the message being sent/received.
int mNestedLevel;
int32_t mSeqno;
int32_t mTransaction;
IPC::Message::seqno_t mSeqno;
IPC::Message::seqno_t mTransaction;
// Next item in mChan->mTransactionStack.
AutoEnterTransaction* mNext;
@@ -497,7 +498,7 @@ void MessageChannel::AssertMaybeDeferredCountCorrect() {
// function is only called when the current transaction is known to be for a
// NESTED_INSIDE_SYNC message. In that case, we know for sure what the caller is
// looking for.
int32_t MessageChannel::CurrentNestedInsideSyncTransaction() const {
auto MessageChannel::CurrentNestedInsideSyncTransaction() const -> seqno_t {
mMonitor->AssertCurrentThreadOwns();
if (!mTransactionStack) {
return 0;
@@ -710,7 +711,7 @@ bool MessageChannel::OpenOnSameThread(MessageChannel* aTargetChan,
Open(std::move(porta), aSide, channelId, currentThread);
}
bool MessageChannel::Send(UniquePtr<Message> aMsg, int32_t* aSeqno) {
bool MessageChannel::Send(UniquePtr<Message> aMsg, seqno_t* aSeqno) {
MOZ_RELEASE_ASSERT(!aMsg->is_sync());
MOZ_RELEASE_ASSERT(aMsg->nested_level() != IPC::Message::NESTED_INSIDE_SYNC);
MOZ_RELEASE_ASSERT(aMsg->routing_id() != MSG_ROUTING_NONE);
@@ -843,7 +844,7 @@ bool MessageChannel::SendBuildIDsMatchMessage(const char* aParentBuildID) {
class CancelMessage : public IPC::Message {
public:
explicit CancelMessage(int transaction)
explicit CancelMessage(seqno_t transaction)
: IPC::Message(MSG_ROUTING_NONE, CANCEL_MESSAGE_TYPE) {
set_transaction_id(transaction);
}
@@ -1001,12 +1002,12 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr<Message> aMsg) {
// If we're awaiting a sync reply, we know that it needs to be immediately
// handled to unblock us.
if (aMsg->is_sync() && aMsg->is_reply()) {
IPC_LOG("Received reply seqno=%d xid=%d", aMsg->seqno(),
IPC_LOG("Received reply seqno=%" PRId64 " xid=%" PRId64, aMsg->seqno(),
aMsg->transaction_id());
if (aMsg->seqno() == mTimedOutMessageSeqno) {
// Drop the message, but allow future sync messages to be sent.
IPC_LOG("Received reply to timedout message; igoring; xid=%d",
IPC_LOG("Received reply to timedout message; igoring; xid=%" PRId64,
mTimedOutMessageSeqno);
EndTimeout();
return;
@@ -1062,8 +1063,9 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr<Message> aMsg) {
bool shouldWakeUp = AwaitingSyncReply() && !ShouldDeferMessage(*aMsg);
IPC_LOG("Receive from link; seqno=%d, xid=%d, shouldWakeUp=%d", aMsg->seqno(),
aMsg->transaction_id(), shouldWakeUp);
IPC_LOG("Receive from link; seqno=%" PRId64 ", xid=%" PRId64
", shouldWakeUp=%d",
aMsg->seqno(), aMsg->transaction_id(), shouldWakeUp);
struct FlowMarkerDispatch {
FlowMarkerDispatch(msgid_t type, Flow flow) : type(type), flow(flow) {
@@ -1086,8 +1088,8 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr<Message> aMsg) {
// We want this marker to span the time when Post is called so that we
// can inherit the connection to the runnable.
FlowMarkerDispatch marker(
aMsg->type(),
Flow::Global(aMsg->seqno() ^ LossyNarrowChannelId(mMessageChannelId)));
aMsg->type(), Flow::Global(static_cast<uint64_t>(aMsg->seqno()) ^
LossyNarrowChannelId(mMessageChannelId)));
// There are two cases we're concerned about, relating to the state of the
// worker thread:
@@ -1149,7 +1151,7 @@ void MessageChannel::ProcessPendingRequests(
return;
}
IPC_LOG("ProcessPendingRequests for seqno=%d, xid=%d",
IPC_LOG("ProcessPendingRequests for seqno=%" PRId64 ", xid=%" PRId64,
aTransaction.SequenceNumber(), aTransaction.TransactionID());
// Loop until there aren't any more nested messages to process.
@@ -1176,7 +1178,8 @@ void MessageChannel::ProcessPendingRequests(
// Only log the interesting messages.
if (msg->is_sync() ||
msg->nested_level() == IPC::Message::NESTED_INSIDE_CPOW) {
IPC_LOG("ShouldDeferMessage(seqno=%d) = %d", msg->seqno(), defer);
IPC_LOG("ShouldDeferMessage(seqno=%" PRId64 ") = %d", msg->seqno(),
defer);
}
if (!defer) {
@@ -1292,7 +1295,7 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
aMsg->set_seqno(NextSeqno());
int32_t seqno = aMsg->seqno();
seqno_t seqno = aMsg->seqno();
int nestedLevel = aMsg->nested_level();
msgid_t replyType = aMsg->type() + 1;
@@ -1304,12 +1307,12 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
// message we're sending).
bool nest =
stackTop && stackTop->NestedLevel() == IPC::Message::NESTED_INSIDE_SYNC;
int32_t transaction = nest ? stackTop->TransactionID() : seqno;
seqno_t transaction = nest ? stackTop->TransactionID() : seqno;
aMsg->set_transaction_id(transaction);
AutoEnterTransaction transact(this, seqno, transaction, nestedLevel);
IPC_LOG("Send seqno=%d, xid=%d", seqno, transaction);
IPC_LOG("Send seqno=%" PRId64 ", xid=%" PRId64, seqno, transaction);
// aMsg will be destroyed soon, let's keep its type.
const char* msgName = aMsg->name();
@@ -1365,7 +1368,7 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
break;
}
IPC_LOG("Timing out Send: xid=%d", transaction);
IPC_LOG("Timing out Send: xid=%" PRId64, transaction);
mTimedOutMessageSeqno = seqno;
mTimedOutMessageNestedLevel = nestedLevel;
@@ -1379,20 +1382,22 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
}
if (transact.IsCanceled()) {
IPC_LOG("Other side canceled seqno=%d, xid=%d", seqno, transaction);
IPC_LOG("Other side canceled seqno=%" PRId64 ", xid=%" PRId64, seqno,
transaction);
mLastSendError = SyncSendError::CancelledAfterSend;
return false;
}
if (transact.IsError()) {
IPC_LOG("Error: seqno=%d, xid=%d", seqno, transaction);
IPC_LOG("Error: seqno=%" PRId64 ", xid=%" PRId64, seqno, transaction);
mLastSendError = SyncSendError::ReplyError;
return false;
}
uint32_t latencyMs = round((TimeStamp::Now() - start).ToMilliseconds());
IPC_LOG("Got reply: seqno=%d, xid=%d, msgName=%s, latency=%ums", seqno,
transaction, msgName, latencyMs);
IPC_LOG("Got reply: seqno=%" PRId64 ", xid=%" PRId64
", msgName=%s, latency=%ums",
seqno, transaction, msgName, latencyMs);
UniquePtr<Message> reply = transact.GetReply();
@@ -1420,7 +1425,7 @@ bool MessageChannel::ProcessPendingRequest(ActorLifecycleProxy* aProxy,
AssertWorkerThread();
mMonitor->AssertCurrentThreadOwns();
IPC_LOG("Process pending: seqno=%d, xid=%d", aUrgent->seqno(),
IPC_LOG("Process pending: seqno=%" PRId64 ", xid=%" PRId64, aUrgent->seqno(),
aUrgent->transaction_id());
// keep the error relevant information
@@ -1694,14 +1699,14 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy,
}
#endif
IPC_LOG("DispatchMessage: seqno=%d, xid=%d", aMsg->seqno(),
IPC_LOG("DispatchMessage: seqno=%" PRId64 ", xid=%" PRId64, aMsg->seqno(),
aMsg->transaction_id());
AddProfilerMarker(*aMsg, MessageDirection::eReceiving);
{
AutoEnterTransaction transaction(this, *aMsg);
int id = aMsg->transaction_id();
seqno_t id = aMsg->transaction_id();
MOZ_RELEASE_ASSERT(!aMsg->is_sync() || id == transaction.TransactionID());
{
@@ -1721,7 +1726,8 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy,
if (reply && transaction.IsCanceled()) {
// The transaction has been canceled. Don't send a reply.
IPC_LOG("Nulling out reply due to cancellation, seqno=%d, xid=%d",
IPC_LOG("Nulling out reply due to cancellation, seqno=%" PRId64
", xid=%" PRId64,
aMsg->seqno(), id);
reply = nullptr;
}
@@ -1734,7 +1740,7 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy,
#endif
if (reply && ChannelConnected == mChannelState) {
IPC_LOG("Sending reply seqno=%d, xid=%d", aMsg->seqno(),
IPC_LOG("Sending reply seqno=%" PRId64 ", xid=%" PRId64, aMsg->seqno(),
aMsg->transaction_id());
AddProfilerMarker(*reply, MessageDirection::eSending);
@@ -2263,7 +2269,7 @@ void MessageChannel::AddProfilerMarker(const IPC::Message& aMessage,
void MessageChannel::EndTimeout() {
mMonitor->AssertCurrentThreadOwns();
IPC_LOG("Ending timeout of seqno=%d", mTimedOutMessageSeqno);
IPC_LOG("Ending timeout of seqno=%" PRId64, mTimedOutMessageSeqno);
mTimedOutMessageSeqno = 0;
mTimedOutMessageNestedLevel = 0;
@@ -2303,7 +2309,7 @@ void MessageChannel::RepostAllMessages() {
AssertMaybeDeferredCountCorrect();
}
void MessageChannel::CancelTransaction(int transaction) {
void MessageChannel::CancelTransaction(seqno_t transaction) {
mMonitor->AssertCurrentThreadOwns();
// When we cancel a transaction, we need to behave as if there's no longer
@@ -2316,13 +2322,13 @@ void MessageChannel::CancelTransaction(int transaction) {
// tampered with (by us). If so, they don't reset the variable to the old
// value.
IPC_LOG("CancelTransaction: xid=%d", transaction);
IPC_LOG("CancelTransaction: xid=%" PRId64, transaction);
// An unusual case: We timed out a transaction which the other side then
// cancelled. In this case we just leave the timedout state and try to
// forget this ever happened.
if (transaction == mTimedOutMessageSeqno) {
IPC_LOG("Cancelled timed out message %d", mTimedOutMessageSeqno);
IPC_LOG("Cancelled timed out message %" PRId64, mTimedOutMessageSeqno);
EndTimeout();
// Normally mCurrentTransaction == 0 here. But it can be non-zero if:
@@ -2353,8 +2359,8 @@ void MessageChannel::CancelTransaction(int transaction) {
if (msg->is_sync() && msg->nested_level() != IPC::Message::NOT_NESTED) {
MOZ_RELEASE_ASSERT(!foundSync);
MOZ_RELEASE_ASSERT(msg->transaction_id() != transaction);
IPC_LOG("Removing msg from queue seqno=%d xid=%d", msg->seqno(),
msg->transaction_id());
IPC_LOG("Removing msg from queue seqno=%" PRId64 " xid=%" PRId64,
msg->seqno(), msg->transaction_id());
foundSync = true;
if (!IsAlwaysDeferred(*msg)) {
mMaybeDeferredPendingCount--;
@@ -2379,7 +2385,7 @@ void MessageChannel::CancelCurrentTransaction() {
mListener->IntentionalCrash();
}
IPC_LOG("Cancel requested: current xid=%d",
IPC_LOG("Cancel requested: current xid=%" PRId64,
CurrentNestedInsideSyncTransaction());
MOZ_RELEASE_ASSERT(DispatchingSyncMessage());
auto cancel =

View File

@@ -114,6 +114,7 @@ class MessageChannel : HasResultCodes {
public:
using Message = IPC::Message;
using seqno_t = Message::seqno_t;
static constexpr int32_t kNoTimeout = INT32_MIN;
@@ -205,7 +206,7 @@ class MessageChannel : HasResultCodes {
// Asynchronously send a message to the other side of the channel.
// If aSeqno is non-null, it will be set to the seqno of the sent message.
bool Send(UniquePtr<Message> aMsg, int32_t* aSeqno = nullptr)
bool Send(UniquePtr<Message> aMsg, seqno_t* aSeqno = nullptr)
MOZ_EXCLUDES(*mMonitor);
bool SendBuildIDsMatchMessage(const char* aParentBuildID)
@@ -361,12 +362,13 @@ class MessageChannel : HasResultCodes {
bool ShouldContinueFromTimeout() MOZ_REQUIRES(*mMonitor);
void EndTimeout() MOZ_REQUIRES(*mMonitor);
void CancelTransaction(int transaction) MOZ_REQUIRES(*mMonitor);
void CancelTransaction(seqno_t transaction) MOZ_REQUIRES(*mMonitor);
void RepostAllMessages() MOZ_REQUIRES(*mMonitor);
int32_t NextSeqno() {
seqno_t NextSeqno() {
AssertWorkerThread();
MOZ_RELEASE_ASSERT(mozilla::Abs(mNextSeqno) < INT64_MAX, "seqno overflow");
return (mSide == ChildSide) ? --mNextSeqno : ++mNextSeqno;
}
@@ -420,7 +422,6 @@ class MessageChannel : HasResultCodes {
// Called to flush [LazySend] messages to the link.
void FlushLazySendMessages() MOZ_REQUIRES(*mMonitor);
bool WasTransactionCanceled(int transaction);
bool ShouldDeferMessage(const Message& aMsg) MOZ_REQUIRES(*mMonitor);
void OnMessageReceivedFromLink(UniquePtr<Message> aMsg)
MOZ_REQUIRES(*mMonitor);
@@ -606,7 +607,7 @@ class MessageChannel : HasResultCodes {
// Worker-thread only; sequence numbers for messages that require
// replies.
int32_t mNextSeqno = 0;
seqno_t mNextSeqno = 0;
static bool sIsPumpingMessages;
@@ -659,7 +660,7 @@ class MessageChannel : HasResultCodes {
friend class AutoEnterTransaction;
AutoEnterTransaction* mTransactionStack MOZ_GUARDED_BY(*mMonitor) = nullptr;
int32_t CurrentNestedInsideSyncTransaction() const MOZ_REQUIRES(*mMonitor);
seqno_t CurrentNestedInsideSyncTransaction() const MOZ_REQUIRES(*mMonitor);
bool AwaitingSyncReply() const MOZ_REQUIRES(*mMonitor);
int AwaitingSyncReplyNestedLevel() const MOZ_REQUIRES(*mMonitor);
@@ -686,7 +687,7 @@ class MessageChannel : HasResultCodes {
// A message is only timed out if it initiated a transaction. This avoids
// hitting a lot of corner cases with message nesting that we don't really
// care about.
int32_t mTimedOutMessageSeqno MOZ_GUARDED_BY(*mMonitor) = 0;
seqno_t mTimedOutMessageSeqno MOZ_GUARDED_BY(*mMonitor) = 0;
int mTimedOutMessageNestedLevel MOZ_GUARDED_BY(*mMonitor) = 0;
// Queue of all incoming messages.
@@ -754,7 +755,7 @@ struct IPCMarker {
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
mozilla::TimeStamp aStart, mozilla::TimeStamp aEnd, int32_t aOtherPid,
int32_t aMessageSeqno, IPC::Message::msgid_t aMessageType,
IPC::Message::seqno_t aMessageSeqno, IPC::Message::msgid_t aMessageType,
mozilla::ipc::Side aSide, mozilla::ipc::MessageDirection aDirection,
mozilla::ipc::MessagePhase aPhase, bool aSync,
mozilla::MarkerThreadId aOriginThreadId) {

View File

@@ -46,21 +46,12 @@ struct ParamTraits<IPCMessageStart>
LastMsgIndex> {};
template <>
struct ParamTraits<mozilla::ipc::ActorHandle> {
typedef mozilla::ipc::ActorHandle paramType;
struct ParamTraits<mozilla::ipc::IProtocol*> {
using paramType = mozilla::ipc::IProtocol*;
static void Write(MessageWriter* aWriter, const paramType& aParam) {
IPC::WriteParam(aWriter, aParam.mId);
}
static void Write(MessageWriter* aWriter, const paramType& aParam);
static bool Read(MessageReader* aReader, paramType* aResult) {
int id;
if (IPC::ReadParam(aReader, &id)) {
aResult->mId = id;
return true;
}
return false;
}
static bool Read(MessageReader* aReader, paramType* aResult);
};
template <>

View File

@@ -337,12 +337,12 @@ IProtocol::~IProtocol() {
// The following methods either directly forward to the toplevel protocol, or
// almost directly do.
IProtocol* IProtocol::Lookup(int32_t aId) { return mToplevel->Lookup(aId); }
IProtocol* IProtocol::Lookup(ActorId aId) { return mToplevel->Lookup(aId); }
Shmem IProtocol::CreateSharedMemory(size_t aSize, bool aUnsafe) {
return mToplevel->CreateSharedMemory(aSize, aUnsafe);
}
Shmem::Segment* IProtocol::LookupSharedMemory(int32_t aId) {
Shmem::Segment* IProtocol::LookupSharedMemory(Shmem::id_t aId) {
return mToplevel->LookupSharedMemory(aId);
}
bool IProtocol::IsTrackingSharedMemory(const Shmem::Segment* aSegment) {
@@ -363,39 +363,6 @@ nsISerialEventTarget* IProtocol::GetActorEventTarget() {
return GetIPCChannel()->GetWorkerEventTarget();
}
Maybe<IProtocol*> IProtocol::ReadActor(IPC::MessageReader* aReader,
bool aNullable,
const char* aActorDescription,
int32_t aProtocolTypeId) {
int32_t id;
if (!IPC::ReadParam(aReader, &id)) {
ActorIdReadError(aActorDescription);
return Nothing();
}
if (id == 1 || (id == 0 && !aNullable)) {
BadActorIdError(aActorDescription);
return Nothing();
}
if (id == 0) {
return Some(static_cast<IProtocol*>(nullptr));
}
IProtocol* listener = this->Lookup(id);
if (!listener) {
ActorLookupError(aActorDescription);
return Nothing();
}
if (listener->GetProtocolId() != aProtocolTypeId) {
MismatchedActorTypeError(aActorDescription);
return Nothing();
}
return Some(listener);
}
void IProtocol::FatalError(const char* const aErrorMsg) {
HandleFatalError(aErrorMsg);
}
@@ -457,7 +424,7 @@ void IProtocol::SetManager(IRefCountedProtocol* aManager) {
}
bool IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager,
int32_t aId) {
ActorId aId) {
MOZ_RELEASE_ASSERT(mLinkStatus == LinkStatus::Inactive,
"Actor must be inactive to SetManagerAndRegister");
@@ -515,7 +482,8 @@ void IProtocol::UnlinkManager() {
mManager = nullptr;
}
bool IProtocol::ChannelSend(UniquePtr<IPC::Message> aMsg, int32_t* aSeqno) {
bool IProtocol::ChannelSend(UniquePtr<IPC::Message> aMsg,
IPC::Message::seqno_t* aSeqno) {
if (CanSend()) {
// NOTE: This send call failing can only occur during toplevel channel
// teardown. As this is an async call, this isn't reasonable to predict or
@@ -601,9 +569,8 @@ void IProtocol::ActorDisconnected(ActorDestroyReason aWhy) {
fuzzing::IPCFuzzController::instance().OnActorDestroyed(actor);
#endif
int32_t id = actor->mId;
ActorId id = actor->mId;
if (IProtocol* manager = actor->Manager()) {
actor->mId = kFreedActorId;
auto entry = toplevel->mActorMap.Lookup(id);
MOZ_DIAGNOSTIC_ASSERT(entry && *entry == actor->GetLifecycleProxy(),
"ID must be present and reference this actor");
@@ -673,7 +640,7 @@ IToplevelProtocol::IToplevelProtocol(const char* aName, ProtocolId aProtoId,
Side aSide)
: IRefCountedProtocol(aProtoId, aSide),
mOtherPid(base::kInvalidProcessId),
mLastLocalId(0),
mLastLocalId(kNullActorId),
mChannel(aName, this) {
mToplevel = this;
}
@@ -723,23 +690,15 @@ bool IToplevelProtocol::IsOnCxxStack() const {
return GetIPCChannel()->IsOnCxxStack();
}
int32_t IToplevelProtocol::NextId() {
int64_t IToplevelProtocol::NextId() {
// Generate the next ID to use for a shared memory or protocol. Parent and
// Child sides of the protocol use different pools.
int32_t tag = 0;
if (GetSide() == ParentSide) {
tag |= 1 << 1;
MOZ_RELEASE_ASSERT(mozilla::Abs(mLastLocalId) < MSG_ROUTING_CONTROL - 1,
"actor id overflow");
return (GetSide() == ChildSide) ? --mLastLocalId : ++mLastLocalId;
}
// Check any overflow
MOZ_RELEASE_ASSERT(mLastLocalId < (1 << 29));
// Compute the ID to use with the low two bits as our tag, and the remaining
// bits as a monotonic.
return (++mLastLocalId << 2) | tag;
}
IProtocol* IToplevelProtocol::Lookup(int32_t aId) {
IProtocol* IToplevelProtocol::Lookup(ActorId aId) {
if (auto entry = mActorMap.Lookup(aId)) {
return entry.Data()->Get();
}
@@ -888,8 +847,8 @@ bool IPDLAsyncReturnsCallbacks::EntryKey::operator<(
(mSeqno == aOther.mSeqno && mType < aOther.mType);
}
void IPDLAsyncReturnsCallbacks::AddCallback(int32_t aSeqno, msgid_t aType,
Callback aResolve,
void IPDLAsyncReturnsCallbacks::AddCallback(IPC::Message::seqno_t aSeqno,
msgid_t aType, Callback aResolve,
RejectCallback aReject) {
Entry entry{{aSeqno, aType}, std::move(aResolve), std::move(aReject)};
MOZ_ASSERT(!mMap.ContainsSorted(entry));
@@ -950,3 +909,46 @@ void IPDLAsyncReturnsCallbacks::RejectPendingResponses(
} // namespace ipc
} // namespace mozilla
namespace IPC {
void ParamTraits<mozilla::ipc::IProtocol*>::Write(MessageWriter* aWriter,
const paramType& aParam) {
MOZ_RELEASE_ASSERT(aWriter->GetActor(),
"Cannot serialize managed actors without an actor");
mozilla::ipc::ActorId id = mozilla::ipc::IProtocol::kNullActorId;
if (aParam) {
id = aParam->Id();
MOZ_RELEASE_ASSERT(id != mozilla::ipc::IProtocol::kNullActorId,
"Actor has ID of 0?");
MOZ_RELEASE_ASSERT(aParam->CanSend(),
"Actor must still be open when sending");
MOZ_RELEASE_ASSERT(
aWriter->GetActor()->GetIPCChannel() == aParam->GetIPCChannel(),
"Actor must be from the same tree as the actor it is being sent over");
}
IPC::WriteParam(aWriter, id);
}
bool ParamTraits<mozilla::ipc::IProtocol*>::Read(MessageReader* aReader,
paramType* aResult) {
MOZ_RELEASE_ASSERT(aReader->GetActor(),
"Cannot serialize managed actors without an actor");
mozilla::ipc::ActorId id;
if (!IPC::ReadParam(aReader, &id)) {
return false;
}
if (id == mozilla::ipc::IProtocol::kNullActorId) {
*aResult = nullptr;
return true;
}
*aResult = aReader->GetActor()->Lookup(id);
return *aResult != nullptr;
}
} // namespace IPC

View File

@@ -124,9 +124,7 @@ struct EndpointProcInfo {
// Used to pass references to protocol actors across the wire.
// Actors created on the parent-side have a positive ID, and actors
// allocated on the child side have a negative ID.
struct ActorHandle {
int mId;
};
using ActorId = IPC::Message::routeid_t;
enum class LinkStatus : uint8_t {
// The actor has not established a link yet, or the actor is no longer in use
@@ -194,10 +192,10 @@ class IProtocol : public HasResultCodes {
const IToplevelProtocol* ToplevelProtocol() const { return mToplevel; }
// Lookup() is forwarded directly to the toplevel protocol.
IProtocol* Lookup(int32_t aId);
IProtocol* Lookup(ActorId aId);
Shmem CreateSharedMemory(size_t aSize, bool aUnsafe);
Shmem::Segment* LookupSharedMemory(int32_t aId);
Shmem::Segment* LookupSharedMemory(ActorId aId);
bool IsTrackingSharedMemory(const Shmem::Segment* aSegment);
bool DestroySharedMemory(Shmem& aShmem);
@@ -213,7 +211,7 @@ class IProtocol : public HasResultCodes {
ProtocolId GetProtocolId() const { return mProtocolId; }
const char* GetProtocolName() const { return ProtocolIdToName(mProtocolId); }
int32_t Id() const { return mId; }
ActorId Id() const { return mId; }
IRefCountedProtocol* Manager() const { return mManager; }
uint32_t AllManagedActorsCount() const;
@@ -232,11 +230,7 @@ class IProtocol : public HasResultCodes {
}
// Deallocate a managee given its type.
virtual void DeallocManagee(int32_t, IProtocol*) = 0;
Maybe<IProtocol*> ReadActor(IPC::MessageReader* aReader, bool aNullable,
const char* aActorDescription,
int32_t aProtocolTypeId);
virtual void DeallocManagee(ProtocolId, IProtocol*) = 0;
virtual Result OnMessageReceived(const Message& aMessage) = 0;
virtual Result OnMessageReceived(const Message& aMessage,
@@ -255,6 +249,7 @@ class IProtocol : public HasResultCodes {
friend class ActorLifecycleProxy;
friend class IPDLResolverInner;
friend class UntypedManagedEndpoint;
friend struct IPC::ParamTraits<IProtocol*>;
// We have separate functions because the accessibility code and BrowserParent
// manually calls SetManager.
@@ -269,10 +264,11 @@ class IProtocol : public HasResultCodes {
// its manager, setting up channels for the protocol as well. Not
// for use outside of IPDL.
bool SetManagerAndRegister(IRefCountedProtocol* aManager,
int32_t aId = kNullActorId);
ActorId aId = kNullActorId);
// Helpers for calling `Send` on our underlying IPC channel.
bool ChannelSend(UniquePtr<IPC::Message> aMsg, int32_t* aSeqno = nullptr);
bool ChannelSend(UniquePtr<IPC::Message> aMsg,
IPC::Message::seqno_t* aSeqno = nullptr);
bool ChannelSend(UniquePtr<IPC::Message> aMsg,
UniquePtr<IPC::Message>* aReply);
@@ -311,8 +307,7 @@ class IProtocol : public HasResultCodes {
// The actor has been freed after this method returns.
virtual void ActorDealloc() = 0;
static const int32_t kNullActorId = 0;
static const int32_t kFreedActorId = 1;
static const ActorId kNullActorId = 0;
private:
#ifdef DEBUG
@@ -327,7 +322,7 @@ class IProtocol : public HasResultCodes {
// identify managed actors to destroy when tearing down an actor tree.
IProtocol* PeekManagedActor() const;
int32_t mId;
ActorId mId;
const ProtocolId mProtocolId;
const Side mSide;
LinkStatus mLinkStatus;
@@ -444,10 +439,10 @@ class IToplevelProtocol : public IRefCountedProtocol {
public:
// Shadows the method on IProtocol, which will forward to the top.
IProtocol* Lookup(int32_t aId);
IProtocol* Lookup(Shmem::id_t aId);
Shmem CreateSharedMemory(size_t aSize, bool aUnsafe);
Shmem::Segment* LookupSharedMemory(int32_t aId);
Shmem::Segment* LookupSharedMemory(Shmem::id_t aId);
bool IsTrackingSharedMemory(const Shmem::Segment* aSegment);
bool DestroySharedMemory(Shmem& aShmem);
@@ -546,17 +541,17 @@ class IToplevelProtocol : public IRefCountedProtocol {
GeckoChildID OtherChildIDMaybeInvalid() const { return mOtherChildID; }
private:
int32_t NextId();
int64_t NextId();
template <class T>
using IDMap = nsTHashMap<nsUint32HashKey, T>;
using IDMap = nsTHashMap<int64_t, T>;
base::ProcessId mOtherPid;
GeckoChildID mOtherChildID;
// NOTE NOTE NOTE
// Used to be on mState
int32_t mLastLocalId;
int64_t mLastLocalId;
IDMap<RefPtr<ActorLifecycleProxy>> mActorMap;
IDMap<RefPtr<Shmem::Segment>> mShmemMap;
@@ -761,16 +756,17 @@ class IPDLAsyncReturnsCallbacks : public HasResultCodes {
// the IPC::MessageReader* argument.
using Callback =
mozilla::MoveOnlyFunction<Result(IPC::MessageReader* IProtocol)>;
using seqno_t = IPC::Message::seqno_t;
using msgid_t = IPC::Message::msgid_t;
void AddCallback(int32_t aSeqno, msgid_t aType, Callback aResolve,
void AddCallback(seqno_t aSeqno, msgid_t aType, Callback aResolve,
RejectCallback aReject);
Result GotReply(IProtocol* aActor, const IPC::Message& aMessage);
void RejectPendingResponses(ResponseRejectReason aReason);
private:
struct EntryKey {
int32_t mSeqno;
seqno_t mSeqno;
msgid_t mType;
bool operator==(const EntryKey& aOther) const;

View File

@@ -20,7 +20,7 @@ class ShmemCreated : public IPC::Message {
typedef Shmem::id_t id_t;
public:
ShmemCreated(int32_t routingId, id_t aIPDLId,
ShmemCreated(routeid_t routingId, id_t aIPDLId,
MutableSharedMemoryHandle&& aHandle)
: IPC::Message(
routingId, SHMEM_CREATED_MESSAGE_TYPE, 0,
@@ -46,7 +46,7 @@ class ShmemDestroyed : public IPC::Message {
typedef Shmem::id_t id_t;
public:
ShmemDestroyed(int32_t routingId, id_t aIPDLId)
ShmemDestroyed(routeid_t routingId, id_t aIPDLId)
: IPC::Message(
routingId, SHMEM_DESTROYED_MESSAGE_TYPE, 0,
HeaderFlags(NOT_NESTED, NORMAL_PRIORITY, COMPRESSION_NONE,
@@ -127,7 +127,7 @@ Shmem::Builder::Builder(size_t aSize) : mSize(aSize) {
}
std::tuple<UniquePtr<IPC::Message>, Shmem> Shmem::Builder::Build(
id_t aId, bool aUnsafe, int32_t aRoutingId) {
id_t aId, bool aUnsafe, IPC::Message::routeid_t aRoutingId) {
Shmem shmem(std::move(mSegment), aId, mSize, aUnsafe);
shmem.AssertInvariants();
MOZ_ASSERT(mHandle, "null shmem handle");
@@ -160,7 +160,8 @@ already_AddRefed<Shmem::Segment> Shmem::OpenExisting(
return MakeAndAddRef<Shmem::Segment>(std::move(mapping));
}
UniquePtr<IPC::Message> Shmem::MkDestroyedMessage(int32_t routingId) {
UniquePtr<IPC::Message> Shmem::MkDestroyedMessage(
IPC::Message::routeid_t routingId) {
AssertInvariants();
return MakeUnique<ShmemDestroyed>(routingId, mId);
}

View File

@@ -68,7 +68,7 @@ class Shmem final {
friend class IToplevelProtocol;
public:
using id_t = int32_t;
using id_t = int64_t;
// Low-level wrapper around platform shmem primitives.
class Segment final : public SharedMemoryMapping {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Segment);
@@ -89,8 +89,8 @@ class Shmem final {
// Prepare this to be shared with another process. Return an IPC message
// that contains enough information for the other process to map this
// segment in OpenExisting(), and the shmem.
std::tuple<UniquePtr<IPC::Message>, Shmem> Build(id_t aId, bool aUnsafe,
int32_t aRoutingId);
std::tuple<UniquePtr<IPC::Message>, Shmem> Build(
id_t aId, bool aUnsafe, IPC::Message::routeid_t aRoutingId);
private:
size_t mSize;
@@ -169,7 +169,7 @@ class Shmem final {
// contains enough information for the other process to unmap this
// segment. Return a new message if successful (owned by the
// caller), nullptr if not.
UniquePtr<IPC::Message> MkDestroyedMessage(int32_t routingId);
UniquePtr<IPC::Message> MkDestroyedMessage(IPC::Message::routeid_t routingId);
// Return a Segment instance in this process using the descriptor shared
// to us by the process that created the underlying OS shmem resource. The

View File

@@ -130,7 +130,7 @@ def _protocolId(ptype):
def _protocolIdType():
return Type.INT32
return Type("mozilla::ipc::ProtocolId")
def _actorName(pname, side):
@@ -142,11 +142,7 @@ def _actorName(pname, side):
def _actorIdType():
return Type.INT32
def _actorTypeTagType():
return Type.INT32
return Type("mozilla::ipc::ActorId")
def _actorId(actor=None):
@@ -155,10 +151,6 @@ def _actorId(actor=None):
return ExprCall(ExprVar("Id"))
def _actorHId(actorhandle):
return ExprSelect(actorhandle, ".", "mId")
def _deleteId():
return ExprVar("Msg___delete____ID")
@@ -1822,7 +1814,7 @@ def _generateMessageConstructor(md, segmentSize, protocol, forReply=False):
func = FunctionDefn(
FunctionDecl(
clsname,
params=[Decl(Type("int32_t"), routingId.name)],
params=[Decl(Type("IPC::Message::routeid_t"), routingId.name)],
ret=Type("mozilla::UniquePtr<IPC::Message>"),
)
)
@@ -2144,53 +2136,38 @@ class _ParamTraits:
Write and read callers will perform nullability validation."""
cxxtype = _cxxBareType(actortype, side, fq=True)
basetype = Type("mozilla::ipc::IProtocol", ptr=True)
write = StmtCode(
"""
MOZ_RELEASE_ASSERT(
${writervar}->GetActor(),
"Cannot serialize managed actors without an actor");
int32_t id;
if (!${var}) {
id = 0; // kNullActorId
} else {
id = ${var}->Id();
if (id == 1) { // kFreedActorId
${var}->FatalError("Actor has been |delete|d");
}
MOZ_RELEASE_ASSERT(
${writervar}->GetActor()->GetIPCChannel() == ${var}->GetIPCChannel(),
"Actor must be from the same channel as the"
" actor it's being sent over");
MOZ_RELEASE_ASSERT(
${var}->CanSend(),
"Actor must still be open when sending");
}
${write};
""",
var=cls.var,
writervar=cls.writervar,
write=cls.write(ExprVar("id"), cls.writervar),
# void Write(..) impl - Write actor as IProtocol*
write = cls.checkedWrite(
None,
ExprCast(cls.var, basetype, static=True),
cls.writervar,
sentinelKey=actortype.name(),
)
# bool Read(..) impl
# bool Read(..) impl - Read actor as IProtocol*
read = StmtCode(
"""
MOZ_RELEASE_ASSERT(
${readervar}->GetActor(),
"Cannot deserialize managed actors without an actor");
mozilla::Maybe<mozilla::ipc::IProtocol*> actor = ${readervar}->GetActor()
->ReadActor(${readervar}, true, ${actortype}, ${protocolid});
if (actor.isSome()) {
return static_cast<${cxxtype}>(actor.ref());
}
${read}
if (actor && actor->GetProtocolId() != ${protocolid}) {
${typeerror}
return {};
}
return static_cast<${cxxtype}>(actor);
""",
readervar=cls.readervar,
actortype=ExprLiteral.String(actortype.name()),
read=cls._checkedRead(
None,
basetype,
ExprVar("actor"),
sentinelKey=actortype.name(),
what="managed " + actortype.name() + " actor",
),
protocolid=_protocolId(actortype),
typeerror=cls.fatalError(
cls.readervar,
"Unexpected actor type (expected " + actortype.name() + ")",
),
cxxtype=cxxtype,
)
@@ -3350,7 +3327,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
self.nonForwardDeclaredHeaders = set()
self.typedefSet = set(
[
Typedef(Type("mozilla::ipc::ActorHandle"), "ActorHandle"),
Typedef(Type("mozilla::ipc::ActorId"), "ActorId"),
Typedef(Type("base::ProcessId"), "ProcessId"),
Typedef(Type("mozilla::ipc::ProtocolId"), "ProtocolId"),
Typedef(Type("mozilla::ipc::Endpoint"), "Endpoint", ["FooSide"]),
@@ -4034,8 +4011,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
# for ctor recv cases, we can't read the actor ID into a PFoo*
# because it doesn't exist on this side yet. Use a "special"
# actor handle instead
handlevar = ExprVar("handle__")
self.handlevar = handlevar
actoridvar = ExprVar("actorid__")
self.actoridvar = actoridvar
msgtype = ExprCode("msg__.type()")
self.asyncSwitch = StmtSwitch(msgtype)
@@ -4130,7 +4107,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
method.addcode(
"""
int32_t route__ = ${msgvar}.routing_id();
IPC::Message::routeid_t route__ = ${msgvar}.routing_id();
if (MSG_ROUTING_CONTROL != route__) {
IProtocol* routed__ = Lookup(route__);
if (!routed__ || !routed__->GetLifecycleProxy()) {
@@ -4762,7 +4739,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
def genCtorRecvCase(self, md):
lbl = CaseLabel(md.pqMsgId())
case = StmtBlock()
actorhandle = self.handlevar
stmts = self.deserializeMessage(
md, self.side, errfnRecv, errfnSent=errfnSentinel(_Result.ValuError)
@@ -4778,7 +4754,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
# alloc the actor, register it under the foreign ID
+ [self.callAllocActor(md, retsems="in", side=self.side)]
+ self.bindManagedActor(
md.actorDecl(), errfn=_Result.ValuError, idexpr=_actorHId(actorhandle)
md.actorDecl(), errfn=_Result.ValuError, idexpr=self.actoridvar
)
+ [Whitespace.NL]
+ saveIdStmts
@@ -4847,11 +4823,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
def makeMessage(self, md, errfn, fromActor=None):
msgvar = self.msgvar
writervar = ExprVar("writer__")
isctor = md.decl.type.isCtor()
routingId = self.protocol.routingId(fromActor)
this = fromActor or ExprVar.THIS
stmts = (
[
stmts = [
StmtDecl(
Decl(Type("UniquePtr<IPC::Message>"), msgvar.name),
init=ExprCall(ExprVar(md.pqMsgCtorFunc()), args=[routingId]),
@@ -4860,20 +4836,32 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
Decl(Type("IPC::MessageWriter"), writervar.name),
initargs=[ExprDeref(msgvar), this],
),
Whitespace.NL,
]
+ [Whitespace.NL]
+ [
start = 0
if isctor:
# serialize the actor as the raw actor ID so that it can be used to
# construct the "real" actor on the other side.
stmts += [
_ParamTraits.checkedWrite(
None,
_actorId(ExprVar("actor")),
ExprAddrOf(writervar),
sentinelKey="actorid",
)
]
start = 1
stmts += [
_ParamTraits.checkedWrite(
p.ipdltype,
p.var(),
ExprAddrOf(writervar),
sentinelKey=p.name,
)
for p in md.params
for p in md.params[start:]
]
+ [Whitespace.NL]
+ self.setMessageFlags(md, msgvar)
)
return msgvar, stmts
def makeResolver(self, md, errfn, routingId):
@@ -4964,20 +4952,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
)
for r in md.returns
]
+ self.setMessageFlags(md, replyvar)
+ [self.logMessage(md, replyvar, "Sending reply ")]
)
def setMessageFlags(self, md, var, seqno=None):
stmts = []
if seqno:
stmts.append(
StmtExpr(ExprCall(ExprSelect(var, "->", "set_seqno"), args=[seqno]))
)
return stmts + [Whitespace.NL]
def deserializeMessage(self, md, side, errfn, errfnSent):
msgvar = self.msgvar
msgexpr = ExprAddrOf(msgvar)
@@ -4996,17 +4973,17 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
if isctor:
# return the raw actor handle so that its ID can be used
# to construct the "real" actor
handlevar = self.handlevar
handletype = Type("ActorHandle")
actoridvar = self.actoridvar
actoridtype = _actorIdType()
reads = [
_ParamTraits.checkedRead(
None,
handletype,
handlevar,
actoridtype,
actoridvar,
ExprAddrOf(readervar),
errfn,
"'%s'" % handletype.name,
sentinelKey="actor",
"'%s'" % actoridtype.name,
sentinelKey="actorid",
errfnSentinel=errfnSent,
)
]
@@ -5066,27 +5043,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
StmtReturn(errcode),
]
start, reads = 0, []
if md.decl.type.isCtor():
# return the raw actor handle so that its ID can be used
# to construct the "real" actor
handlevar = self.handlevar
handletype = Type("ActorHandle")
reads = [
_ParamTraits.checkedRead(
None,
handletype,
handlevar,
readervar,
errfn,
"'%s'" % handletype.name,
sentinelKey="actor",
errfnSentinel=errfnSentinel(_Result.ValuError),
)
]
start = 1
reads += [
_ParamTraits.checkedRead(
p.ipdltype,
p.bareType(side),
@@ -5097,7 +5054,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
sentinelKey=p.name,
errfnSentinel=errfnSentinel(_Result.ValuError),
)
for p in md.returns[start:]
for p in md.returns
]
if len(md.returns) > 1:
@@ -5185,7 +5142,12 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
if actor is not None:
send = ExprSelect(actor, "->", send.name)
if md.returns:
stmts.append(StmtDecl(Decl(Type.INT32, seqno.name), init=ExprLiteral.ZERO))
stmts.append(
StmtDecl(
Decl(Type("IPC::Message::seqno_t"), seqno.name),
init=ExprLiteral.ZERO,
)
)
ifsendok = StmtIf(
ExprCall(send, args=[ExprMove(msgexpr), ExprAddrOf(seqno)])
)

View File

@@ -326,15 +326,16 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
Maybe<PortName> portName = channel->GetPortName();
if (!portName) {
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %d Protocol: %s\n",
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
" Protocol: %s\n",
protocol->Id(), protocol->GetProtocolName());
}
if (portName) {
if (!protoIdFilter.empty()) {
if (!strcmp(protocol->GetProtocolName(), protoIdFilter.c_str())) {
MOZ_FUZZING_NYX_PRINTF(
"INFO: [OnActorConnected] ActorID %d Protocol: %s matches "
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
" Protocol: %s matches "
"target.\n",
protocol->Id(), protocol->GetProtocolName());
@@ -343,14 +344,14 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
// the actor will always be added to the map.
protoFilterTargetExcludeToplevel = protocol->Manager() != nullptr;
} else if (actorIds[*portName].empty()) {
MOZ_FUZZING_NYX_PRINTF(
"INFO: [OnActorConnected] ActorID %d Protocol: %s is toplevel "
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
" Protocol: %s is toplevel "
"actor.\n",
protocol->Id(), protocol->GetProtocolName());
} else if (allowSubActors &&
IsManagedByTargetActor(protocol, protoIdFilter)) {
MOZ_FUZZING_NYX_PRINTF(
"INFO: [OnActorConnected] ActorID %d Protocol: %s is managed by "
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
" Protocol: %s is managed by "
"target actor.\n",
protocol->Id(), protocol->GetProtocolName());
} else {
@@ -358,8 +359,8 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
// sub actor of our target or we are focusing only on the target. Ignore
// this actor.
if (!!getenv("MOZ_FUZZ_DEBUG")) {
MOZ_FUZZING_NYX_PRINTF(
"INFO: [OnActorConnected] ActorID %d Protocol: %s ignored due to "
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
" Protocol: %s ignored due to "
"filter.\n",
protocol->Id(), protocol->GetProtocolName());
}
@@ -368,10 +369,10 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
}
if (!!getenv("MOZ_FUZZ_DEBUG")) {
MOZ_FUZZING_NYX_PRINTF(
"INFO: [OnActorConnected] ActorID %d Protocol: %s Port: %lu %lu\n",
protocol->Id(), protocol->GetProtocolName(), portName->v1,
portName->v2);
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
" Protocol: %s Port: %lu %lu\n",
protocol->Id(), protocol->GetProtocolName(),
portName->v1, portName->v2);
}
actorIds[*portName].emplace_back(protocol->Id(), protocol->GetProtocolId());
@@ -474,7 +475,8 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel,
}
return true;
} else if (aMessage.type() == mIPCTriggerMsg && !Nyx::instance().started()) {
MOZ_FUZZING_NYX_PRINTF("DEBUG: Ready message detected on actor %d.\n",
MOZ_FUZZING_NYX_PRINTF("DEBUG: Ready message detected on actor %" PRId64
".\n",
aMessage.routing_id());
if (!haveTargetNodeName && !!getenv("MOZ_FUZZ_PROTOID_FILTER")) {
@@ -504,7 +506,7 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel,
// In this mode, we really want to focus on a single actor.
useLastActor = 1024;
maybeLastActorId = aMessage.routing_id();
MOZ_FUZZING_NYX_PRINTF("DEBUG: Pinned to actor %d forever.\n",
MOZ_FUZZING_NYX_PRINTF("DEBUG: Pinned to actor %" PRId64 " forever.\n",
aMessage.routing_id());
} else {
// In this mode, we want to focus on a particular actor and all of its
@@ -644,8 +646,8 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel,
// Called on the I/O thread and modifies `portSeqNos`.
MutexAutoLock lock(mMutex);
portSeqNos.insert_or_assign(
name, std::pair<int32_t, uint64_t>(aMessage.seqno(),
userMsgEv->sequence_num()));
name, std::pair<IPC::Message::seqno_t, uint64_t>(
aMessage.seqno(), userMsgEv->sequence_num()));
#ifdef FUZZ_DEBUG
MOZ_FUZZING_NYX_PRINTF(
"DEBUG: Port %lu %lu updated sequence number to %lu\n", name.v1,
@@ -718,8 +720,9 @@ void IPCFuzzController::OnMessageError(
bool IPCFuzzController::MakeTargetDecision(
uint8_t portIndex, uint8_t portInstanceIndex, uint8_t actorIndex,
uint8_t actorProtocolIndex, uint16_t typeOffset, PortName* name,
int32_t* seqno, uint64_t* fseqno, int32_t* actorId, uint32_t* type,
bool* is_cons, bool update) {
IPC::Message::seqno_t* seqno, uint64_t* fseqno,
mozilla::ipc::ActorId* actorId, uint32_t* type, bool* is_cons,
bool update) {
if (useLastActor) {
useLastActor--;
*name = lastActorPortName;
@@ -894,14 +897,15 @@ bool IPCFuzzController::MakeTargetDecision(
MOZ_FUZZING_NYX_PRINTF(
"DEBUG: MakeTargetDecision: Top-Level Protocol: %s Protocol: %s msgType: "
"%s (%u), Actor Instance %u of %zu, actor ID: %d, PreservedHeader: %d\n",
"%s (%u), Actor Instance %u of %zu, actor ID: %" PRId64
", PreservedHeader: %d\n",
portNameToProtocolName[*name].c_str(), ProtocolIdToName(ids.second),
IPC::StringFromIPCMessageType(*type), *type, actorIndex, actors.size(),
*actorId, isPreserveHeader);
if (update) {
portSeqNos.insert_or_assign(*name,
std::pair<int32_t, uint64_t>(*seqno, *fseqno));
portSeqNos.insert_or_assign(
*name, std::pair<IPC::Message::seqno_t, uint64_t>(*seqno, *fseqno));
}
return true;
@@ -1048,7 +1052,7 @@ NS_IMETHODIMP IPCFuzzController::IPCFuzzLoop::Run() {
// have to adjust these so the next calculated sequence number pair
// matches the start sequence numbers.
IPCFuzzController::instance().portSeqNos.insert_or_assign(
iter->first, std::pair<int32_t, uint64_t>(0, 0));
iter->first, std::pair<IPC::Message::seqno_t, uint64_t>(0, 0));
IPCFuzzController::instance().AddToplevelActor(
iter->first, iter->second[0].second);
@@ -1139,10 +1143,10 @@ NS_IMETHODIMP IPCFuzzController::IPCFuzzLoop::Run() {
ipchdr->payload_size = ipcMsgLen - sizeof(IPC::Message::Header);
PortName new_port_name;
int32_t new_seqno;
IPC::Message::seqno_t new_seqno;
uint64_t new_fseqno;
int32_t actorId;
mozilla::ipc::ActorId actorId;
uint32_t msgType = 0;
bool isConstructor = false;
// Control Data Layout (16 byte)
@@ -1575,7 +1579,7 @@ UniquePtr<IPC::Message> IPCFuzzController::replaceIPCMessage(
UniquePtr<IPC::Message> msg(new IPC::Message(ipcMsgData, ipcMsgLen));
if (!!getenv("MOZ_FUZZ_DEBUG")) {
MOZ_FUZZING_NYX_PRINTF("INFO: Name: %s Target: %d\n", msg->name(),
MOZ_FUZZING_NYX_PRINTF("INFO: Name: %s Target: %" PRId64 "\n", msg->name(),
msg->routing_id());
}

View File

@@ -52,6 +52,7 @@ namespace ipc {
// We can't include ProtocolUtils.h here
class IProtocol;
typedef IPCMessageStart ProtocolId;
typedef IPC::Message::routeid_t ActorId;
class NodeChannel;
} // namespace ipc
@@ -59,9 +60,10 @@ class NodeChannel;
namespace fuzzing {
class IPCFuzzController {
typedef std::pair<int32_t, uint64_t> SeqNoPair;
typedef std::pair<IPC::Message::seqno_t, uint64_t> SeqNoPair;
typedef std::pair<int32_t, mozilla::ipc::ProtocolId> ActorIdPair;
typedef std::pair<mozilla::ipc::ActorId, mozilla::ipc::ProtocolId>
ActorIdPair;
class IPCFuzzLoop final : public Runnable {
friend class IPCFuzzController;
@@ -87,8 +89,9 @@ class IPCFuzzController {
bool MakeTargetDecision(uint8_t portIndex, uint8_t portInstanceIndex,
uint8_t actorIndex, uint8_t actorProtocolIndex,
uint16_t typeOffset,
mojo::core::ports::PortName* name, int32_t* seqno,
uint64_t* fseqno, int32_t* actorId, uint32_t* type,
mojo::core::ports::PortName* name,
IPC::Message::seqno_t* seqno, uint64_t* fseqno,
mozilla::ipc::ActorId* actorId, uint32_t* type,
bool* is_cons, bool update = true);
void OnActorConnected(mozilla::ipc::IProtocol* protocol);
@@ -159,7 +162,7 @@ class IPCFuzzController {
Atomic<uint32_t> useLastActor;
// If this is non-zero, we want a specific actor ID instead of the last.
Atomic<int32_t> maybeLastActorId;
Atomic<mozilla::ipc::ActorId> maybeLastActorId;
// If this is non-empty and in certain configurations, we only use a fixed
// set of messages, rather than sending any message type for that actor.

View File

@@ -596,7 +596,7 @@ template <>
void LogTaskBase<IPC::Message>::LogDispatchWithPid(IPC::Message* aEvent,
int32_t aPid) {
if (aEvent->seqno() && aPid > 0) {
LOG1(("SEND %p %d %d", aEvent, aEvent->seqno(), aPid));
LOG1(("SEND %p %" PRId64 " %d", aEvent, aEvent->seqno(), aPid));
}
}
@@ -651,7 +651,7 @@ LogTaskBase<Task>::Run::Run(Task* aTask, bool aWillRunAgain)
template <>
LogTaskBase<IPC::Message>::Run::Run(IPC::Message* aMessage, bool aWillRunAgain)
: mWillRunAgain(aWillRunAgain) {
LOG1(("RECV %p %p %d [%s]", aMessage, this, aMessage->seqno(),
LOG1(("RECV %p %p %" PRId64 " [%s]", aMessage, this, aMessage->seqno(),
aMessage->name()));
}