blob: e2dd7dcc92d5f3ac2e0a4a20101269470f9bc938 [file] [log] [blame]
// Copyright 2024 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/debug_agent/minidump_iterator.h"
#include "fidl/fuchsia.debugger/cpp/fidl.h"
#include "src/developer/debug/debug_agent/debug_agent.h"
#include "src/developer/debug/debug_agent/debugged_process.h"
#include "src/developer/debug/ipc/protocol.h"
namespace debug_agent {
MinidumpIterator::MinidumpIterator(fxl::WeakPtr<DebugAgent> debug_agent,
std::vector<DebuggedProcess*> processes)
: processes_(std::move(processes)), debug_agent_(std::move(debug_agent)) {}
void MinidumpIterator::GetNext(GetNextCompleter::Sync& completer) {
FX_CHECK(debug_agent_);
if (processes_.empty()) {
completer.Reply(fit::error(fuchsia_debugger::MinidumpError::kNoProcesses));
completer.Close(ZX_ERR_BAD_STATE);
return;
}
zx::vmo vmo;
if (!Advance()) {
zx::vmo::create(0, 0, &vmo);
completer.Reply(fit::success(
fuchsia_debugger::MinidumpIteratorGetNextResponse{{.minidump = std::move(vmo)}}));
completer.Close(ZX_OK);
return;
}
// |current_process_| should always be valid after |Advance| returns true.
FX_DCHECK(current_process_);
debug_ipc::SaveMinidumpReply reply;
debug_agent_->OnSaveMinidump({.process_koid = current_process_->koid()}, &reply);
if (reply.status.has_error()) {
LOGS(Warn) << reply.status.message();
completer.Reply(fit::error(fuchsia_debugger::MinidumpError::kInternalError));
return;
}
if (auto status = zx::vmo::create(reply.core_data.size(), 0, &vmo); status != ZX_OK) {
completer.Reply(fit::error(fuchsia_debugger::MinidumpError::kInternalError));
return;
}
if (auto status = vmo.write(reply.core_data.data(), 0, reply.core_data.size()); status != ZX_OK) {
completer.Reply(fit::error(fuchsia_debugger::MinidumpError::kInternalError));
return;
}
completer.Reply(fit::success(
fuchsia_debugger::MinidumpIteratorGetNextResponse{{.minidump = std::move(vmo)}}));
}
bool MinidumpIterator::Advance() {
if (processes_.empty() || index_ == processes_.size()) {
current_process_ = nullptr;
return false;
}
// Grab the process at the current index and move along, at this point we know that
// processes_[index_] is a valid pointer (the process might not be around anymore).
current_process_ = processes_[index_++];
return true;
}
} // namespace debug_agent