diff --git a/src/developer/debug/debug_agent/breakpoint.cc b/src/developer/debug/debug_agent/breakpoint.cc index e022d3b272d411838285b6e5cd474378a279adb8..b405c80c3242123e686f0689272da166ce71ec21 100644 --- a/src/developer/debug/debug_agent/breakpoint.cc +++ b/src/developer/debug/debug_agent/breakpoint.cc @@ -30,10 +30,16 @@ Breakpoint::~Breakpoint() { } zx_status_t Breakpoint::SetSettings( + debug_ipc::BreakpointType type, const debug_ipc::BreakpointSettings& settings) { - zx_status_t result = ZX_OK; + FXL_DCHECK(type == debug_ipc::BreakpointType::kSoftware || + type == debug_ipc::BreakpointType::kHardware) + << "Got: " << debug_ipc::BreakpointTypeToString(type); + type_ = type; settings_ = settings; + zx_status_t result = ZX_OK; + // The stats needs to reference the current ID. We assume setting the // settings doesn't update the stats (an option to do this may need to be // added in the future). @@ -64,8 +70,6 @@ zx_status_t Breakpoint::SetSettings( return result; } - - bool Breakpoint::AppliesToThread(zx_koid_t pid, zx_koid_t tid) const { for (auto& location : settings_.locations) { diff --git a/src/developer/debug/debug_agent/breakpoint.h b/src/developer/debug/debug_agent/breakpoint.h index 81969691e4ee568324881e7bf39efbd0e14d0586..8e45d59ec70a0e43d06e2c0889cd3b106ac15cfc 100644 --- a/src/developer/debug/debug_agent/breakpoint.h +++ b/src/developer/debug/debug_agent/breakpoint.h @@ -57,7 +57,14 @@ class Breakpoint { const debug_ipc::BreakpointStats& stats() const { return stats_; } // Sets the initial settings, or updates settings. - zx_status_t SetSettings(const debug_ipc::BreakpointSettings& settings); + zx_status_t SetSettings(debug_ipc::BreakpointType, + const debug_ipc::BreakpointSettings& settings); + + debug_ipc::BreakpointType type() const { return type_; } + + // The setter is used mostly for testing. Normal setting should go through + // SetSettings. + void set_type(debug_ipc::BreakpointType type) { type_ = type; } const debug_ipc::BreakpointSettings& settings() const { return settings_; } // A breakpoint can be set to apply to a specific set of threads. A thread @@ -73,6 +80,7 @@ class Breakpoint { ProcessDelegate* process_delegate_; // Non-owning. + debug_ipc::BreakpointType type_ = debug_ipc::BreakpointType::kLast; debug_ipc::BreakpointSettings settings_; debug_ipc::BreakpointStats stats_; diff --git a/src/developer/debug/debug_agent/breakpoint_unittest.cc b/src/developer/debug/debug_agent/breakpoint_unittest.cc index cfa2840e855385ab86f0455a5a48bf2f0bab5bdc..d2dc605846fd3535117a03100c330109a8d2b380 100644 --- a/src/developer/debug/debug_agent/breakpoint_unittest.cc +++ b/src/developer/debug/debug_agent/breakpoint_unittest.cc @@ -55,7 +55,8 @@ TEST(Breakpoint, Registration) { pr_settings.address = kAddress1; // Apply the settings. - ASSERT_EQ(ZX_OK, bp.SetSettings(settings)); + ASSERT_EQ(ZX_OK, bp.SetSettings(debug_ipc::BreakpointType::kSoftware, + settings)); EXPECT_EQ(CallVector({CallPair{kProcess1, kAddress1}}), delegate.register_calls()); EXPECT_TRUE(delegate.unregister_calls().empty()); @@ -69,7 +70,8 @@ TEST(Breakpoint, Registration) { pr_settings.thread_koid = 0; pr_settings.address = kAddress2; - ASSERT_EQ(ZX_OK, bp.SetSettings(settings)); + ASSERT_EQ(ZX_OK, bp.SetSettings(debug_ipc::BreakpointType::kSoftware, + settings)); EXPECT_EQ(CallVector({CallPair{kProcess2, kAddress2}}), delegate.register_calls()); EXPECT_EQ(CallVector({CallPair{kProcess1, kAddress1}}), @@ -96,7 +98,8 @@ TEST(Breakpoint, Registration) { settings.locations.push_back(old_pr_settings); settings.locations.push_back(new_pr_settings); - ASSERT_EQ(ZX_OK, bp.SetSettings(settings)); + ASSERT_EQ(ZX_OK, bp.SetSettings(debug_ipc::BreakpointType::kSoftware, + settings)); EXPECT_EQ(CallVector({{kProcess1, kAddress1}, {kProcess3, kAddress3}}), delegate.register_calls()); @@ -121,7 +124,8 @@ TEST(Breakpoint, Destructor) { pr_settings.address = kAddress1; // Apply the settings. - ASSERT_EQ(ZX_OK, bp->SetSettings(settings)); + ASSERT_EQ(ZX_OK, bp->SetSettings(debug_ipc::BreakpointType::kSoftware, + settings)); EXPECT_EQ(CallVector({CallPair{kProcess1, kAddress1}}), delegate.register_calls()); EXPECT_TRUE(delegate.unregister_calls().empty()); @@ -153,7 +157,8 @@ TEST(Breakpoint, HitCount) { pr_settings.address = kAddress1; // Apply the settings. - ASSERT_EQ(ZX_OK, bp->SetSettings(settings)); + ASSERT_EQ(ZX_OK, bp->SetSettings(debug_ipc::BreakpointType::kSoftware, + settings)); delegate.Clear(); EXPECT_EQ(kBreakpointId, bp->stats().breakpoint_id); @@ -189,7 +194,8 @@ TEST(Breakpoint, OneShot) { pr_settings.address = kAddress; // Apply the settings. - ASSERT_EQ(ZX_OK, bp->SetSettings(settings)); + ASSERT_EQ(ZX_OK, bp->SetSettings(debug_ipc::BreakpointType::kSoftware, + settings)); delegate.Clear(); EXPECT_EQ(kBreakpointId, bp->stats().breakpoint_id); diff --git a/src/developer/debug/debug_agent/debug_agent.cc b/src/developer/debug/debug_agent/debug_agent.cc index 1f67aad3f17b07b20bd9621b09f23985ea67a834..ad439a63ab6358ef98a69011854bb2deb4918dc2 100644 --- a/src/developer/debug/debug_agent/debug_agent.cc +++ b/src/developer/debug/debug_agent/debug_agent.cc @@ -346,17 +346,18 @@ void DebugAgent::OnWriteRegisters( void DebugAgent::OnAddOrChangeBreakpoint( const debug_ipc::AddOrChangeBreakpointRequest& request, debug_ipc::AddOrChangeBreakpointReply* reply) { - TIME_BLOCK(); - uint32_t id = request.breakpoint.breakpoint_id; - auto found = breakpoints_.find(id); - if (found == breakpoints_.end()) { - found = breakpoints_ - .emplace(std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple(this)) - .first; + switch (request.breakpoint_type) { + case debug_ipc::BreakpointType::kSoftware: + case debug_ipc::BreakpointType::kHardware: + return SetupBreakpoint(request, reply); + case debug_ipc::BreakpointType::kWatchpoint: + return SetupWatchpoint(request, reply); + case debug_ipc::BreakpointType::kLast: + break; } - reply->status = found->second.SetSettings(request.breakpoint); + + FXL_NOTREACHED() << "Invalid Breakpoint Type."; } void DebugAgent::OnRemoveBreakpoint( @@ -418,6 +419,21 @@ void DebugAgent::UnregisterBreakpoint(Breakpoint* bp, zx_koid_t process_koid, proc->UnregisterBreakpoint(bp, address); } +void DebugAgent::SetupBreakpoint( + const debug_ipc::AddOrChangeBreakpointRequest& request, + debug_ipc::AddOrChangeBreakpointReply* reply) { + uint32_t id = request.breakpoint.breakpoint_id; + auto found = breakpoints_.find(id); + if (found == breakpoints_.end()) { + found = breakpoints_ + .emplace(std::piecewise_construct, std::forward_as_tuple(id), + std::forward_as_tuple(this)) + .first; + } + reply->status = found->second.SetSettings(request.breakpoint_type, + request.breakpoint); +} + zx_status_t DebugAgent::RegisterWatchpoint( Watchpoint* wp, zx_koid_t process_koid, const debug_ipc::AddressRange& range) { @@ -442,6 +458,21 @@ void DebugAgent::UnregisterWatchpoint(Watchpoint* wp, zx_koid_t process_koid, process->UnregisterWatchpoint(wp, range); } +void DebugAgent::SetupWatchpoint( + const debug_ipc::AddOrChangeBreakpointRequest& request, + debug_ipc::AddOrChangeBreakpointReply* reply) { + auto id = request.watchpoint.watchpoint_id; + + auto wp_it = watchpoints_.find(id); + if (wp_it == watchpoints_.end()) { + wp_it = watchpoints_ + .emplace(std::piecewise_construct, std::forward_as_tuple(id), + std::forward_as_tuple(this)) + .first; + } + reply->status = wp_it->second.SetSettings(request.watchpoint); +} + void DebugAgent::OnAddressSpace(const debug_ipc::AddressSpaceRequest& request, debug_ipc::AddressSpaceReply* reply) { TIME_BLOCK(); diff --git a/src/developer/debug/debug_agent/debug_agent.h b/src/developer/debug/debug_agent/debug_agent.h index 2aad02405bb7caaca077c8f3c9e952d525e98de9..dbe5f7e935a95387d4efc0fec8152224f6ce6324 100644 --- a/src/developer/debug/debug_agent/debug_agent.h +++ b/src/developer/debug/debug_agent/debug_agent.h @@ -110,6 +110,9 @@ class DebugAgent : public RemoteAPI, void UnregisterBreakpoint(Breakpoint* bp, zx_koid_t process_koid, uint64_t address) override; + void SetupBreakpoint(const debug_ipc::AddOrChangeBreakpointRequest& request, + debug_ipc::AddOrChangeBreakpointReply* reply); + // Watchpoint::ProcessDelegate implementation -------------------------------- zx_status_t RegisterWatchpoint(Watchpoint*, zx_koid_t process_koid, @@ -117,6 +120,9 @@ class DebugAgent : public RemoteAPI, void UnregisterWatchpoint(Watchpoint*, zx_koid_t process_koid, const debug_ipc::AddressRange&) override; + void SetupWatchpoint(const debug_ipc::AddOrChangeBreakpointRequest& request, + debug_ipc::AddOrChangeBreakpointReply* reply); + // Job/Process/Thread Management --------------------------------------------- zx_status_t AddDebuggedJob(zx_koid_t job_koid, zx::job zx_job); diff --git a/src/developer/debug/debug_agent/hardware_breakpoint.cc b/src/developer/debug/debug_agent/hardware_breakpoint.cc index ab7aa3341eefbd4b2b343bfaad24d911c6252724..64bce53cf8dbf0d057d5613333e28cd6c6a63a26 100644 --- a/src/developer/debug/debug_agent/hardware_breakpoint.cc +++ b/src/developer/debug/debug_agent/hardware_breakpoint.cc @@ -169,7 +169,7 @@ std::set<zx_koid_t> HWThreadsTargeted(const ProcessBreakpoint& pb) { bool all_threads = false; for (Breakpoint* bp : pb.breakpoints()) { // We only care about hardware breakpoints. - if (bp->settings().type != debug_ipc::BreakpointType::kHardware) + if (bp->type() != debug_ipc::BreakpointType::kHardware) continue; for (auto& location : bp->settings().locations) { diff --git a/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc b/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc index 1a70af13c6e5c88808a2209961975210360c85b8..3ff19b18f68aaab229e0951a221c7f48ccac6b24 100644 --- a/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc +++ b/src/developer/debug/debug_agent/integration_tests/breakpoint_test.cc @@ -254,9 +254,9 @@ TEST(BreakpointIntegration, HWBreakpoint) { location.address = module_function; debug_ipc::AddOrChangeBreakpointRequest breakpoint_request = {}; + breakpoint_request.breakpoint_type = debug_ipc::BreakpointType::kHardware; breakpoint_request.breakpoint.breakpoint_id = kBreakpointId; breakpoint_request.breakpoint.one_shot = true; - breakpoint_request.breakpoint.type = debug_ipc::BreakpointType::kHardware; breakpoint_request.breakpoint.locations.push_back(location); debug_ipc::AddOrChangeBreakpointReply breakpoint_reply; remote_api->OnAddOrChangeBreakpoint(breakpoint_request, &breakpoint_reply); diff --git a/src/developer/debug/debug_agent/integration_tests/debugged_job_test.cc b/src/developer/debug/debug_agent/integration_tests/debugged_job_test.cc index ab8e538139d3aa96e0279a8fe2011fcda9139e63..85a0aa681eba4a3a27bd16017760b8a005eae5bc 100644 --- a/src/developer/debug/debug_agent/integration_tests/debugged_job_test.cc +++ b/src/developer/debug/debug_agent/integration_tests/debugged_job_test.cc @@ -356,8 +356,8 @@ TEST(DebuggedJobIntegrationTest, DISABLED_RepresentativeScenario) { location.process_koid = process_koid; location.address = function_address; AddOrChangeBreakpointRequest breakpoint_request; + breakpoint_request.breakpoint_type = debug_ipc::BreakpointType::kSoftware; breakpoint_request.breakpoint.breakpoint_id = breakpoint_id; - breakpoint_request.breakpoint.type = debug_ipc::BreakpointType::kSoftware; breakpoint_request.breakpoint.locations.push_back(location); AddOrChangeBreakpointReply breakpoint_reply; remote_api->OnAddOrChangeBreakpoint(breakpoint_request, &breakpoint_reply); diff --git a/src/developer/debug/debug_agent/process_breakpoint.cc b/src/developer/debug/debug_agent/process_breakpoint.cc index 212d11c86b8058d2d879574577ac3139133ad120..0277274ccc6b3634302840843a1b1b05a76dc8f8 100644 --- a/src/developer/debug/debug_agent/process_breakpoint.cc +++ b/src/developer/debug/debug_agent/process_breakpoint.cc @@ -73,7 +73,7 @@ void ProcessBreakpoint::OnHit( hit_breakpoints->clear(); for (Breakpoint* breakpoint : breakpoints_) { // Only care for breakpoints that match the exception type. - if (breakpoint->settings().type != exception_type) + if (breakpoint->type() != exception_type) continue; breakpoint->OnHit(); @@ -137,7 +137,7 @@ zx_status_t ProcessBreakpoint::Update() { // regardless of which threads are targeted. int sw_bp_count = 0; for (Breakpoint* bp : breakpoints_) { - if (bp->settings().type == debug_ipc::BreakpointType::kSoftware) + if (bp->type() == debug_ipc::BreakpointType::kSoftware) sw_bp_count++; } diff --git a/src/developer/debug/debug_agent/process_breakpoint_unittest.cc b/src/developer/debug/debug_agent/process_breakpoint_unittest.cc index 6da0d342383a6fbee5bd5cbb3c4142df07be2d40..9ba3a9de7d1b571936b634694a387b5c3f73e4c7 100644 --- a/src/developer/debug/debug_agent/process_breakpoint_unittest.cc +++ b/src/developer/debug/debug_agent/process_breakpoint_unittest.cc @@ -152,6 +152,7 @@ const char TEST(ProcessBreakpoint, InstallAndFixup) { TestProcessDelegate process_delegate; Breakpoint main_breakpoint(&process_delegate); + main_breakpoint.set_type(debug_ipc::BreakpointType::kSoftware); zx_koid_t process_koid = 0x1234; MockProcess process(process_koid); @@ -188,6 +189,7 @@ TEST(ProcessBreakpoint, InstallAndFixup) { TEST(ProcessBreakpoint, StepMultiple) { TestProcessDelegate process_delegate; Breakpoint main_breakpoint(&process_delegate); + main_breakpoint.set_type(debug_ipc::BreakpointType::kSoftware); zx_koid_t process_koid = 0x1234; MockProcess process(process_koid); @@ -245,14 +247,16 @@ TEST(ProcessBreakpoint, HitCount) { // (corresponds to two logical breakpoints at the same address). std::unique_ptr<Breakpoint> main_breakpoint1 = std::make_unique<Breakpoint>(&process_delegate); - zx_status_t status = main_breakpoint1->SetSettings(settings); + zx_status_t status = main_breakpoint1->SetSettings( + debug_ipc::BreakpointType::kSoftware, settings); ASSERT_EQ(ZX_OK, status); std::unique_ptr<Breakpoint> main_breakpoint2 = std::make_unique<Breakpoint>(&process_delegate); constexpr uint32_t kBreakpointId2 = 13; settings.breakpoint_id = kBreakpointId2; - status = main_breakpoint2->SetSettings(settings); + status = main_breakpoint2->SetSettings(debug_ipc::BreakpointType::kSoftware, + settings); ASSERT_EQ(ZX_OK, status); // There should only be one address with a breakpoint. @@ -307,10 +311,10 @@ TEST(ProcessBreakpoint, HWBreakpointForAllThreads) { auto breakpoint = std::make_unique<Breakpoint>(&process_delegate); debug_ipc::BreakpointSettings settings1 = {}; settings1.breakpoint_id = kBreakpointId1; - settings1.type = debug_ipc::BreakpointType::kHardware; // This location is for all threads. settings1.locations.push_back({kProcessId, 0, kAddress}); - zx_status_t status = breakpoint->SetSettings(settings1); + zx_status_t status = + breakpoint->SetSettings(debug_ipc::BreakpointType::kHardware, settings1); ASSERT_EQ(status, ZX_OK); // Should have installed the breakpoint. @@ -354,9 +358,9 @@ TEST(ProcessBreakpoint, HWBreakpointWithThreadId) { auto breakpoint1 = std::make_unique<Breakpoint>(&process_delegate); debug_ipc::BreakpointSettings settings1 = {}; settings1.breakpoint_id = kBreakpointId1; - settings1.type = debug_ipc::BreakpointType::kHardware; settings1.locations.push_back({kProcessId, kThreadId1, kAddress}); - zx_status_t status = breakpoint1->SetSettings(settings1); + zx_status_t status = + breakpoint1->SetSettings(debug_ipc::BreakpointType::kHardware, settings1); ASSERT_EQ(status, ZX_OK); // Should have installed the process breakpoint. ASSERT_EQ(process_delegate.bps().size(), 1u); @@ -374,13 +378,12 @@ TEST(ProcessBreakpoint, HWBreakpointWithThreadId) { auto breakpoint2 = std::make_unique<Breakpoint>(&process_delegate); debug_ipc::BreakpointSettings settings2 = {}; settings2.breakpoint_id = kBreakpointId2; - settings2.type = debug_ipc::BreakpointType::kHardware; settings2.locations.push_back({kProcessId, kThreadId2, kAddress}); // This breakpoint has another location for another thread. // In practice, this should not happen, but it's important that no HW // breakpoint get installed if for the wrong location. settings2.locations.push_back({kProcessId, kThreadId3, kOtherAddress}); - breakpoint2->SetSettings(settings2); + breakpoint2->SetSettings(debug_ipc::BreakpointType::kHardware, settings2); // Registering this breakpoint should create a new ProcessBreakpoint. ASSERT_EQ(process_delegate.bps().size(), 2u); auto& process_bp2 = (process_delegate.bps().begin()++)->second; @@ -409,9 +412,8 @@ TEST(ProcessBreakpoint, HWBreakpointWithThreadId) { auto sw_breakpoint = std::make_unique<Breakpoint>(&process_delegate); debug_ipc::BreakpointSettings sw_settings = {}; sw_settings.breakpoint_id = kSwBreakpointId; - sw_settings.type = debug_ipc::BreakpointType::kSoftware; sw_settings.locations.push_back({kProcessId, 0, kAddress}); - sw_breakpoint->SetSettings(sw_settings); + sw_breakpoint->SetSettings(debug_ipc::BreakpointType::kSoftware, sw_settings); // Should have installed only a SW breakpoint. ASSERT_EQ(arch_provider->TotalBreakpointInstallCalls(), 3u); ASSERT_EQ(arch_provider->TotalBreakpointUninstallCalls(), 1u); diff --git a/src/developer/debug/ipc/agent_protocol.cc b/src/developer/debug/ipc/agent_protocol.cc index 08896f0a6960c55dca9f42c4e3c02af6d56eb12b..e4c4543d984fdb211d754bad02bf93d8c5b2694d 100644 --- a/src/developer/debug/ipc/agent_protocol.cc +++ b/src/developer/debug/ipc/agent_protocol.cc @@ -31,11 +31,6 @@ bool Deserialize(MessageReader* reader, BreakpointSettings* settings) { return false; settings->stop = static_cast<Stop>(stop); - uint32_t type; - if (!reader->ReadUint32(&type)) - return false; - settings->type = static_cast<BreakpointType>(type); - return Deserialize(reader, &settings->locations); } @@ -350,6 +345,14 @@ bool ReadRequest(MessageReader* reader, AddOrChangeBreakpointRequest* request, if (!reader->ReadHeader(&header)) return false; *transaction_id = header.transaction_id; + + uint32_t breakpoint_type; + if (!reader->ReadUint32(&breakpoint_type) || + breakpoint_type >= static_cast<uint32_t>(BreakpointType::kLast)) { + return false; + } + request->breakpoint_type = static_cast<BreakpointType>(breakpoint_type); + return Deserialize(reader, &request->breakpoint); } diff --git a/src/developer/debug/ipc/client_protocol.cc b/src/developer/debug/ipc/client_protocol.cc index 22deddfc4a7e3af6a07198be5227848389826026..20d6544e0089fb2c9d0da0c6a8e48a45a64f038c 100644 --- a/src/developer/debug/ipc/client_protocol.cc +++ b/src/developer/debug/ipc/client_protocol.cc @@ -130,7 +130,6 @@ void Serialize(const BreakpointSettings& settings, MessageWriter* writer) { writer->WriteUint32(settings.breakpoint_id); writer->WriteBool(settings.one_shot); writer->WriteUint32(static_cast<uint32_t>(settings.stop)); - writer->WriteUint32(static_cast<uint32_t>(settings.type)); Serialize(settings.locations, writer); } @@ -414,6 +413,7 @@ bool ReadReply(MessageReader* reader, WriteRegistersReply* reply, void WriteRequest(const AddOrChangeBreakpointRequest& request, uint32_t transaction_id, MessageWriter* writer) { writer->WriteHeader(MsgHeader::Type::kAddOrChangeBreakpoint, transaction_id); + writer->WriteUint32(static_cast<uint32_t>(request.breakpoint_type)); Serialize(request.breakpoint, writer); } diff --git a/src/developer/debug/ipc/protocol.h b/src/developer/debug/ipc/protocol.h index 8912de60183b8ec88d56e636c539b77ae502bc4d..a72b7539b178c848837cbce3513d247b2f20c7e6 100644 --- a/src/developer/debug/ipc/protocol.h +++ b/src/developer/debug/ipc/protocol.h @@ -222,7 +222,12 @@ struct ReadMemoryReply { }; struct AddOrChangeBreakpointRequest { + // What kind of request this is. + BreakpointType breakpoint_type = BreakpointType::kSoftware; + + // Only one of these should be valid at a time. BreakpointSettings breakpoint; + WatchpointSettings watchpoint; }; struct AddOrChangeBreakpointReply { // A variety of race conditions could cause a breakpoint modification or diff --git a/src/developer/debug/ipc/protocol_unittests.cc b/src/developer/debug/ipc/protocol_unittests.cc index 09e8abca3bd5543a735465689a51bd7273839d70..07f715fe65a722ab7da34284be0310a94fd7e4f8 100644 --- a/src/developer/debug/ipc/protocol_unittests.cc +++ b/src/developer/debug/ipc/protocol_unittests.cc @@ -379,6 +379,7 @@ TEST(Protocol, ReadMemoryReply) { TEST(Protocol, AddOrChangeBreakpointRequest) { AddOrChangeBreakpointRequest initial; + initial.breakpoint_type = BreakpointType::kHardware; initial.breakpoint.breakpoint_id = 8976; initial.breakpoint.stop = debug_ipc::Stop::kProcess; initial.breakpoint.locations.resize(1); @@ -391,6 +392,7 @@ TEST(Protocol, AddOrChangeBreakpointRequest) { AddOrChangeBreakpointRequest second; ASSERT_TRUE(SerializeDeserializeRequest(initial, &second)); + EXPECT_EQ(initial.breakpoint_type, second.breakpoint_type); EXPECT_EQ(initial.breakpoint.breakpoint_id, second.breakpoint.breakpoint_id); EXPECT_EQ(initial.breakpoint.stop, second.breakpoint.stop); ASSERT_EQ(initial.breakpoint.locations.size(), diff --git a/src/developer/debug/ipc/records.cc b/src/developer/debug/ipc/records.cc index 0659ad7e4b87b497054418ee34b84be141f13100..935435566a173c5fde41fd0e4a6e2dbc359ab408 100644 --- a/src/developer/debug/ipc/records.cc +++ b/src/developer/debug/ipc/records.cc @@ -77,6 +77,22 @@ const char* RegisterCategory::TypeToString(RegisterCategory::Type type) { return nullptr; } +const char* BreakpointTypeToString(BreakpointType type) { + switch (type) { + case BreakpointType::kSoftware: + return "Software"; + case BreakpointType::kHardware: + return "Hardware"; + case BreakpointType::kWatchpoint: + return "Watchpoint"; + case BreakpointType::kLast: + return "Last"; + } + + FXL_NOTREACHED(); + return nullptr; +} + RegisterCategory::Type RegisterCategory::RegisterIDToCategory(RegisterID id) { uint32_t val = static_cast<uint32_t>(id); diff --git a/src/developer/debug/ipc/records.h b/src/developer/debug/ipc/records.h index 835719274c49858cdf0bacfb2464e35c50822849..143803ef0d5819827cb0a9972e5fd79cd153f32f 100644 --- a/src/developer/debug/ipc/records.h +++ b/src/developer/debug/ipc/records.h @@ -151,7 +151,10 @@ enum class Stop : uint32_t { enum class BreakpointType : uint32_t { kSoftware, kHardware, + kWatchpoint, + kLast, }; +const char* BreakpointTypeToString(BreakpointType); struct BreakpointSettings { // The ID if this breakpoint. This is assigned by the client. This is @@ -166,9 +169,6 @@ struct BreakpointSettings { // What should stop when the breakpoint is hit. Stop stop = Stop::kAll; - // What kind of breakpoint this is. - BreakpointType type = BreakpointType::kSoftware; - // Processes to which this breakpoint applies. // // If any process specifies a nonzero thread_koid, it must be the only diff --git a/src/developer/debug/zxdb/client/breakpoint_impl.cc b/src/developer/debug/zxdb/client/breakpoint_impl.cc index 1e040054fe24492eed0f21e041ab680e99f3a889..5958015b2f6c6f55c53308a30a84316defa1b8c7 100644 --- a/src/developer/debug/zxdb/client/breakpoint_impl.cc +++ b/src/developer/debug/zxdb/client/breakpoint_impl.cc @@ -260,10 +260,10 @@ void BreakpointImpl::SendBackendAddOrChange( backend_installed_ = true; debug_ipc::AddOrChangeBreakpointRequest request; + request.breakpoint_type = settings_.type; request.breakpoint.breakpoint_id = backend_id_; request.breakpoint.stop = SettingsStopToIpcStop(settings_.stop_mode); request.breakpoint.one_shot = settings_.one_shot; - request.breakpoint.type = settings_.type; for (const auto& proc : procs_) { for (const auto& pair : proc.second.locs) { diff --git a/src/developer/debug/zxdb/console/command_utils.cc b/src/developer/debug/zxdb/console/command_utils.cc index dd3dfe80ed42aae3be9c597e154e1047889ae26d..e0319e4eb6a309061472ac9d17f458a40ad66c81 100644 --- a/src/developer/debug/zxdb/console/command_utils.cc +++ b/src/developer/debug/zxdb/console/command_utils.cc @@ -330,15 +330,6 @@ const char* BreakpointEnabledToString(bool enabled) { return enabled ? "Enabled" : "Disabled"; } -const char* BreakpointTypeToString(debug_ipc::BreakpointType type) { - switch (type) { - case debug_ipc::BreakpointType::kSoftware: - return "Software"; - case debug_ipc::BreakpointType::kHardware: - return "Hardware"; - } -} - std::string DescribeJobContext(const ConsoleContext* context, const JobContext* job_context) { int id = context->IdForJobContext(job_context); diff --git a/src/developer/debug/zxdb/console/command_utils.h b/src/developer/debug/zxdb/console/command_utils.h index ccd9886d89b2dd20ba1a609a6140ab32ab06fa68..d7dec3089cd48c161c426da1293d46c400796104 100644 --- a/src/developer/debug/zxdb/console/command_utils.h +++ b/src/developer/debug/zxdb/console/command_utils.h @@ -86,7 +86,6 @@ std::string BreakpointScopeToString(const ConsoleContext* context, const BreakpointSettings& settings); std::string BreakpointStopToString(BreakpointSettings::StopMode mode); const char* BreakpointEnabledToString(bool enabled); -const char* BreakpointTypeToString(debug_ipc::BreakpointType); std::string DescribeTarget(const ConsoleContext* context, const Target* target);