blob: 614aabc1dad97e6e9bc1824f547b0f17ba670f63 [file]
// Copyright 2026 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/zxdb/debug_adapter/handlers/request_zxdb_detach.h"
#include <string>
#include <utility>
#include <vector>
#include <dap/types.h>
#include "src/developer/debug/zxdb/client/process.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/target.h"
namespace dap {
DAP_IMPLEMENT_STRUCT_TYPEINFO(ZxdbDetachRequest, "zxdb.Detach", DAP_FIELD(pid, "pid"),
DAP_FIELD(all, "all"))
DAP_IMPLEMENT_STRUCT_TYPEINFO(ZxdbDetachResponse, "")
} // namespace dap
namespace zxdb {
void OnRequestZxdbDetach(
DebugAdapterContext* ctx, const dap::ZxdbDetachRequest& req,
const std::function<void(dap::ResponseOrError<dap::ZxdbDetachResponse>)>& callback) {
if (req.all && *req.all) {
if (req.pid && *req.pid > 0) {
callback(dap::Error("Cannot specify both 'all' and 'pid'"));
return;
}
const size_t current_targets = ctx->session()->system().GetTargets().size();
ctx->session()->system().DetachFromAllTargets(
[current_targets, callback](int detached_targets) {
if (std::cmp_not_equal(current_targets, detached_targets)) {
callback(dap::Error("Detached from %d targets but had %d", detached_targets,
current_targets));
} else {
callback(dap::ZxdbDetachResponse());
}
});
return;
}
if (!req.pid) {
callback(dap::Error("PID is required when 'all' is not specified."));
return;
}
if (*req.pid <= 0) {
callback(dap::Error("PID must be positive"));
return;
}
uint64_t pid = static_cast<uint64_t>(*req.pid);
// Find target with given PID
auto targets = ctx->session()->system().GetTargets();
Target* match = nullptr;
for (auto target : targets) {
if (target && target->GetProcess() && target->GetProcess()->GetKoid() == pid) {
match = target;
break;
}
}
if (!match) {
callback(dap::Error("Process not found"));
return;
}
match->Detach([callback](const fxl::WeakPtr<Target>&, const Err& err) {
if (err.has_error()) {
callback(dap::Error(err.msg()));
} else {
callback(dap::ZxdbDetachResponse());
}
});
}
} // namespace zxdb