| // Copyright 2018 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/developer/debug/ipc/agent_protocol.h" | |
| #include "src/developer/debug/ipc/message_reader.h" | |
| #include "src/developer/debug/ipc/message_writer.h" | |
| #include "src/developer/debug/ipc/protocol_helpers.h" | |
| namespace debug_ipc { | |
| // Record deserializers ---------------------------------------------------------------------------- | |
| bool Deserialize(MessageReader* reader, ProcessBreakpointSettings* settings) { | |
| if (!reader->ReadUint64(&settings->process_koid) || !reader->ReadUint64(&settings->thread_koid) || | |
| !reader->ReadUint64(&settings->address)) { | |
| return false; | |
| } | |
| return Deserialize(reader, &settings->address_range); | |
| } | |
| bool Deserialize(MessageReader* reader, BreakpointSettings* settings) { | |
| if (!reader->ReadUint32(&settings->id)) | |
| return false; | |
| uint32_t type; | |
| if (!reader->ReadUint32(&type) || type >= static_cast<uint32_t>(BreakpointType::kLast)) | |
| return false; | |
| settings->type = static_cast<BreakpointType>(type); | |
| if (!reader->ReadString(&settings->name)) | |
| return false; | |
| if (!reader->ReadBool(&settings->one_shot)) | |
| return false; | |
| uint32_t stop; | |
| if (!reader->ReadUint32(&stop)) | |
| return false; | |
| settings->stop = static_cast<Stop>(stop); | |
| return Deserialize(reader, &settings->locations); | |
| } | |
| bool Deserialize(MessageReader* reader, ConfigAction* action) { | |
| uint32_t type = 0; | |
| if (!reader->ReadUint32(&type) || type >= static_cast<uint32_t>(ConfigAction::Type::kLast)) { | |
| return false; | |
| } | |
| action->type = static_cast<ConfigAction::Type>(type); | |
| if (!reader->ReadString(&action->value)) | |
| return false; | |
| return true; | |
| } | |
| // Record serializers ------------------------------------------------------------------------------ | |
| void Serialize(const ProcessTreeRecord& record, MessageWriter* writer) { | |
| writer->WriteUint32(static_cast<uint32_t>(record.type)); | |
| writer->WriteUint64(record.koid); | |
| writer->WriteString(record.name); | |
| Serialize(record.children, writer); | |
| } | |
| void Serialize(const ThreadRecord& record, MessageWriter* writer) { | |
| writer->WriteUint64(record.process_koid); | |
| writer->WriteUint64(record.thread_koid); | |
| writer->WriteString(record.name); | |
| writer->WriteUint32(static_cast<uint32_t>(record.state)); | |
| writer->WriteUint32(static_cast<uint32_t>(record.blocked_reason)); | |
| writer->WriteUint32(static_cast<uint32_t>(record.stack_amount)); | |
| Serialize(record.frames, writer); | |
| } | |
| void Serialize(const ProcessRecord& record, MessageWriter* writer) { | |
| writer->WriteUint64(record.process_koid); | |
| writer->WriteString(record.process_name); | |
| Serialize(record.threads, writer); | |
| } | |
| void Serialize(const MemoryBlock& block, MessageWriter* writer) { | |
| writer->WriteUint64(block.address); | |
| writer->WriteBool(block.valid); | |
| writer->WriteUint32(block.size); | |
| if (block.valid && block.size > 0) | |
| writer->WriteBytes(&block.data[0], block.size); | |
| } | |
| void Serialize(const Module& module, MessageWriter* writer) { | |
| writer->WriteString(module.name); | |
| writer->WriteUint64(module.base); | |
| writer->WriteUint64(module.debug_address); | |
| writer->WriteString(module.build_id); | |
| } | |
| void Serialize(const StackFrame& frame, MessageWriter* writer) { | |
| writer->WriteUint64(frame.ip); | |
| writer->WriteUint64(frame.sp); | |
| writer->WriteUint64(frame.cfa); | |
| Serialize(frame.regs, writer); | |
| } | |
| void Serialize(const AddressRegion& region, MessageWriter* writer) { | |
| writer->WriteString(region.name); | |
| writer->WriteUint64(region.base); | |
| writer->WriteUint64(region.size); | |
| writer->WriteUint64(region.depth); | |
| } | |
| void Serialize(const BreakpointStats& stats, MessageWriter* writer) { | |
| writer->WriteUint32(stats.id); | |
| writer->WriteUint32(stats.hit_count); | |
| writer->WriteBool(stats.should_delete); | |
| } | |
| // Hello ------------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, HelloRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return true; | |
| } | |
| void WriteReply(const HelloReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kHello, transaction_id); | |
| writer->WriteBytes(&reply, sizeof(HelloReply)); | |
| } | |
| // Status ------------------------------------------------------------------------------------------ | |
| bool ReadRequest(MessageReader* reader, StatusRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return true; | |
| } | |
| void WriteReply(const StatusReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kStatus, transaction_id); | |
| Serialize(reply.processes, writer); | |
| Serialize(reply.limbo, writer); | |
| } | |
| // ProcessStatus ----------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, ProcessStatusRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| if (!reader->ReadUint64(&request->process_koid)) | |
| return false; | |
| return true; | |
| } | |
| void WriteReply(const ProcessStatusReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kProcessStatus, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| } | |
| // Launch ------------------------------------------------------------------------------------------ | |
| bool ReadRequest(MessageReader* reader, LaunchRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| uint32_t inferior_type; | |
| if (!reader->ReadUint32(&inferior_type) || | |
| inferior_type >= static_cast<uint32_t>(InferiorType::kLast)) { | |
| return false; | |
| } | |
| request->inferior_type = static_cast<InferiorType>(inferior_type); | |
| return Deserialize(reader, &request->argv); | |
| } | |
| void WriteReply(const LaunchReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kLaunch, transaction_id); | |
| writer->WriteUint32(static_cast<uint32_t>(reply.inferior_type)); | |
| writer->WriteUint32(reply.status); | |
| writer->WriteUint64(reply.process_id); | |
| writer->WriteUint64(reply.component_id); | |
| writer->WriteString(reply.process_name); | |
| } | |
| // Kill ------------------------------------------------------------------------------------------ | |
| bool ReadRequest(MessageReader* reader, KillRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadUint64(&request->process_koid); | |
| } | |
| void WriteReply(const KillReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kKill, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| } | |
| // Attach ------------------------------------------------------------------------------------------ | |
| bool ReadRequest(MessageReader* reader, AttachRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| uint32_t type; | |
| if (!reader->ReadUint32(&type)) | |
| return false; | |
| if (type >= static_cast<uint32_t>(TaskType::kLast)) | |
| return false; | |
| request->type = static_cast<TaskType>(type); | |
| return reader->ReadUint64(&request->koid); | |
| } | |
| void WriteReply(const AttachReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kAttach, transaction_id); | |
| writer->WriteUint64(reply.koid); | |
| writer->WriteUint32(reply.status); | |
| writer->WriteString(reply.name); | |
| } | |
| // Detach ------------------------------------------------------------------------------------------ | |
| bool ReadRequest(MessageReader* reader, DetachRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| uint32_t type; | |
| if (!reader->ReadUint32(&type)) | |
| return false; | |
| if (type >= static_cast<uint32_t>(TaskType::kLast)) | |
| return false; | |
| request->type = static_cast<TaskType>(type); | |
| return reader->ReadUint64(&request->koid); | |
| } | |
| void WriteReply(const DetachReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kDetach, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| } | |
| // Pause ------------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, PauseRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| if (!reader->ReadUint64(&request->process_koid)) | |
| return false; | |
| if (!reader->ReadUint64(&request->thread_koid)) | |
| return false; | |
| return true; | |
| } | |
| void WriteReply(const PauseReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kPause, transaction_id); | |
| Serialize(reply.threads, writer); | |
| } | |
| // QuitAgent --------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, QuitAgentRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return true; | |
| } | |
| void WriteReply(const QuitAgentReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kQuitAgent, transaction_id); | |
| } | |
| // Resume ------------------------------------------------------------------------------------------ | |
| bool ReadRequest(MessageReader* reader, ResumeRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| if (!reader->ReadUint64(&request->process_koid)) | |
| return false; | |
| if (!Deserialize(reader, &request->thread_koids)) | |
| return false; | |
| uint32_t how; | |
| if (!reader->ReadUint32(&how)) | |
| return false; | |
| if (how >= static_cast<uint32_t>(ResumeRequest::How::kLast)) | |
| return false; | |
| request->how = static_cast<ResumeRequest::How>(how); | |
| if (!reader->ReadUint64(&request->range_begin)) | |
| return false; | |
| if (!reader->ReadUint64(&request->range_end)) | |
| return false; | |
| return true; | |
| } | |
| void WriteReply(const ResumeReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kResume, transaction_id); | |
| } | |
| // ProcessTree ------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, ProcessTreeRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadBytes(sizeof(ProcessTreeRequest), request); | |
| } | |
| void WriteReply(const ProcessTreeReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kProcessTree, transaction_id); | |
| Serialize(reply.root, writer); | |
| } | |
| // Threads ----------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, ThreadsRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadBytes(sizeof(ThreadsRequest), request); | |
| } | |
| void WriteReply(const ThreadsReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kThreads, transaction_id); | |
| Serialize(reply.threads, writer); | |
| } | |
| // ReadMemory -------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, ReadMemoryRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadBytes(sizeof(ReadMemoryRequest), request); | |
| } | |
| void WriteReply(const ReadMemoryReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kReadMemory, transaction_id); | |
| Serialize(reply.blocks, writer); | |
| } | |
| // AddOrChangeBreakpoint --------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, AddOrChangeBreakpointRequest* request, | |
| uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return Deserialize(reader, &request->breakpoint); | |
| } | |
| void WriteReply(const AddOrChangeBreakpointReply& reply, uint32_t transaction_id, | |
| MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kAddOrChangeBreakpoint, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| } | |
| // RemoveBreakpoint -------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, RemoveBreakpointRequest* request, | |
| uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadBytes(sizeof(RemoveBreakpointRequest), request); | |
| } | |
| void WriteReply(const RemoveBreakpointReply& reply, uint32_t transaction_id, | |
| MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kRemoveBreakpoint, transaction_id); | |
| } | |
| // SysInfo ----------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, SysInfoRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return true; | |
| } | |
| void WriteReply(const SysInfoReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kSysInfo, transaction_id); | |
| writer->WriteString(reply.version); | |
| writer->WriteUint32(reply.num_cpus); | |
| writer->WriteUint32(reply.memory_mb); | |
| writer->WriteUint32(reply.hw_breakpoint_count); | |
| writer->WriteUint32(reply.hw_watchpoint_count); | |
| } | |
| // ThreadStatus ------------------------------------------------------------------------------------ | |
| bool ReadRequest(MessageReader* reader, ThreadStatusRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadBytes(sizeof(ThreadStatusRequest), request); | |
| } | |
| void WriteReply(const ThreadStatusReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kThreadStatus, transaction_id); | |
| Serialize(reply.record, writer); | |
| } | |
| // Modules ----------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, ModulesRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadBytes(sizeof(ModulesRequest), request); | |
| } | |
| void WriteReply(const ModulesReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kModules, transaction_id); | |
| Serialize(reply.modules, writer); | |
| } | |
| // JobFilter -------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, JobFilterRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| if (!reader->ReadUint64(&request->job_koid)) | |
| return false; | |
| return Deserialize(reader, &request->filters); | |
| } | |
| void WriteReply(const JobFilterReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kJobFilter, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| Serialize(reply.matched_processes, writer); | |
| } | |
| // WriteMemory ------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, WriteMemoryRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| if (!reader->ReadUint64(&request->process_koid)) | |
| return false; | |
| if (!reader->ReadUint64(&request->address)) | |
| return false; | |
| return Deserialize(reader, &request->data); | |
| } | |
| void WriteReply(const WriteMemoryReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kWriteMemory, transaction_id); | |
| writer->WriteUint64(reply.status); | |
| } | |
| // LoadInfoHandleTable | |
| // ------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, LoadInfoHandleTableRequest* request, | |
| uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadUint64(&request->process_koid); | |
| } | |
| void WriteReply(const LoadInfoHandleTableReply& reply, uint32_t transaction_id, | |
| MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kLoadInfoHandleTable, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| Serialize(reply.handles, writer); | |
| } | |
| // UpdateGlobalSettings --------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, UpdateGlobalSettingsRequest* request, | |
| uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return Deserialize(reader, &request->exception_strategies); | |
| } | |
| void WriteReply(const UpdateGlobalSettingsReply& reply, uint32_t transaction_id, | |
| MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kUpdateGlobalSettings, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| } | |
| // ReadRegisters ----------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, ReadRegistersRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| if (!reader->ReadUint64(&request->process_koid) || !reader->ReadUint64(&request->thread_koid)) | |
| return false; | |
| return Deserialize(reader, &request->categories); | |
| } | |
| void WriteReply(const ReadRegistersReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kReadRegisters, transaction_id); | |
| Serialize(reply.registers, writer); | |
| } | |
| // WriteRegisters ---------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, WriteRegistersRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| if (!reader->ReadUint64(&request->process_koid) || !reader->ReadUint64(&request->thread_koid)) | |
| return false; | |
| return Deserialize(reader, &request->registers); | |
| } | |
| void WriteReply(const WriteRegistersReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kWriteRegisters, transaction_id); | |
| writer->WriteUint32(reply.status); | |
| Serialize(reply.registers, writer); | |
| } | |
| // Address space ----------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, AddressSpaceRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return reader->ReadBytes(sizeof(AddressSpaceRequest), request); | |
| } | |
| void WriteReply(const AddressSpaceReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kAddressSpace, transaction_id); | |
| Serialize(reply.map, writer); | |
| } | |
| // ConfigAgent ------------------------------------------------------------------------------------- | |
| bool ReadRequest(MessageReader* reader, ConfigAgentRequest* request, uint32_t* transaction_id) { | |
| MsgHeader header; | |
| if (!reader->ReadHeader(&header)) | |
| return false; | |
| *transaction_id = header.transaction_id; | |
| return Deserialize(reader, &request->actions); | |
| } | |
| void WriteReply(const ConfigAgentReply& reply, uint32_t transaction_id, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kConfigAgent, transaction_id); | |
| Serialize(reply.results, writer); | |
| } | |
| // Notifications ----------------------------------------------------------------------------------- | |
| void WriteNotifyProcessExiting(const NotifyProcessExiting& notify, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kNotifyProcessExiting, 0); | |
| writer->WriteUint64(notify.process_koid); | |
| writer->WriteInt64(notify.return_code); | |
| } | |
| void WriteNotifyProcessStarting(const NotifyProcessStarting& notify, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kNotifyProcessStarting, 0); | |
| writer->WriteUint32(static_cast<uint32_t>(notify.type)); | |
| writer->WriteUint64(notify.koid); | |
| writer->WriteUint32(notify.component_id); | |
| writer->WriteString(notify.name); | |
| } | |
| void WriteNotifyThread(MsgHeader::Type type, const NotifyThread& notify, MessageWriter* writer) { | |
| writer->WriteHeader(type, 0); | |
| Serialize(notify.record, writer); | |
| } | |
| void WriteNotifyException(const NotifyException& notify, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kNotifyException, 0); | |
| Serialize(notify.thread, writer); | |
| writer->WriteUint32(static_cast<uint32_t>(notify.type)); | |
| writer->WriteBytes(¬ify.exception, sizeof(notify.exception)); | |
| Serialize(notify.hit_breakpoints, writer); | |
| Serialize(notify.other_affected_threads, writer); | |
| } | |
| void WriteNotifyModules(const NotifyModules& notify, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kNotifyModules, 0); | |
| writer->WriteUint64(notify.process_koid); | |
| Serialize(notify.modules, writer); | |
| Serialize(notify.stopped_thread_koids, writer); | |
| } | |
| void WriteNotifyIO(const NotifyIO& notify, MessageWriter* writer) { | |
| writer->WriteHeader(MsgHeader::Type::kNotifyIO, 0); | |
| writer->WriteUint64(notify.process_koid); | |
| writer->WriteUint32(static_cast<uint32_t>(notify.type)); | |
| writer->WriteString(notify.data); | |
| writer->WriteBool(notify.more_data_available); | |
| } | |
| } // namespace debug_ipc |